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"),
args.get("party_account"),
args.get("company"),
filters=args,
condition=condition,
)

View File

@@ -211,7 +211,7 @@ class PaymentReconciliation(Document):
condition += " and cost_center = '{0}' ".format(self.cost_center)
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:

View File

@@ -840,7 +840,7 @@ def remove_return_pos_invoices(party_type, party, 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 = []
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)
payment_entries = frappe.db.sql(
"""
select against_voucher_type, against_voucher,
ifnull(sum({payment_dr_or_cr}), 0) as payment_amount
from `tabGL Entry`
where party_type = %(party_type)s and party = %(party)s
and account = %(account)s
and {payment_dr_or_cr} > 0
and against_voucher is not null and against_voucher != ''
and is_cancelled=0
group by against_voucher_type, against_voucher
""".format(
payment_dr_or_cr=payment_dr_or_cr
),
{"party_type": party_type, "party": party, "account": account},
as_dict=True,
)
if invoice_list:
invoices = [d.voucher_no for d in invoice_list]
payment_entries = frappe.db.sql(
"""
select against_voucher_type, against_voucher,
ifnull(sum({payment_dr_or_cr}), 0) as payment_amount
from `tabGL Entry`
where
company = %(company)s
and party_type = %(party_type)s and party = %(party)s
and account = %(account)s
and {payment_dr_or_cr} > 0
and ifnull(against_voucher, '') != ''
and is_cancelled=0
and against_voucher in %(invoices)s
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()
for d in payment_entries:
pe_map.setdefault((d.against_voucher_type, d.against_voucher), d.payment_amount)
pe_map = frappe._dict()
for d in payment_entries:
pe_map.setdefault((d.against_voucher_type, d.against_voucher), d.payment_amount)
for d in invoice_list:
payment_amount = pe_map.get((d.voucher_type, d.voucher_no), 0)
outstanding_amount = flt(d.invoice_amount - payment_amount, precision)
if outstanding_amount > 0.5 / (10**precision):
if (
filters
and filters.get("outstanding_amt_greater_than")
and not (
outstanding_amount >= filters.get("outstanding_amt_greater_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,
}
for d in invoice_list:
payment_amount = pe_map.get((d.voucher_type, d.voucher_no), 0)
outstanding_amount = flt(d.invoice_amount - payment_amount, precision)
if outstanding_amount > 0.5 / (10**precision):
if (
filters
and filters.get("outstanding_amt_greater_than")
and not (
outstanding_amount >= filters.get("outstanding_amt_greater_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,
}
)
)
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