diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.js b/erpnext/accounts/doctype/pos_profile/pos_profile.js
index 8de8e351bc..99438a6a5f 100755
--- a/erpnext/accounts/doctype/pos_profile/pos_profile.js
+++ b/erpnext/accounts/doctype/pos_profile/pos_profile.js
@@ -24,18 +24,6 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) {
});
});
-//cash bank account
-//------------------------------------
-cur_frm.fields_dict['cash_bank_account'].get_query = function(doc,cdt,cdn) {
- return{
- filters:{
- 'report_type': "Balance Sheet",
- 'is_group': 0,
- 'company': doc.company
- }
- }
-}
-
// Income Account
// --------------------------------
cur_frm.fields_dict['income_account'].get_query = function(doc,cdt,cdn) {
diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.json b/erpnext/accounts/doctype/pos_profile/pos_profile.json
index 8f25ba90b3..b1420fc2a1 100644
--- a/erpnext/accounts/doctype/pos_profile/pos_profile.json
+++ b/erpnext/accounts/doctype/pos_profile/pos_profile.json
@@ -739,33 +739,6 @@
"set_only_once": 0,
"unique": 0
},
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "cash_bank_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Cash/Bank Account",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "cash_bank_account",
- "oldfieldtype": "Link",
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
{
"allow_on_submit": 0,
"bold": 0,
@@ -857,7 +830,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-05-09 00:00:30.610878",
+ "modified": "2016-05-25 15:00:09.335025",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",
diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.py b/erpnext/accounts/doctype/pos_profile/pos_profile.py
index 634d63c190..5f4d5bc75d 100644
--- a/erpnext/accounts/doctype/pos_profile/pos_profile.py
+++ b/erpnext/accounts/doctype/pos_profile/pos_profile.py
@@ -27,7 +27,7 @@ class POSProfile(Document):
self.company), raise_exception=1)
def validate_all_link_fields(self):
- accounts = {"Account": [self.cash_bank_account, self.income_account,
+ accounts = {"Account": [self.income_account,
self.expense_account], "Cost Center": [self.cost_center],
"Warehouse": [self.warehouse]}
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index 4ec2524529..2fbf4b6ac8 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -7,6 +7,7 @@ from frappe import _
from frappe.utils import nowdate
from erpnext.setup.utils import get_exchange_rate
from erpnext.stock.get_item_details import get_pos_profile
+from erpnext.accounts.party import get_party_account_currency
from erpnext.controllers.accounts_controller import get_taxes_and_charges
@frappe.whitelist()
@@ -28,7 +29,7 @@ def get_pos_data():
return {
'doc': doc,
'items': get_items(doc, pos_profile),
- 'customers': get_customers(pos_profile),
+ 'customers': get_customers(pos_profile, doc),
'pricing_rules': get_pricing_rules(doc),
'mode_of_payment': get_mode_of_payment(doc),
'print_template': print_template,
@@ -68,6 +69,12 @@ def update_multi_mode_option(doc, pos_profile):
from frappe.model import default_fields
if not pos_profile:
+ for payment in frappe.get_all('Mode of Payment Account', fields=["default_account", "parent"],
+ filters = {'company': doc.company}):
+ payments = doc.append('payments', {})
+ payments.mode_of_payment = payment.parent
+ payments.account = payment.default_account
+
return
for payment_mode in pos_profile.payments:
@@ -106,12 +113,19 @@ def get_items(doc, pos_profile):
return item_list
-def get_customers(pos_profile):
+def get_customers(pos_profile, doc):
filters = {'disabled': 0}
+ customer_list = []
if pos_profile.get('customer'):
filters.update({'name': pos_profile.customer})
- return frappe.get_all("Customer", fields=["*"], filters = filters)
+ customers = frappe.get_all("Customer", fields=["*"], filters = filters)
+
+ for customer in customers:
+ customer_currency = get_party_account_currency('Customer', customer.name, doc.company) or doc.currency
+ if customer_currency == doc.currency:
+ customer_list.append(customer)
+ return customer_list
def get_pricing_rules(doc):
if doc.ignore_pricing_rule == 0:
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index abc4083f1c..cc3d95227c 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -525,7 +525,6 @@ class TestSalesInvoice(unittest.TestCase):
def make_pos_profile(self):
pos_profile = frappe.get_doc({
- "cash_bank_account": "_Test Bank - _TC",
"company": "_Test Company",
"cost_center": "_Test Cost Center - _TC",
"currency": "INR",
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index 386ed9ed93..4b3da285f3 100644
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -4,7 +4,7 @@ frappe.provide("erpnext.pos");
frappe.pages['pos'].on_page_load = function(wrapper) {
var page = frappe.ui.make_app_page({
parent: wrapper,
- title: 'Point of Sale',
+ title: __('Point of Sale'),
single_column: true
});
@@ -32,6 +32,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
var me = this;
if(this.load){
this.load = false;
+ }else if(this.connection_status){
+ this.onload();
}else{
this.create_new();
}
@@ -42,12 +44,13 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
//Check Internet connection after every 30 seconds
setInterval(function(){
me.set_indicator();
- }, 30000)
+ }, 5000)
},
set_indicator: function(){
var me = this;
// navigator.onLine
+ this.connection_status = false;
this.page.set_indicator("Offline", "grey")
frappe.call({
method:"frappe.handler.ping",
@@ -73,6 +76,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
var me = this;
this.page.add_menu_item(__("New Sales Invoice"), function() {
+ me.save_previous_entry()
me.create_new()
})
@@ -89,7 +93,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
});
this.page.add_menu_item(__("POS Profile"), function() {
- frappe.set_route('POS Profile');
+ frappe.set_route('List', 'POS Profile');
});
},
@@ -106,8 +110,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
$(this.list_body).append('
\
Sr
\
Customer
\
-
Grand Total
\
-
Status
\
+
Grand Total
\
+
Status
\
')
$.each(this.si_docs, function(index, data){
@@ -117,7 +121,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
name: key,
customer: data[key].customer,
grand_total: format_currency(data[key].grand_total, me.frm.doc.currency),
- status: (data[key].docstatus == 1) ? 'Submitted' : 'Draft'
+ data: me.get_doctype_status(data[key])
})).appendTo($(me.list_body));
}
})
@@ -135,6 +139,16 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
})
},
+ get_doctype_status: function(doc){
+ if(doc.outstanding_amount == 0){
+ return {status: "Paid", indicator: "green"}
+ }else if(doc.docstatus == 0){
+ return {status: "Draft", indicator: "red"}
+ }else if(doc.paid_amount >= 0){
+ return {status: "Unpaid", indicator: "orange"}
+ }
+ },
+
set_missing_values: function(){
var me = this;
doc = JSON.parse(localStorage.getItem('doc'))
@@ -174,11 +188,16 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
})
},
+ save_previous_entry : function(){
+ if(this.frm.doc.items.length > 0){
+ this.create_invoice()
+ }
+ },
+
create_new: function(){
var me = this;
this.frm = {}
this.name = '';
- this.frm.doc = JSON.parse(localStorage.getItem('doc'))
this.load_data();
this.setup();
},
@@ -187,6 +206,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.items = window.items;
this.customers = window.customers;
this.pricing_rules = window.pricing_rules;
+ this.frm.doc = JSON.parse(localStorage.getItem('doc'));
$.each(window.meta, function(i, data){
frappe.meta.sync(data)
@@ -264,6 +284,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}
this.party_field.$input.autocomplete({
+ autoFocus: true,
source: function (request, response) {
me.customer_data = me.get_customers(request.term)
response($.map(me.customer_data, function(data){
@@ -282,19 +303,30 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}
me.refresh();
}
- })
+ }).on("focus", function(){
+ setTimeout(function() {
+ if(!me.party_field.$input.val()) {
+ me.party_field.$input.autocomplete( "search", " " );
+ }
+ }, 500);
+ });
},
get_customers: function(key){
var me = this;
- key = key.toLowerCase()
- return $.grep(this.customers, function(data) {
- if(data.name.toLowerCase().match(key)
- || data.customer_name.toLowerCase().match(key)
- || (data.customer_group && data.customer_group.toLowerCase().match(key))){
- return data
- }
- })
+ key = key.toLowerCase().trim()
+ if(key){
+ return $.grep(this.customers, function(data) {
+ if(data.name.toLowerCase().match(key)
+ || data.customer_name.toLowerCase().match(key)
+ || (data.customer_group && data.customer_group.toLowerCase().match(key))){
+ return data
+ }
+ })
+ }else{
+ customers = this.customers.sort(function(a,b){ return a.idx < b.idx })
+ return customers.slice(0, 20)
+ }
},
make_item_list: function() {
@@ -377,39 +409,52 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
$(this.wrapper).find(".pos-item-qty").on("change", function(){
var item_code = $(this).parents(".pos-bill-item").attr("data-item-code");
- me.update_qty_against_item_code(item_code, $(this).val());
+ me.update_qty_rate_against_item_code(item_code, "qty", $(this).val());
})
$(this.wrapper).find("[data-action='increase-qty']").on("click", function(){
var item_code = $(this).parents(".pos-bill-item").attr("data-item-code");
var qty = flt($(this).parents(".pos-bill-item").find('.pos-item-qty').val()) + 1;
- me.update_qty_against_item_code(item_code, qty);
+ me.update_qty_rate_against_item_code(item_code, "qty", qty);
})
$(this.wrapper).find("[data-action='decrease-qty']").on("click", function(){
var item_code = $(this).parents(".pos-bill-item").attr("data-item-code");
var qty = flt($(this).parents(".pos-bill-item").find('.pos-item-qty').val()) - 1;
- me.update_qty_against_item_code(item_code, qty);
+ me.update_qty_rate_against_item_code(item_code, "qty", qty);
})
},
- update_qty_against_item_code: function(item_code, qty){
+ update_rate: function() {
var me = this;
- if(qty < 0){
- frappe.throw(__("Quantity must be positive"));
+
+ $(this.wrapper).find(".pos-item-rate").on("change", function(){
+ var item_code = $(this).parents(".pos-bill-item").attr("data-item-code");
+ me.update_qty_rate_against_item_code(item_code, "rate", $(this).val());
+ })
+ },
+
+ update_qty_rate_against_item_code: function(item_code, field, value){
+ var me = this;
+ if(value < 0){
+ frappe.throw(__("Enter value must be positive"));
}
this.remove_item = []
$.each(this.frm.doc["items"] || [], function(i, d) {
if (d.item_code == item_code) {
- d.qty = flt(qty);
+ d[field] = flt(value);
d.amount = flt(d.rate) * flt(d.qty);
if(d.qty==0){
me.remove_item.push(d.idx)
}
}
});
- this.remove_zero_qty_item();
+
+ if(field == 'qty'){
+ this.remove_zero_qty_item();
+ }
+
this.refresh();
},
@@ -512,6 +557,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
var me = this;
this.refresh_fields();
this.update_qty();
+ this.update_rate();
this.set_primary_action();
},
refresh_fields: function() {
@@ -544,7 +590,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
qty: d.qty,
actual_qty: d.actual_qty,
projected_qty: d.projected_qty,
- rate: format_currency(d.rate, me.frm.doc.currency),
+ rate: format_number(d.rate, me.frm.doc.currency),
amount: format_currency(d.amount, me.frm.doc.currency)
})).appendTo($items);
});
@@ -552,6 +598,10 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.wrapper.find("input.pos-item-qty").on("focus", function() {
$(this).select();
});
+
+ this.wrapper.find("input.pos-item-rate").on("focus", function() {
+ $(this).select();
+ });
},
set_taxes: function(){
@@ -596,18 +646,23 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}else if(this.frm.doc.docstatus == 1){
this.page.set_primary_action(__("Print"), function() {
html = frappe.render(me.print_template, me.frm.doc)
- frappe.require("/assets/js/print_format_v3.min.js", function() {
- w = _p.preview(html);
- setTimeout(function(){
- w.print();
- }, 1000)
- });
+ me.print_document(html)
})
}else {
this.page.clear_primary_action()
}
},
+ print_document: function(html){
+ var w = window.open();
+ w.document.write(html);
+ w.document.close();
+ setTimeout(function(){
+ w.print();
+ w.close();
+ }, 1000)
+ },
+
write_off_amount: function(){
var me = this;
var value = 0.0;
@@ -723,7 +778,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
var me = this;
this.si_docs = this.get_submitted_invoice()
- if(this.connection_status && this.si_docs.length){
+ if(this.si_docs.length){
frappe.call({
method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
args: {
@@ -740,12 +795,14 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
},
get_submitted_invoice: function(){
- invoices = []
- docs = this.get_doc_from_localstorage()
+ var invoices = [];
+ var index = 1;
+ docs = this.get_doc_from_localstorage();
if(docs){
invoices = $.map(docs, function(data){
for(key in data){
- if(data[key].docstatus == 1){
+ if(data[key].docstatus == 1 && index < 50){
+ index++
return data
}
}
diff --git a/erpnext/accounts/print_format/point_of_sale/point_of_sale.json b/erpnext/accounts/print_format/point_of_sale/point_of_sale.json
index 7641924f02..645fce6fe6 100644
--- a/erpnext/accounts/print_format/point_of_sale/point_of_sale.json
+++ b/erpnext/accounts/print_format/point_of_sale/point_of_sale.json
@@ -6,9 +6,9 @@
"docstatus": 0,
"doctype": "Print Format",
"font": "Default",
- "html": "\n\n\n\t{{ company }}
\n\t{{ __(\"Invoice\") }}
\n
\n\n\t{{ __(\"Date\") }}: {{ posting_date }}
\n
\n\n
\n\n\t\n\t\t\n\t\t\t{{ __(\"Item\") }} | \n\t\t\t{{ __(\"Qty\") }} | \n\t\t\t{{ __(\"Amount\") }} | \n\t\t
\n\t\n\t\n\t\t{% for item in items %}\n\t\t\n\t\t\t\n\t\t\t\t{{ item.item_name }}\n\t\t\t | \n\t\t\t{{ item.qty }} @ {{ format_currency(item.rate, currency) }} | \n\t\t\t{{ format_currency(item.amount, currency) }} | \n\t\t
\n\t\t{% endfor %}\n\t\n
\n\n\n\t\n\t\t\n\t\t\t\n\t\t\t\t{{ __(\"Net Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(total, currency) }}\n\t\t\t | \n\t\t
\n\t\t{% for row in taxes %}\n\t\t{% if not row.included_in_print_rate %}\n\t\t\n\t\t\t\n\t\t\t\t{{ row.description }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(row.tax_amount, currency) }}\n\t\t\t | \n\t\t
\n\t\t{% endif %}\n\t\t{% endfor %}\n\t\t{% if discount_amount %}\n\t\t\n\t\t\t\n\t\t\t\t{{ __(\"Discount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(discount_amount, currency) }}\n\t\t\t | \n\t\t
\n\t\t{% endif %}\n\t\t\n\t\t\t\n\t\t\t\t{{ __(\"Grand Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(grand_total, currency) }}\n\t\t\t | \n\t\t
\n\t\n
\n\n\n
\n{{ __(\"Thank you, please visit again.\") }}
",
+ "html": "\n\n\n\t{{ company }}
\n\t{{ __(\"Invoice\") }}
\n
\n\n\t{{ __(\"Date\") }}: {{ dateutil.global_date_format(posting_date) }}
\n
\n\n
\n\n\t\n\t\t\n\t\t\t{{ __(\"Item\") }} | \n\t\t\t{{ __(\"Qty\") }} | \n\t\t\t{{ __(\"Amount\") }} | \n\t\t
\n\t\n\t\n\t\t{% for item in items %}\n\t\t\n\t\t\t\n\t\t\t\t{{ item.item_name }}\n\t\t\t | \n\t\t\t{{ item.qty }} @ {{ format_currency(item.rate, currency) }} | \n\t\t\t{{ format_currency(item.amount, currency) }} | \n\t\t
\n\t\t{% endfor %}\n\t\n
\n\n\n\t\n\t\t\n\t\t\t\n\t\t\t\t{{ __(\"Net Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(total, currency) }}\n\t\t\t | \n\t\t
\n\t\t{% for row in taxes %}\n\t\t{% if not row.included_in_print_rate %}\n\t\t\n\t\t\t\n\t\t\t\t{{ row.description }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(row.tax_amount, currency) }}\n\t\t\t | \n\t\t
\n\t\t{% endif %}\n\t\t{% endfor %}\n\t\t{% if discount_amount %}\n\t\t\n\t\t\t\n\t\t\t\t{{ __(\"Discount\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(discount_amount, currency) }}\n\t\t\t | \n\t\t
\n\t\t{% endif %}\n\t\t\n\t\t\t\n\t\t\t\t{{ __(\"Grand Total\") }}\n\t\t\t | \n\t\t\t\n\t\t\t\t{{ format_currency(grand_total, currency) }}\n\t\t\t | \n\t\t
\n\t\n
\n\n\n
\n{{ __(\"Thank you, please visit again.\") }}
",
"idx": 0,
- "modified": "2016-05-11 15:04:24.359583",
+ "modified": "2016-05-21 00:25:20.359074",
"modified_by": "Administrator",
"name": "Point of Sale",
"owner": "Administrator",
diff --git a/erpnext/public/js/pos/pos_bill_item.html b/erpnext/public/js/pos/pos_bill_item.html
index fe521f6fb9..c21e1d5ce8 100644
--- a/erpnext/public/js/pos/pos_bill_item.html
+++ b/erpnext/public/js/pos/pos_bill_item.html
@@ -17,6 +17,7 @@
-
{%= amount %}
{%= rate %}
+
+
{%= amount %}
diff --git a/erpnext/public/js/pos/pos_invoice_list.html b/erpnext/public/js/pos/pos_invoice_list.html
index 8d2644ce27..cb25072756 100644
--- a/erpnext/public/js/pos/pos_invoice_list.html
+++ b/erpnext/public/js/pos/pos_invoice_list.html
@@ -1,6 +1,6 @@
{%= sr %}
{%= customer %}
-
{%= grand_total %}
-
{%= status %}
+
{%= grand_total %}
+
{{ data.status }}
diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less
index 58e8e6265d..7da54e7dd8 100644
--- a/erpnext/public/less/erpnext.less
+++ b/erpnext/public/less/erpnext.less
@@ -156,3 +156,55 @@
.dashboard-list-item:last-child {
border-bottom: none;
}
+
+.payment-toolbar {
+ margin-left: 35px;
+}
+
+.payment-mode {
+ cursor: pointer;
+ font-family: sans-serif;
+ font-size: 15px;
+}
+
+.pos-payment-row .col-xs-6 {
+ padding :10px;
+}
+
+.pos-payment-row {
+ border-bottom:1px solid #d1d8dd;
+ margin: 2px 0px 5px 0px;
+}
+
+.pos-payment-row:hover, .pos-keyboard-key:hover{
+ background-color: #FAFBFC;
+ cursor: pointer;
+}
+
+.pos-keyboard-key, .delete-btn {
+ border: 1px solid #d1d8dd;
+ height:85px;
+ width:85px;
+ margin:10px 10px;
+ font-size:24px;
+ font-weight:200;
+ background-color: #FDFDFD;
+ border-color: #e8e8e8;
+}
+
+.amount {
+ margin-top: 5px;
+}
+
+.amount-label {
+ font-size: 16px;
+}
+
+.selected-payment-mode {
+ background-color: #FAFBFC;
+ cursor: pointer;
+}
+
+.pos-invoice-list {
+ padding: 15px 10px;
+}