Merge pull request #30968 from nextchamp-saqib/validate-on-hold-invs
fix(accounts): minor fixes & validations
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 7257e6d..a3a7be2 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -346,6 +346,12 @@
)
)
+ if ref_doc.doctype == "Purchase Invoice" and ref_doc.get("on_hold"):
+ frappe.throw(
+ _("{0} {1} is on hold").format(d.reference_doctype, d.reference_name),
+ title=_("Invalid Invoice"),
+ )
+
if ref_doc.docstatus != 1:
frappe.throw(_("{0} {1} must be submitted").format(d.reference_doctype, d.reference_name))
diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
index 5b70b51..a8211c8 100644
--- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
@@ -743,6 +743,21 @@
flt(payment_entry.total_taxes_and_charges, 2), flt(10 / payment_entry.target_exchange_rate, 2)
)
+ def test_payment_entry_against_onhold_purchase_invoice(self):
+ pi = make_purchase_invoice()
+
+ pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank USD - _TC")
+ pe.reference_no = "1"
+ pe.reference_date = "2016-01-01"
+
+ # block invoice after creating payment entry
+ # since `get_payment_entry` will not attach blocked invoice to payment
+ pi.block_invoice()
+ with self.assertRaises(frappe.ValidationError) as err:
+ pe.save()
+
+ self.assertTrue("is on hold" in str(err.exception).lower())
+
def create_payment_entry(**args):
payment_entry = frappe.new_doc("Payment Entry")
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index a0c0ecc..b8154dd 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -3140,6 +3140,39 @@
si.reload()
self.assertTrue(si.items[0].serial_no)
+ def test_sales_invoice_with_disabled_account(self):
+ try:
+ account = frappe.get_doc("Account", "VAT 5% - _TC")
+ account.disabled = 1
+ account.save()
+
+ si = create_sales_invoice(do_not_save=True)
+ si.posting_date = add_days(getdate(), 1)
+ si.taxes = []
+
+ si.append(
+ "taxes",
+ {
+ "charge_type": "On Net Total",
+ "account_head": "VAT 5% - _TC",
+ "cost_center": "Main - _TC",
+ "description": "VAT @ 5.0",
+ "rate": 9,
+ },
+ )
+ si.save()
+
+ with self.assertRaises(frappe.ValidationError) as err:
+ si.submit()
+
+ self.assertTrue(
+ "Cannot create accounting entries against disabled accounts" in str(err.exception)
+ )
+
+ finally:
+ account.disabled = 0
+ account.save()
+
def test_gain_loss_with_advance_entry(self):
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index 89034eb..1598d91 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -31,6 +31,7 @@
if gl_map:
if not cancel:
validate_accounting_period(gl_map)
+ validate_disabled_accounts(gl_map)
gl_map = process_gl_map(gl_map, merge_entries)
if gl_map and len(gl_map) > 1:
save_entries(gl_map, adv_adj, update_outstanding, from_repost)
@@ -45,6 +46,26 @@
make_reverse_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding)
+def validate_disabled_accounts(gl_map):
+ accounts = [d.account for d in gl_map if d.account]
+
+ Account = frappe.qb.DocType("Account")
+
+ disabled_accounts = (
+ frappe.qb.from_(Account)
+ .where(Account.name.isin(accounts) & Account.disabled == 1)
+ .select(Account.name, Account.disabled)
+ ).run(as_dict=True)
+
+ if disabled_accounts:
+ account_list = "<br>"
+ account_list += ", ".join([frappe.bold(d.name) for d in disabled_accounts])
+ frappe.throw(
+ _("Cannot create accounting entries against disabled accounts: {0}").format(account_list),
+ title=_("Disabled Account Selected"),
+ )
+
+
def validate_accounting_period(gl_map):
accounting_periods = frappe.db.sql(
""" SELECT
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index abe9977..eeb5a7f 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -162,6 +162,7 @@
{account_type_condition}
AND is_group = 0
AND company = %(company)s
+ AND disabled = %(disabled)s
AND (account_currency = %(currency)s or ifnull(account_currency, '') = '')
AND `{searchfield}` LIKE %(txt)s
{mcond}
@@ -175,6 +176,7 @@
dict(
account_types=filters.get("account_type"),
company=filters.get("company"),
+ disabled=filters.get("disabled", 0),
currency=company_currency,
txt="%{}%".format(txt),
offset=start,
diff --git a/erpnext/public/js/controllers/accounts.js b/erpnext/public/js/controllers/accounts.js
index 84c7176..c1fe72b 100644
--- a/erpnext/public/js/controllers/accounts.js
+++ b/erpnext/public/js/controllers/accounts.js
@@ -27,7 +27,8 @@
query: "erpnext.controllers.queries.tax_account_query",
filters: {
"account_type": account_type,
- "company": doc.company
+ "company": doc.company,
+ "disabled": 0
}
}
});