Merge pull request #5474 from rohitwaghchaure/pos_enhancement_and_minor_fixes
[POS] Enhancement to set default payment as cash, functionality to clear amount value, renamed doctype Payments and some fixes.
diff --git a/erpnext/accounts/doctype/pos_profile/pos_profile.json b/erpnext/accounts/doctype/pos_profile/pos_profile.json
index b1420fc..a7e49dd 100644
--- a/erpnext/accounts/doctype/pos_profile/pos_profile.json
+++ b/erpnext/accounts/doctype/pos_profile/pos_profile.json
@@ -307,10 +307,10 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "label": "Payments",
+ "label": "Sales Invoice Payment",
"length": 0,
"no_copy": 0,
- "options": "Payments",
+ "options": "Sales Invoice Payment",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -350,6 +350,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "default": "Point of Sale",
"fieldname": "print_format",
"fieldtype": "Link",
"hidden": 0,
@@ -824,13 +825,14 @@
"hide_toolbar": 0,
"icon": "icon-cog",
"idx": 1,
+ "image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-05-25 15:00:09.335025",
+ "modified": "2016-06-13 21:20:13.805101",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index 9689328..54d47b5 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -25,15 +25,16 @@
update_pos_profile_data(doc, pos_profile)
update_multi_mode_option(doc, pos_profile)
- print_template = frappe.db.get_value('Print Format', pos_profile.get('print_format'), 'html') or ''
+ default_print_format = pos_profile.get('print_format') or "Point of Sale"
+ print_template = frappe.db.get_value('Print Format', default_print_format, 'html')
return {
'doc': doc,
'items': get_items(doc, 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,
+ 'write_off_account': pos_profile.get('write_off_account'),
'meta': {
'invoice': frappe.get_meta('Sales Invoice'),
'items': frappe.get_meta('Sales Invoice Item'),
@@ -70,11 +71,11 @@
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}):
+ for payment in get_mode_of_payment(doc):
payments = doc.append('payments', {})
payments.mode_of_payment = payment.parent
payments.account = payment.default_account
+ payments.type = payment.type
return
@@ -87,6 +88,10 @@
doc.append('payments', payment_mode)
+def get_mode_of_payment(doc):
+ return frappe.db.sql(""" select mpa.default_account, mpa.parent, mp.type as type from `tabMode of Payment Account` mpa,
+ `tabMode of Payment` mp where mpa.parent = mp.name and company = %(company)s""", {'company': doc.company}, as_dict=1)
+
def update_tax_table(doc):
taxes = get_taxes_and_charges('Sales Taxes and Charges Template', doc.taxes_and_charges)
for tax in taxes:
@@ -136,9 +141,6 @@
ifnull(valid_from, '2000-01-01') and ifnull(valid_upto, '2500-12-31') order by priority desc, name desc""",
{'company': doc.company, 'price_list': doc.selling_price_list, 'date': nowdate()}, as_dict=1)
-def get_mode_of_payment(doc):
- return frappe.get_all('Mode of Payment Account', fields = ['distinct parent'], filters={'company': doc.company})
-
@frappe.whitelist()
def make_invoice(doc_list):
if isinstance(doc_list, basestring):
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index 9da4aae..357dec2 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -2055,10 +2055,10 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "label": "Payments",
+ "label": "Sales Invoice Payment",
"length": 0,
"no_copy": 0,
- "options": "Payments",
+ "options": "Sales Invoice Payment",
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -3589,6 +3589,7 @@
"hide_toolbar": 0,
"icon": "icon-file-text",
"idx": 181,
+ "image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
@@ -3596,7 +3597,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-05-09 15:03:33.236351",
+ "modified": "2016-06-10 12:57:08.818701",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 109a9eb..2584d40 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -650,6 +650,7 @@
# write off entries, applicable if only pos
if self.write_off_account and self.write_off_amount:
write_off_account_currency = get_account_currency(self.write_off_account)
+ default_cost_center = frappe.db.get_value('Company', self.company, 'cost_center')
gl_entries.append(
self.get_gl_dict({
@@ -671,7 +672,7 @@
"debit": self.base_write_off_amount,
"debit_in_account_currency": self.base_write_off_amount \
if write_off_account_currency==self.company_currency else self.write_off_amount,
- "cost_center": self.write_off_cost_center
+ "cost_center": self.write_off_cost_center or default_cost_center
}, write_off_account_currency)
)
diff --git a/erpnext/accounts/doctype/payments/__init__.py b/erpnext/accounts/doctype/sales_invoice_payment/__init__.py
similarity index 100%
rename from erpnext/accounts/doctype/payments/__init__.py
rename to erpnext/accounts/doctype/sales_invoice_payment/__init__.py
diff --git a/erpnext/accounts/doctype/payments/payments.json b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json
similarity index 96%
rename from erpnext/accounts/doctype/payments/payments.json
rename to erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json
index d52fb15..6a17483 100644
--- a/erpnext/accounts/doctype/payments/payments.json
+++ b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.json
@@ -169,16 +169,17 @@
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
+ "image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-05-09 00:14:18.975568",
+ "modified": "2016-06-10 12:54:18.343417",
"modified_by": "Administrator",
"module": "Accounts",
- "name": "Payments",
+ "name": "Sales Invoice Payment",
"name_case": "",
"owner": "Administrator",
"permissions": [],
diff --git a/erpnext/accounts/doctype/payments/payments.py b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.py
similarity index 86%
rename from erpnext/accounts/doctype/payments/payments.py
rename to erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.py
index 15cf0b2..cc0b7a6 100644
--- a/erpnext/accounts/doctype/payments/payments.py
+++ b/erpnext/accounts/doctype/sales_invoice_payment/sales_invoice_payment.py
@@ -6,5 +6,5 @@
import frappe
from frappe.model.document import Document
-class Payments(Document):
+class SalesInvoicePayment(Document):
pass
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index 2bff841..f3c8c33 100644
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -12,6 +12,9 @@
}
frappe.pages['pos'].refresh = function(wrapper) {
+ window.onbeforeunload = function () {
+ return wrapper.pos.beforeunload()
+ }
wrapper.pos.on_refresh_page()
}
@@ -39,6 +42,21 @@
}
},
+ beforeunload: function(e){
+ if(this.connection_status == false && frappe.get_route()[0] == "pos"){
+ e = e || window.event;
+
+ // For IE and Firefox prior to version 4
+ if (e) {
+ e.returnValue = __("You are in offline mode. You will not be able to reload until you have network.");
+ return
+ }
+
+ // For Safari
+ return __("You are in offline mode. You will not be able to reload until you have network.");
+ }
+ },
+
check_internet_connection: function(){
var me = this;
//Check Internet connection after every 30 seconds
@@ -76,19 +94,19 @@
var me = this;
this.page.add_menu_item(__("New Sales Invoice"), function() {
- me.save_previous_entry()
- me.create_new()
+ me.save_previous_entry();
+ me.create_new();
})
this.page.add_menu_item(__("View Offline Records"), function(){
- me.show_unsync_invoice_list()
+ me.show_unsync_invoice_list();
});
this.page.add_menu_item(__("Sync Master Data"), function(){
me.get_data_from_server(function(){
- me.load_data()
- me.make_customer()
- me.make_item_list()
+ me.load_data();
+ me.make_customer();
+ me.make_item_list();
})
});
@@ -107,36 +125,40 @@
this.list_dialog.show();
this.list_body = this.list_dialog.body;
- $(this.list_body).append('<div class="row list-row list-row-head pos-invoice-list">\
- <div class="col-xs-3">Sr</div>\
- <div class="col-xs-3">Customer</div>\
- <div class="col-xs-4 text-center">Grand Total</div>\
- <div class="col-xs-2 text-left">Status</div>\
- </div>')
+ if(this.si_docs.length > 0){
+ $(this.list_body).append('<div class="row list-row list-row-head pos-invoice-list">\
+ <div class="col-xs-2">Sr</div>\
+ <div class="col-xs-4">Customer</div>\
+ <div class="col-xs-2 text-left">Status</div>\
+ <div class="col-xs-4 text-right">Grand Total</div>\
+ </div>')
- $.each(this.si_docs, function(index, data){
- for(key in data) {
- $(frappe.render_template("pos_invoice_list", {
- sr: index + 1,
- name: key,
- customer: data[key].customer,
- grand_total: format_currency(data[key].grand_total, me.frm.doc.currency),
- data: me.get_doctype_status(data[key])
- })).appendTo($(me.list_body));
- }
- })
+ $.each(this.si_docs, function(index, data){
+ for(key in data) {
+ $(frappe.render_template("pos_invoice_list", {
+ sr: index + 1,
+ name: key,
+ customer: data[key].customer,
+ grand_total: format_currency(data[key].grand_total, me.frm.doc.currency),
+ data: me.get_doctype_status(data[key])
+ })).appendTo($(me.list_body));
+ }
+ })
- $(this.list_body).find('.list-row').click(function() {
- me.name = $(this).attr('invoice-name')
- doc_data = me.get_invoice_doc(me.si_docs)
- if(doc_data){
- me.frm.doc = doc_data[0][me.name];
- me.set_missing_values();
- me.refresh();
- me.disable_input_field();
- me.list_dialog.hide();
- }
- })
+ $(this.list_body).find('.list-row').click(function() {
+ me.name = $(this).attr('invoice-name')
+ doc_data = me.get_invoice_doc(me.si_docs)
+ if(doc_data){
+ me.frm.doc = doc_data[0][me.name];
+ me.set_missing_values();
+ me.refresh();
+ me.disable_input_field();
+ me.list_dialog.hide();
+ }
+ })
+ }else{
+ $(this.list_body).append(repl('<div class="media-heading">%(message)s</div>', {'message': __("All records are synced.")}))
+ }
},
get_doctype_status: function(doc){
@@ -180,6 +202,7 @@
window.pricing_rules = r.message.pricing_rules;
window.meta = r.message.meta;
window.print_template = r.message.print_template;
+ me.write_off_account = r.message.write_off_account;
localStorage.setItem('doc', JSON.stringify(r.message.doc));
if(callback){
callback();
@@ -640,8 +663,10 @@
me.create_invoice();
me.make_payment();
});
- }else if(this.frm.doc.docstatus == 0 && this.name){
+ }else if(this.frm.doc.docstatus == 0 && this.frm.doc.items.length){
this.page.set_primary_action(__("Submit"), function() {
+ me.validate()
+ me.create_invoice();
me.write_off_amount()
})
}else if(this.frm.doc.docstatus == 1){
@@ -652,6 +677,11 @@
}else {
this.page.clear_primary_action()
}
+
+ this.page.set_secondary_action(__("New"), function() {
+ me.save_previous_entry();
+ me.create_new();
+ });
},
print_document: function(html){
@@ -672,18 +702,30 @@
dialog = new frappe.ui.Dialog({
title: 'Write Off Amount',
fields: [
- {fieldtype: "Check", fieldname: "write_off_amount", label: __("Write of Outstanding Amount")},
+ {fieldtype: "Check", fieldname: "write_off_amount", label: __("Write off Outstanding Amount")},
+ {fieldtype: "Link", options:"Account", default:this.write_off_account, fieldname: "write_off_account",
+ label: __("Write off Account"), get_query: function() {
+ return {
+ filters: {'is_group': 0, 'report_type': 'Profit and Loss'}
+ }
+ }}
]
});
dialog.show();
dialog.fields_dict.write_off_amount.$input.change(function(){
- write_off_amount = dialog.get_values().write_off_amount
+ write_off_amount = dialog.get_values().write_off_amount;
me.frm.doc.write_off_outstanding_amount_automatically = write_off_amount;
me.frm.doc.base_write_off_amount = (write_off_amount==1) ? flt(me.frm.doc.grand_total - me.frm.doc.paid_amount, precision("outstanding_amount")) : 0;
+ me.frm.doc.write_off_account = (write_off_amount==1) ? dialog.get_values().write_off_account : '';
me.frm.doc.write_off_amount = flt(me.frm.doc.base_write_off_amount * me.frm.doc.conversion_rate, precision("write_off_amount"))
me.calculate_outstanding_amount();
+ me.set_primary_action();
+ })
+
+ dialog.fields_dict.write_off_account.$input.change(function(){
+ me.frm.doc.write_off_account = dialog.get_values().write_off_account;
})
dialog.set_primary_action(__("Submit"), function(){
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index cab08ca..363a5a6 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -269,3 +269,4 @@
execute:frappe.delete_doc_if_exists("Page", "financial-analytics")
erpnext.patches.v7_0.update_project_in_gl_entry
execute:frappe.db.sql('update tabQuotation set status="Cancelled" where docstatus=2')
+execute:frappe.rename_doc("DocType", "Payments", "Sales Invoice Payment", force=True)
\ No newline at end of file
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index f775f29..cf66501 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -577,7 +577,7 @@
var me = this;
var paid_amount = base_paid_amount = 0.0;
$.each(this.frm.doc['payments'] || [], function(index, data){
- if(data.amount > 0){
+ if(data.amount > -1){
data.base_amount = flt(data.amount * me.frm.doc.conversion_rate);
paid_amount += data.amount;
base_paid_amount += data.base_amount;
diff --git a/erpnext/public/js/payment/payment_details.html b/erpnext/public/js/payment/payment_details.html
index 00a2d93..18f9d03 100644
--- a/erpnext/public/js/payment/payment_details.html
+++ b/erpnext/public/js/payment/payment_details.html
@@ -1,9 +1,11 @@
<div class="row pos-payment-row" type="{{type}}" idx={{idx}}>
- <div class="col-xs-6"><h5 class="payment-mode text-ellipsis" idx="{{idx}}"> {{mode_of_payment}} </h5></div>
- <div class="col-xs-6 text-right">
- <input disabled data-fieldtype="Currency"
- style="cursor: pointer;"
- class="input-with-feedback form-control text-right amount"
- idx="{{idx}}" type="text" value="{{format_number(amount, 2)}}">
+ <div class="col-xs-6">{{mode_of_payment}}</div>
+ <div class="col-xs-6">
+ <div class="input-group">
+ <input disabled class="form-control text-right amount" idx="{{idx}}" type="text" value="{{format_number(amount, 2)}}">
+ <span class="input-group-btn">
+ <button type="button" class="btn btn-default clr" idx="{{idx}}" style="border:1px solid #d1d8dd">C</button>
+ </span>
</div>
+ </div>
</div>
\ No newline at end of file
diff --git a/erpnext/public/js/payment/payments.js b/erpnext/public/js/payment/payments.js
index f5527b1..4cd12f1 100644
--- a/erpnext/public/js/payment/payments.js
+++ b/erpnext/public/js/payment/payments.js
@@ -31,6 +31,7 @@
$(this.$body).html(frappe.render_template('pos_payment', this.frm.doc))
this.show_payment_details();
this.bind_keyboard_event()
+ this.clear_amount()
},
make_multimode_payment: function(){
@@ -57,11 +58,33 @@
currency: me.frm.doc.currency,
type: data.type
})).appendTo(multimode_payments)
+
+ if (data.type == 'Cash' && me.frm.doc.outstanding_amount > 0) {
+ me.idx = data.idx;
+ me.set_outstanding_amount();
+ }
})
}else{
$("<p>No payment mode selected in pos profile</p>").appendTo(multimode_payments)
}
},
+
+ set_outstanding_amount: function(){
+ this.selected_mode = $(this.$body).find(repl("input[idx='%(idx)s']",{'idx': this.idx}));
+ this.highlight_selected_row()
+ this.payment_val = 0.0
+ if(this.frm.doc.outstanding_amount > 0 && flt(this.selected_mode.val()) == 0.0){
+ //When user first tithis click on row
+ this.payment_val = flt(this.frm.doc.outstanding_amount)
+ this.selected_mode.val(format_number(this.payment_val, 2));
+ this.update_paid_amount()
+ }else if(flt(this.selected_mode.val()) > 0){
+ //If user click on existing row which has value
+ this.payment_val = flt(this.selected_mode.val());
+ }
+ this.selected_mode.select()
+ this.bind_amount_change_event();
+ },
bind_keyboard_event: function(){
var me = this;
@@ -69,28 +92,15 @@
this.bind_payment_mode_keys_event();
this.bind_keyboard_keys_event();
},
-
+
bind_payment_mode_keys_event: function(){
var me = this;
$(this.$body).find('.pos-payment-row').click(function(){
me.idx = $(this).attr("idx");
- me.selected_mode = $(me.$body).find(repl("input[idx='%(idx)s']",{'idx': me.idx}));
- me.highlight_selected_row()
- me.payment_val = 0.0
- if(me.frm.doc.outstanding_amount > 0 && flt(me.selected_mode.val()) == 0.0){
- //When user first time click on row
- me.payment_val = flt(me.frm.doc.outstanding_amount)
- me.selected_mode.val(format_number(me.payment_val, 2));
- me.update_paid_amount()
- }else if(flt(me.selected_mode.val()) > 0){
- //If user click on existing row which has value
- me.payment_val = flt(me.selected_mode.val());
- }
- me.selected_mode.select()
- me.bind_amount_change_event();
+ me.set_outstanding_amount()
})
},
-
+
highlight_selected_row: function(){
var me = this;
selected_row = $(this.$body).find(repl(".pos-payment-row[idx='%(idx)s']",{'idx': this.idx}));
@@ -127,7 +137,19 @@
me.update_paid_amount()
})
},
-
+
+ clear_amount: function(){
+ var me = this;
+ $(this.$body).find('.clr').click(function(e){
+ e.stopPropagation();
+ me.idx = $(this).attr("idx");
+ me.selected_mode = $(me.$body).find(repl("input[idx='%(idx)s']",{'idx': me.idx}));
+ me.payment_val = 0.0;
+ me.selected_mode.val(0.0);
+ me.update_paid_amount();
+ })
+ },
+
update_paid_amount: function(){
var me = this;
$.each(this.frm.doc.payments, function(index, data){
diff --git a/erpnext/public/js/pos/pos_invoice_list.html b/erpnext/public/js/pos/pos_invoice_list.html
index cb25072..c0b4764 100644
--- a/erpnext/public/js/pos/pos_invoice_list.html
+++ b/erpnext/public/js/pos/pos_invoice_list.html
@@ -1,6 +1,6 @@
<div class="row list-row pos-invoice-list" invoice-name = "{{name}}">
- <div class="col-xs-3">{%= sr %}</div>
- <div class="col-xs-3">{%= customer %}</div>
- <div class="col-xs-4 text-center">{%= grand_total %}</div>
+ <div class="col-xs-2">{%= sr %}</div>
+ <div class="col-xs-4">{%= customer %}</div>
<div class="col-xs-2 text-left"><span class="indicator {{data.indicator}}">{{ data.status }}</span></div>
+ <div class="col-xs-4 text-right">{%= grand_total %}</div>
</div>
diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less
index a9ef2d0..404540a 100644
--- a/erpnext/public/less/erpnext.less
+++ b/erpnext/public/less/erpnext.less
@@ -177,7 +177,8 @@
.pos-payment-row {
border-bottom:1px solid #d1d8dd;
- margin: 2px 0px 5px 0px;
+ margin: 2px 0px 5px 0px;
+ height: 60px;
}
.pos-payment-row:hover, .pos-keyboard-key:hover{
@@ -196,10 +197,6 @@
border-color: #e8e8e8;
}
-.amount {
- margin-top: 5px;
-}
-
.amount-label {
font-size: 16px;
}