fix(accounts): protect payment reconciliation log allocations

(cherry picked from commit eb2a08a8ac)
This commit is contained in:
pandiyan
2026-10-25 19:21:53 +00:00
committed by Mergify
parent 4ef6cba70b
commit f05951b0fa
3 changed files with 26 additions and 16 deletions
@@ -338,7 +338,7 @@ class PaymentReconciliation(Document):
row.update(payment)
row.is_advance = payment.book_advance_payments_in_separate_party_account
def get_invoice_entries(self):
def get_invoice_entries(self, vouchers=None):
# Fetch JVs, Sales and Purchase Invoices for 'invoices' to reconcile against
self.build_qb_filter_conditions(get_invoices=True)
@@ -357,7 +357,8 @@ class PaymentReconciliation(Document):
min_outstanding=self.minimum_invoice_amount if self.minimum_invoice_amount else None,
max_outstanding=self.maximum_invoice_amount if self.maximum_invoice_amount else None,
accounting_dimensions=self.accounting_dimension_filter_conditions,
limit=self.invoice_limit,
vouchers=vouchers,
limit=self.invoice_limit if not vouchers else None,
voucher_no=self.invoice_name,
)
@@ -370,7 +371,7 @@ class PaymentReconciliation(Document):
# Happens when non-standalone cr/dr notes are linked with another invoice through journal entry
non_reconciled_invoices = [x for x in non_reconciled_invoices if x.voucher_no not in cr_dr_notes]
if self.invoice_limit:
if self.invoice_limit and not vouchers:
non_reconciled_invoices = non_reconciled_invoices[: self.invoice_limit]
non_reconciled_invoices = sorted(
@@ -744,7 +745,9 @@ class PaymentReconciliation(Document):
).format(row.idx, row.allocated_amount, row.amount)
)
invoice_outstanding = unreconciled_invoices.get(row.invoice_type, {}).get(row.invoice_number)
invoice_outstanding = unreconciled_invoices.get(row.invoice_type, {}).get(
row.invoice_number, 0
)
if flt(row.allocated_amount) - invoice_outstanding > 0.009:
frappe.throw(
_(
@@ -752,6 +755,10 @@ class PaymentReconciliation(Document):
).format(row.idx, row.allocated_amount, invoice_outstanding)
)
unreconciled_invoices.setdefault(row.invoice_type, {})[row.invoice_number] = (
invoice_outstanding - flt(row.allocated_amount)
)
if not invoices_to_reconcile:
frappe.throw(_("No records found in Allocation table"))
@@ -247,7 +247,7 @@ def reconcile_based_on_filters(doc: None | str = None) -> None:
log = frappe.new_doc("Process Payment Reconciliation Log")
log.process_pr = doc
log.status = "Running"
log = log.save()
log = log.save(ignore_permissions=True)
job_name = f"process_{doc}_fetch_and_allocate"
if not is_job_running(job_name):
@@ -365,7 +365,7 @@ def fetch_and_allocate(doc: str) -> None:
reconcile_log.allocated = True
reconcile_log.total_allocations = len(reconcile_log.get("allocations"))
reconcile_log.reconciled_entries = 0
reconcile_log.save()
reconcile_log.save(ignore_permissions=True)
# generate reconcile job name
allocation = get_next_allocation(log)
@@ -412,6 +412,15 @@ def reconcile(doc: None | str = None) -> None:
for x in allocations:
pr.append("allocation", x)
pr.get_nonreconciled_payment_entries()
pr.get_invoice_entries(
vouchers=[
frappe._dict(voucher_type=x.invoice_type, voucher_no=x.invoice_number)
for x in allocations
]
)
pr.validate_allocation()
skip_ref_details_update_for_pe = check_multi_currency(pr)
# reconcile
pr.reconcile_allocations(skip_ref_details_update_for_pe=skip_ref_details_update_for_pe)
@@ -109,7 +109,7 @@
"in_create": 1,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-01-08 08:22:19.104975",
"modified": "2026-10-22 15:46:11.716794",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Process Payment Reconciliation Log",
@@ -117,32 +117,26 @@
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"share": 1,
"write": 1
"role": "Accounts Manager"
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"share": 1,
"write": 1
"role": "Accounts User"
}
],
"search_fields": "allocated, reconciled, total_allocations, reconciled_entries",
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
}