Skip to content

Commit

Permalink
perf: pull latest details only for referenced vouchers
Browse files Browse the repository at this point in the history
(cherry picked from commit deb0d71)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.py
  • Loading branch information
ruthra-kumar authored and mergify[bot] committed Aug 17, 2023
1 parent 67c8350 commit 47345e8
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 13 deletions.
96 changes: 83 additions & 13 deletions erpnext/accounts/doctype/payment_entry/payment_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ def term_based_allocation_enabled_for_reference(
return False

def validate_allocated_amount_with_latest_data(self):
<<<<<<< HEAD
latest_references = get_outstanding_reference_documents(
{
"posting_date": self.posting_date,
Expand All @@ -197,16 +198,36 @@ def validate_allocated_amount_with_latest_data(self):
"get_orders_to_be_billed": True,
}
)
=======
if self.references:
uniq_vouchers = set([(x.reference_doctype, x.reference_name) for x in self.references])
vouchers = [frappe._dict({"voucher_type": x[0], "voucher_no": x[1]}) for x in uniq_vouchers]
latest_references = get_outstanding_reference_documents(
{
"posting_date": self.posting_date,
"company": self.company,
"party_type": self.party_type,
"payment_type": self.payment_type,
"party": self.party,
"party_account": self.paid_from if self.payment_type == "Receive" else self.paid_to,
"get_outstanding_invoices": True,
"get_orders_to_be_billed": True,
"vouchers": vouchers,
},
validate=True,
)
>>>>>>> deb0d71294 (perf: pull latest details only for referenced vouchers)

# Group latest_references by (voucher_type, voucher_no)
latest_lookup = {}
for d in latest_references:
d = frappe._dict(d)
latest_lookup.setdefault((d.voucher_type, d.voucher_no), frappe._dict())[d.payment_term] = d
# Group latest_references by (voucher_type, voucher_no)
latest_lookup = {}
for d in latest_references:
d = frappe._dict(d)
latest_lookup.setdefault((d.voucher_type, d.voucher_no), frappe._dict())[d.payment_term] = d

for idx, d in enumerate(self.get("references"), start=1):
latest = latest_lookup.get((d.reference_doctype, d.reference_name)) or frappe._dict()
for idx, d in enumerate(self.get("references"), start=1):
latest = latest_lookup.get((d.reference_doctype, d.reference_name)) or frappe._dict()

<<<<<<< HEAD
# If term based allocation is enabled, throw
if (
d.payment_term is None or d.payment_term == ""
Expand Down Expand Up @@ -254,15 +275,63 @@ def validate_allocated_amount_with_latest_data(self):
"Row #{0}: Allocated amount:{1} is greater than outstanding amount:{2} for Payment Term {3}"
).format(
d.idx, d.allocated_amount, latest.payment_term_outstanding, d.payment_term
=======
# If term based allocation is enabled, throw
if (
d.payment_term is None or d.payment_term == ""
) and self.term_based_allocation_enabled_for_reference(
d.reference_doctype, d.reference_name
):
frappe.throw(
_(
"{0} has Payment Term based allocation enabled. Select a Payment Term for Row #{1} in Payment References section"
).format(frappe.bold(d.reference_name), frappe.bold(idx))
>>>>>>> deb0d71294 (perf: pull latest details only for referenced vouchers)
)
)

if (flt(d.allocated_amount)) > 0 and flt(d.allocated_amount) > flt(latest.outstanding_amount):
frappe.throw(fail_message.format(d.idx))
# if no payment template is used by invoice and has a custom term(no `payment_term`), then invoice outstanding will be in 'None' key
latest = latest.get(d.payment_term) or latest.get(None)

# Check for negative outstanding invoices as well
if flt(d.allocated_amount) < 0 and flt(d.allocated_amount) < flt(latest.outstanding_amount):
frappe.throw(fail_message.format(d.idx))
# The reference has already been fully paid
if not latest:
frappe.throw(
_("{0} {1} has already been fully paid.").format(_(d.reference_doctype), d.reference_name)
)
# The reference has already been partly paid
elif latest.outstanding_amount < latest.invoice_amount and flt(
d.outstanding_amount, d.precision("outstanding_amount")
) != flt(latest.outstanding_amount, d.precision("outstanding_amount")):
frappe.throw(
_(
"{0} {1} has already been partly paid. Please use the 'Get Outstanding Invoice' or the 'Get Outstanding Orders' button to get the latest outstanding amounts."
).format(_(d.reference_doctype), d.reference_name)
)

fail_message = _("Row #{0}: Allocated Amount cannot be greater than outstanding amount.")

if (
d.payment_term
and (
(flt(d.allocated_amount)) > 0
and latest.payment_term_outstanding
and (flt(d.allocated_amount) > flt(latest.payment_term_outstanding))
)
and self.term_based_allocation_enabled_for_reference(d.reference_doctype, d.reference_name)
):
frappe.throw(
_(
"Row #{0}: Allocated amount:{1} is greater than outstanding amount:{2} for Payment Term {3}"
).format(
d.idx, d.allocated_amount, latest.payment_term_outstanding, d.payment_term
)
)

if (flt(d.allocated_amount)) > 0 and flt(d.allocated_amount) > flt(latest.outstanding_amount):
frappe.throw(fail_message.format(d.idx))

# Check for negative outstanding invoices as well
if flt(d.allocated_amount) < 0 and flt(d.allocated_amount) < flt(latest.outstanding_amount):
frappe.throw(fail_message.format(d.idx))

def delink_advance_entry_references(self):
for reference in self.references:
Expand Down Expand Up @@ -1463,6 +1532,7 @@ def get_outstanding_reference_documents(args):
min_outstanding=args.get("outstanding_amt_greater_than"),
max_outstanding=args.get("outstanding_amt_less_than"),
accounting_dimensions=accounting_dimensions_filter,
vouchers=args.get("vouchers") or None,
)

outstanding_invoices = split_invoices_based_on_payment_terms(
Expand Down
2 changes: 2 additions & 0 deletions erpnext/accounts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,7 @@ def get_outstanding_invoices(
min_outstanding=None,
max_outstanding=None,
accounting_dimensions=None,
vouchers=None,
):

ple = qb.DocType("Payment Ledger Entry")
Expand All @@ -909,6 +910,7 @@ def get_outstanding_invoices(

ple_query = QueryPaymentLedger()
invoice_list = ple_query.get_voucher_outstandings(
vouchers=vouchers,
common_filter=common_filter,
posting_date=posting_date,
min_outstanding=min_outstanding,
Expand Down

0 comments on commit 47345e8

Please sign in to comment.