diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 33cd0d55ef7..8bbea96e1d2 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -13,6 +13,7 @@ from erpnext.accounts.deferred_revenue import validate_service_stop_date from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import ( validate_docs_for_deferred_accounting, + validate_docs_for_voucher_types, ) from erpnext.accounts.doctype.sales_invoice.sales_invoice import ( check_if_return_invoice_linked_with_payment_entry, @@ -494,6 +495,7 @@ class PurchaseInvoice(BuyingController): def validate_for_repost(self): self.validate_write_off_account() self.validate_expense_account() + validate_docs_for_voucher_types(["Purchase Invoice"]) validate_docs_for_deferred_accounting([], [self.name]) def on_submit(self): diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json index 7f71bd61e35..b62b4bab140 100644 --- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json +++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json @@ -492,6 +492,7 @@ "fieldtype": "Column Break" }, { + "allow_on_submit": 1, "fieldname": "project", "fieldtype": "Link", "label": "Project", @@ -499,6 +500,7 @@ "print_hide": 1 }, { + "allow_on_submit": 1, "default": ":Company", "depends_on": "eval:!doc.is_fixed_asset", "fieldname": "cost_center", diff --git a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py index 69cfe9fcd74..1d72a46c12f 100644 --- a/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py +++ b/erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.py @@ -10,12 +10,7 @@ from frappe.utils.data import comma_and class RepostAccountingLedger(Document): def __init__(self, *args, **kwargs): super(RepostAccountingLedger, self).__init__(*args, **kwargs) - self._allowed_types = [ - x.document_type - for x in frappe.db.get_all( - "Repost Allowed Types", filters={"allowed": True}, fields=["distinct(document_type)"] - ) - ] + self._allowed_types = get_allowed_types_from_settings() def validate(self): self.validate_vouchers() @@ -56,15 +51,7 @@ class RepostAccountingLedger(Document): def validate_vouchers(self): if self.vouchers: - # Validate voucher types - voucher_types = set([x.voucher_type for x in self.vouchers]) - if disallowed_types := voucher_types.difference(self._allowed_types): - frappe.throw( - _("{0} types are not allowed. Only {1} are.").format( - frappe.bold(comma_and(list(disallowed_types))), - frappe.bold(comma_and(list(self._allowed_types))), - ) - ) + validate_docs_for_voucher_types([x.voucher_type for x in self.vouchers]) def get_existing_ledger_entries(self): vouchers = [x.voucher_no for x in self.vouchers] @@ -168,6 +155,15 @@ def start_repost(account_repost_doc=str) -> None: frappe.db.commit() +def get_allowed_types_from_settings(): + return [ + x.document_type + for x in frappe.db.get_all( + "Repost Allowed Types", filters={"allowed": True}, fields=["distinct(document_type)"] + ) + ] + + def validate_docs_for_deferred_accounting(sales_docs, purchase_docs): docs_with_deferred_revenue = frappe.db.get_all( "Sales Invoice Item", @@ -191,6 +187,25 @@ def validate_docs_for_deferred_accounting(sales_docs, purchase_docs): ) +def validate_docs_for_voucher_types(doc_voucher_types): + allowed_types = get_allowed_types_from_settings() + # Validate voucher types + voucher_types = set(doc_voucher_types) + if disallowed_types := voucher_types.difference(allowed_types): + message = "are" if len(disallowed_types) > 1 else "is" + frappe.throw( + _("{0} {1} not allowed to be reposted. Modify {2} to enable reposting.").format( + frappe.bold(comma_and(list(disallowed_types))), + message, + frappe.bold( + frappe.utils.get_link_to_form( + "Repost Accounting Ledger Settings", "Repost Accounting Ledger Settings" + ) + ), + ) + ) + + @frappe.whitelist() @frappe.validate_and_sanitize_search_inputs def get_repost_allowed_types(doctype, txt, searchfield, start, page_len, filters): diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 27ba8853c7d..34ea24dde49 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -17,6 +17,7 @@ from erpnext.accounts.doctype.loyalty_program.loyalty_program import ( ) from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import ( validate_docs_for_deferred_accounting, + validate_docs_for_voucher_types, ) from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import ( get_party_tax_withholding_details, @@ -180,6 +181,7 @@ class SalesInvoice(SellingController): self.validate_write_off_account() self.validate_account_for_change_amount() self.validate_income_account() + validate_docs_for_voucher_types(["Sales Invoice"]) validate_docs_for_deferred_accounting([self.name], []) def validate_fixed_asset(self):