[POS] Enhancement to set default payment as cash, functionality to clear amount value, renamed doctype Payments and some fixes.

This commit is contained in:
Rohit Waghchaure 2016-06-13 21:37:10 +05:30
parent d1eba515e9
commit 9fe40d557f
14 changed files with 157 additions and 86 deletions

View File

@ -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",

View File

@ -25,15 +25,16 @@ def get_pos_data():
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 @@ 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}):
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 @@ def update_multi_mode_option(doc, pos_profile):
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 @@ def get_pricing_rules(doc):
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):

View File

@ -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",

View File

@ -650,6 +650,7 @@ class SalesInvoice(SellingController):
# 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 @@ class SalesInvoice(SellingController):
"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)
)

View File

@ -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": [],

View File

@ -6,5 +6,5 @@ from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class Payments(Document):
class SalesInvoicePayment(Document):
pass

View File

@ -12,6 +12,9 @@ frappe.pages['pos'].on_page_load = function(wrapper) {
}
frappe.pages['pos'].refresh = function(wrapper) {
window.onbeforeunload = function () {
return wrapper.pos.beforeunload()
}
wrapper.pos.on_refresh_page()
}
@ -39,6 +42,21 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}
},
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 @@ 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()
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 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
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 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
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 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
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 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}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 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
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(){

View File

@ -269,3 +269,4 @@ erpnext.patches.v7_0.create_budget_record
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)

View File

@ -577,7 +577,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
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;

View File

@ -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>

View File

@ -31,6 +31,7 @@ erpnext.payments = erpnext.stock.StockController.extend({
$(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 @@ erpnext.payments = erpnext.stock.StockController.extend({
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 @@ erpnext.payments = erpnext.stock.StockController.extend({
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 @@ erpnext.payments = erpnext.stock.StockController.extend({
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){

View File

@ -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>

View File

@ -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;
}