perf: Timeout while doing payment reconciliation (v13) (#33818)

perf: Timeout while doing payment reconciliation
This commit is contained in:
Deepesh Garg
2023-01-31 09:37:45 +05:30
committed by GitHub
parent abb466e2fb
commit 4bf3e310e1
3 changed files with 66 additions and 53 deletions

View File

@@ -1255,6 +1255,7 @@ def get_outstanding_reference_documents(args):
args.get("party_type"), args.get("party_type"),
args.get("party"), args.get("party"),
args.get("party_account"), args.get("party_account"),
args.get("company"),
filters=args, filters=args,
condition=condition, condition=condition,
) )

View File

@@ -211,7 +211,7 @@ class PaymentReconciliation(Document):
condition += " and cost_center = '{0}' ".format(self.cost_center) condition += " and cost_center = '{0}' ".format(self.cost_center)
non_reconciled_invoices = get_outstanding_invoices( non_reconciled_invoices = get_outstanding_invoices(
self.party_type, self.party, self.receivable_payable_account, condition=condition self.party_type, self.party, self.receivable_payable_account, self.company, condition=condition
) )
if self.invoice_limit: if self.invoice_limit:

View File

@@ -840,7 +840,7 @@ def remove_return_pos_invoices(party_type, party, invoice_list):
return invoice_list return invoice_list
def get_outstanding_invoices(party_type, party, account, condition=None, filters=None): def get_outstanding_invoices(party_type, party, account, company, condition=None, filters=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
@@ -892,61 +892,73 @@ def get_outstanding_invoices(party_type, party, account, condition=None, filters
invoice_list = remove_return_pos_invoices(party_type, party, invoice_list) invoice_list = remove_return_pos_invoices(party_type, party, invoice_list)
payment_entries = frappe.db.sql( if invoice_list:
""" invoices = [d.voucher_no for d in invoice_list]
select against_voucher_type, against_voucher, payment_entries = frappe.db.sql(
ifnull(sum({payment_dr_or_cr}), 0) as payment_amount """
from `tabGL Entry` select against_voucher_type, against_voucher,
where party_type = %(party_type)s and party = %(party)s ifnull(sum({payment_dr_or_cr}), 0) as payment_amount
and account = %(account)s from `tabGL Entry`
and {payment_dr_or_cr} > 0 where
and against_voucher is not null and against_voucher != '' company = %(company)s
and is_cancelled=0 and party_type = %(party_type)s and party = %(party)s
group by against_voucher_type, against_voucher and account = %(account)s
""".format( and {payment_dr_or_cr} > 0
payment_dr_or_cr=payment_dr_or_cr and ifnull(against_voucher, '') != ''
), and is_cancelled=0
{"party_type": party_type, "party": party, "account": account}, and against_voucher in %(invoices)s
as_dict=True, group by against_voucher_type, against_voucher
) """.format(
payment_dr_or_cr=payment_dr_or_cr,
),
{
"company": company,
"party_type": party_type,
"party": party,
"account": account,
"invoices": invoices,
},
as_dict=True,
)
pe_map = frappe._dict() pe_map = frappe._dict()
for d in payment_entries: for d in payment_entries:
pe_map.setdefault((d.against_voucher_type, d.against_voucher), d.payment_amount) pe_map.setdefault((d.against_voucher_type, d.against_voucher), d.payment_amount)
for d in invoice_list: for d in invoice_list:
payment_amount = pe_map.get((d.voucher_type, d.voucher_no), 0) payment_amount = pe_map.get((d.voucher_type, d.voucher_no), 0)
outstanding_amount = flt(d.invoice_amount - payment_amount, precision) outstanding_amount = flt(d.invoice_amount - payment_amount, precision)
if outstanding_amount > 0.5 / (10**precision): if outstanding_amount > 0.5 / (10**precision):
if ( if (
filters filters
and filters.get("outstanding_amt_greater_than") and filters.get("outstanding_amt_greater_than")
and not ( and not (
outstanding_amount >= filters.get("outstanding_amt_greater_than") outstanding_amount >= filters.get("outstanding_amt_greater_than")
and outstanding_amount <= filters.get("outstanding_amt_less_than") and outstanding_amount <= filters.get("outstanding_amt_less_than")
)
):
continue
if not d.voucher_type == "Purchase Invoice" or d.voucher_no not in held_invoices:
outstanding_invoices.append(
frappe._dict(
{
"voucher_no": d.voucher_no,
"voucher_type": d.voucher_type,
"posting_date": d.posting_date,
"invoice_amount": flt(d.invoice_amount),
"payment_amount": payment_amount,
"outstanding_amount": outstanding_amount,
"due_date": d.due_date,
"currency": d.currency,
}
) )
) ):
continue
if not d.voucher_type == "Purchase Invoice" or d.voucher_no not in held_invoices:
outstanding_invoices.append(
frappe._dict(
{
"voucher_no": d.voucher_no,
"voucher_type": d.voucher_type,
"posting_date": d.posting_date,
"invoice_amount": flt(d.invoice_amount),
"payment_amount": payment_amount,
"outstanding_amount": outstanding_amount,
"due_date": d.due_date,
"currency": d.currency,
}
)
)
outstanding_invoices = sorted(
outstanding_invoices, key=lambda k: k["due_date"] or getdate(nowdate())
)
outstanding_invoices = sorted(
outstanding_invoices, key=lambda k: k["due_date"] or getdate(nowdate())
)
return outstanding_invoices return outstanding_invoices