From ff9b39202447d18f84dc4173c4982e587b1cd927 Mon Sep 17 00:00:00 2001 From: ljain112 Date: Fri, 28 Nov 2025 19:13:31 +0530 Subject: [PATCH] fix: add duplicate purchase invoice validation in asset repair --- .../doctype/asset_repair/asset_repair.py | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py index ac172b9c42f..7686d72959b 100644 --- a/erpnext/assets/doctype/asset_repair/asset_repair.py +++ b/erpnext/assets/doctype/asset_repair/asset_repair.py @@ -82,12 +82,34 @@ class AssetRepair(AccountsController): ) def validate_purchase_invoices(self): + self.validate_duplicate_purchase_invoices() self.validate_purchase_invoice_status() for d in self.invoices: self.validate_expense_account(d) self.validate_purchase_invoice_repair_cost(d) + def validate_duplicate_purchase_invoices(self): + # account wise duplicate check + purchase_invoices = set() + duplicates = [] + for row in self.invoices: + key = (row.purchase_invoice, row.expense_account) + if key in purchase_invoices: + duplicates.append((row.idx, row.purchase_invoice, row.expense_account)) + else: + purchase_invoices.add(key) + + if duplicates: + duplicate_links = "".join( + [ + f"
  • {_('Row #{0}:').format(idx)} {get_link_to_form('Purchase Invoice', pi)} - {frappe.bold(account)}
  • " + for idx, pi, account in duplicates + ] + ) + msg = _("The following rows are duplicates:") + f"
    " + frappe.throw(msg) + def validate_purchase_invoice_status(self): pi_names = [row.purchase_invoice for row in self.invoices] docstatus = frappe._dict( @@ -120,7 +142,7 @@ class AssetRepair(AccountsController): if row.expense_account not in valid_accounts: frappe.throw( _( - "Row {0}: Expense account {1} is not valid for Purchase Invoice {2}. " + "Row #{0}: Expense account {1} is not valid for Purchase Invoice {2}. " "Only expense accounts from non-stock items are allowed." ).format( row.idx, @@ -138,7 +160,7 @@ class AssetRepair(AccountsController): if flt(row.repair_cost) > available_amount: frappe.throw( _( - "Row {0}: Repair cost {1} exceeds available amount {2} for Purchase Invoice {3} and Account {4}" + "Row #{0}: Repair cost {1} exceeds available amount {2} for Purchase Invoice {3} and Account {4}" ).format( row.idx, frappe.bold(frappe.format_value(row.repair_cost, {"fieldtype": "Currency"})),