fix: browser hangs while making payment entry for large number of outstaning invoices

This commit is contained in:
Rohit Waghchaure
2019-04-28 23:30:00 +05:30
parent 83f767b5a3
commit 2f3f7507c4
4 changed files with 86 additions and 53 deletions

View File

@@ -302,7 +302,7 @@ frappe.ui.form.on('Payment Entry', {
}, },
() => frm.set_value("party_balance", r.message.party_balance), () => frm.set_value("party_balance", r.message.party_balance),
() => frm.set_value("party_name", r.message.party_name), () => frm.set_value("party_name", r.message.party_name),
() => frm.events.get_outstanding_documents(frm), () => frm.clear_table("references"),
() => frm.events.hide_unhide_fields(frm), () => frm.events.hide_unhide_fields(frm),
() => frm.events.set_dynamic_labels(frm), () => frm.events.set_dynamic_labels(frm),
() => { () => {
@@ -323,9 +323,7 @@ frappe.ui.form.on('Payment Entry', {
frm.events.set_account_currency_and_balance(frm, frm.doc.paid_from, frm.events.set_account_currency_and_balance(frm, frm.doc.paid_from,
"paid_from_account_currency", "paid_from_account_balance", function(frm) { "paid_from_account_currency", "paid_from_account_balance", function(frm) {
if (frm.doc.payment_type == "Receive") { if (frm.doc.payment_type == "Pay") {
frm.events.get_outstanding_documents(frm);
} else if (frm.doc.payment_type == "Pay") {
frm.events.paid_amount(frm); frm.events.paid_amount(frm);
} }
} }
@@ -337,9 +335,7 @@ frappe.ui.form.on('Payment Entry', {
frm.events.set_account_currency_and_balance(frm, frm.doc.paid_to, frm.events.set_account_currency_and_balance(frm, frm.doc.paid_to,
"paid_to_account_currency", "paid_to_account_balance", function(frm) { "paid_to_account_currency", "paid_to_account_balance", function(frm) {
if(frm.doc.payment_type == "Pay") { if (frm.doc.payment_type == "Receive") {
frm.events.get_outstanding_documents(frm);
} else if (frm.doc.payment_type == "Receive") {
if(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) { if(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
if(frm.doc.source_exchange_rate) { if(frm.doc.source_exchange_rate) {
frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate); frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
@@ -533,26 +529,49 @@ frappe.ui.form.on('Payment Entry', {
frm.events.set_unallocated_amount(frm); frm.events.set_unallocated_amount(frm);
}, },
get_outstanding_documents: function(frm) { get_outstanding_invoice: function(frm) {
const fields = [
{fieldtype:"Date", label: __("Posting From Date"), fieldname:"from_date"},
{fieldtype:"Column Break"},
{fieldtype:"Date", label: __("Posting To Date"), fieldname:"to_date"},
{fieldtype:"Section Break"},
];
frappe.prompt(fields, function(data){
frappe.flags.allocate_payment_amount = true;
frm.events.get_outstanding_documents(frm, data);
}, __("Select Date"), __("Get Outstanding Invoices"));
},
get_outstanding_documents: function(frm, date_args) {
frm.clear_table("references"); frm.clear_table("references");
if(!frm.doc.party) return; if(!frm.doc.party) {
return;
}
frm.events.check_mandatory_to_fetch(frm); frm.events.check_mandatory_to_fetch(frm);
var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency; var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
var args = {
"posting_date": frm.doc.posting_date,
"company": frm.doc.company,
"party_type": frm.doc.party_type,
"payment_type": frm.doc.payment_type,
"party": frm.doc.party,
"party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to,
"cost_center": frm.doc.cost_center
}
if(date_args) {
args["from_date"] = date_args["from_date"];
args["to_date"] = date_args["to_date"];
}
return frappe.call({ return frappe.call({
method: 'erpnext.accounts.doctype.payment_entry.payment_entry.get_outstanding_reference_documents', method: 'erpnext.accounts.doctype.payment_entry.payment_entry.get_outstanding_reference_documents',
args: { args: {
args: { args:args
"posting_date": frm.doc.posting_date,
"company": frm.doc.company,
"party_type": frm.doc.party_type,
"payment_type": frm.doc.payment_type,
"party": frm.doc.party,
"party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to,
"cost_center": frm.doc.cost_center
}
}, },
callback: function(r, rt) { callback: function(r, rt) {
if(r.message) { if(r.message) {
@@ -608,24 +627,26 @@ frappe.ui.form.on('Payment Entry', {
frm.events.allocate_party_amount_against_ref_docs(frm, frm.events.allocate_party_amount_against_ref_docs(frm,
(frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount)); (frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount));
frappe.flags.allocate_payment_amount = false;
} }
}); });
}, },
allocate_payment_amount: function(frm) { // allocate_payment_amount: function(frm) {
if(frm.doc.payment_type == 'Internal Transfer'){ // if(frm.doc.payment_type == 'Internal Transfer'){
return // return
} // }
if(frm.doc.references.length == 0){ // if(frm.doc.references.length == 0){
frm.events.get_outstanding_documents(frm); // frm.events.get_outstanding_documents(frm);
} // }
if(frm.doc.payment_type == 'Internal Transfer') { // if(frm.doc.payment_type == 'Internal Transfer') {
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount); // frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
} else { // } else {
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount); // frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
} // }
}, // },
allocate_party_amount_against_ref_docs: function(frm, paid_amount) { allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
var total_positive_outstanding_including_order = 0; var total_positive_outstanding_including_order = 0;
@@ -677,7 +698,7 @@ frappe.ui.form.on('Payment Entry', {
$.each(frm.doc.references || [], function(i, row) { $.each(frm.doc.references || [], function(i, row) {
row.allocated_amount = 0 //If allocate payment amount checkbox is unchecked, set zero to allocate amount row.allocated_amount = 0 //If allocate payment amount checkbox is unchecked, set zero to allocate amount
if(frm.doc.allocate_payment_amount){ if(frappe.flags.allocate_payment_amount){
if(row.outstanding_amount > 0 && allocated_positive_outstanding > 0) { if(row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
if(row.outstanding_amount >= allocated_positive_outstanding) { if(row.outstanding_amount >= allocated_positive_outstanding) {
row.allocated_amount = allocated_positive_outstanding; row.allocated_amount = allocated_positive_outstanding;
@@ -958,7 +979,7 @@ frappe.ui.form.on('Payment Entry', {
}, },
() => { () => {
if(frm.doc.payment_type != "Internal") { if(frm.doc.payment_type != "Internal") {
frm.events.get_outstanding_documents(frm); frm.clear_table("references");
} }
} }
]); ]);

View File

@@ -325,19 +325,17 @@
"reqd": 1 "reqd": 1
}, },
{ {
"collapsible": 1, "collapsible": 0,
"collapsible_depends_on": "references", "collapsible_depends_on": "",
"depends_on": "eval:(doc.party && doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)", "depends_on": "eval:(doc.party && doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)",
"fieldname": "section_break_14", "fieldname": "section_break_14",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Reference" "label": "Reference"
}, },
{ {
"default": "1", "fieldname": "get_outstanding_invoice",
"depends_on": "eval:in_list(['Pay', 'Receive'], doc.payment_type)", "fieldtype": "Button",
"fieldname": "allocate_payment_amount", "label": "Get Outstanding Invoice"
"fieldtype": "Check",
"label": "Allocate Payment Amount"
}, },
{ {
"fieldname": "references", "fieldname": "references",

View File

@@ -574,8 +574,8 @@ def get_outstanding_reference_documents(args):
# Get negative outstanding sales /purchase invoices # Get negative outstanding sales /purchase invoices
negative_outstanding_invoices = [] negative_outstanding_invoices = []
if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"): if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"):
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), args.get("party"),
args.get("party"), args.get("party_account"), party_account_currency, company_currency) args.get("party_account"), args.get("company"), party_account_currency, company_currency)
# Get positive outstanding sales /purchase invoices/ Fees # Get positive outstanding sales /purchase invoices/ Fees
condition = "" condition = ""
@@ -585,10 +585,16 @@ def get_outstanding_reference_documents(args):
# Add cost center condition # Add cost center condition
if args.get("cost_center") and get_allow_cost_center_in_entry_of_bs_account(): if args.get("cost_center") and get_allow_cost_center_in_entry_of_bs_account():
condition += " and cost_center='%s'" % args.get("cost_center") condition += " and cost_center='%s'" % args.get("cost_center")
if args.get("from_date") and args.get("to_date"):
condition += " and posting_date between '{0}' and '{1}'".format(args.get("from_date"), args.get("to_date"))
if args.get("company"):
condition += " and company = '{0}'".format(frappe.db.escape(args.get("company")))
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"), outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
args.get("party_account"), condition=condition) args.get("party_account"), condition=condition, limit=100)
for d in outstanding_invoices: for d in outstanding_invoices:
d["exchange_rate"] = 1 d["exchange_rate"] = 1
@@ -606,12 +612,13 @@ def get_outstanding_reference_documents(args):
orders_to_be_billed = [] orders_to_be_billed = []
if (args.get("party_type") != "Student"): if (args.get("party_type") != "Student"):
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"), orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
args.get("party"), party_account_currency, company_currency) args.get("party"), args.get("company"), party_account_currency, company_currency)
return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency, cost_center=None): def get_orders_to_be_billed(posting_date, party_type, party,
company, party_account_currency, company_currency, cost_center=None):
if party_type == "Customer": if party_type == "Customer":
voucher_type = 'Sales Order' voucher_type = 'Sales Order'
elif party_type == "Supplier": elif party_type == "Supplier":
@@ -641,6 +648,7 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
where where
{party_type} = %s {party_type} = %s
and docstatus = 1 and docstatus = 1
and company = %s
and ifnull(status, "") != "Closed" and ifnull(status, "") != "Closed"
and {ref_field} > advance_paid and {ref_field} > advance_paid
and abs(100 - per_billed) > 0.01 and abs(100 - per_billed) > 0.01
@@ -652,7 +660,7 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
"voucher_type": voucher_type, "voucher_type": voucher_type,
"party_type": scrub(party_type), "party_type": scrub(party_type),
"condition": condition "condition": condition
}), party, as_dict=True) }), (party, company), as_dict=True)
order_list = [] order_list = []
for d in orders: for d in orders:
@@ -663,7 +671,8 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
return order_list return order_list
def get_negative_outstanding_invoices(party_type, party, party_account, party_account_currency, company_currency, cost_center=None): def get_negative_outstanding_invoices(party_type, party, party_account,
company, party_account_currency, company_currency, cost_center=None):
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice" voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
supplier_condition = "" supplier_condition = ""
if voucher_type == "Purchase Invoice": if voucher_type == "Purchase Invoice":
@@ -684,7 +693,8 @@ def get_negative_outstanding_invoices(party_type, party, party_account, party_ac
from from
`tab{voucher_type}` `tab{voucher_type}`
where where
{party_type} = %s and {party_account} = %s and docstatus = 1 and outstanding_amount < 0 {party_type} = %s and {party_account} = %s and docstatus = 1 and
company = %s and outstanding_amount < 0
{supplier_condition} {supplier_condition}
order by order by
posting_date, name posting_date, name
@@ -696,7 +706,7 @@ def get_negative_outstanding_invoices(party_type, party, party_account, party_ac
"party_type": scrub(party_type), "party_type": scrub(party_type),
"party_account": "debit_to" if party_type == "Customer" else "credit_to", "party_account": "debit_to" if party_type == "Customer" else "credit_to",
"cost_center": cost_center "cost_center": cost_center
}), (party, party_account), as_dict=True) }), (party, party_account, company), as_dict=True)
@frappe.whitelist() @frappe.whitelist()

View File

@@ -632,6 +632,10 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
outstanding_invoices = [] outstanding_invoices = []
precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2 precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
limit_cond = ''
if limit:
limit_cond = " limit {}".format(limit)
if erpnext.get_party_account_type(party_type) == 'Receivable': if erpnext.get_party_account_type(party_type) == 'Receivable':
dr_or_cr = "debit_in_account_currency - credit_in_account_currency" dr_or_cr = "debit_in_account_currency - credit_in_account_currency"
payment_dr_or_cr = "credit_in_account_currency - debit_in_account_currency" payment_dr_or_cr = "credit_in_account_currency - debit_in_account_currency"
@@ -673,11 +677,11 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
and account = %(account)s and account = %(account)s
and {payment_dr_or_cr} > 0 and {payment_dr_or_cr} > 0
and against_voucher is not null and against_voucher != '' and against_voucher is not null and against_voucher != ''
group by against_voucher_type, against_voucher group by against_voucher_type, against_voucher {limit_cond}
""".format(payment_dr_or_cr=payment_dr_or_cr), { """.format(payment_dr_or_cr=payment_dr_or_cr, limit_cond= limit_cond), {
"party_type": party_type, "party_type": party_type,
"party": party, "party": party,
"account": account, "account": account
}, as_dict=True) }, as_dict=True)
pe_map = frappe._dict() pe_map = frappe._dict()