From 2bf8dffb604c6c9356a9fa708d49ed3c6ca78dd7 Mon Sep 17 00:00:00 2001 From: ljain112 Date: Thu, 12 Jun 2025 11:57:30 +0530 Subject: [PATCH] fix: auto append_taxes_from_item_tax_template in backend (cherry picked from commit 4cb1fa2b6ba0a2990296dcdcec6064b5c33a6286) # Conflicts: # erpnext/controllers/accounts_controller.py # erpnext/controllers/tests/test_accounts_controller.py --- .../accounts_settings/accounts_settings.js | 17 ++++++++++ .../accounts_settings/accounts_settings.json | 8 +++++ .../accounts_settings/accounts_settings.py | 12 +++++++ .../sales_invoice/test_sales_invoice.py | 4 +++ erpnext/controllers/accounts_controller.py | 20 ++++++++++++ .../tests/test_accounts_controller.py | 31 +++++++++++++++++++ .../doctype/quotation/test_quotation.py | 11 +++++-- 7 files changed, 100 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js index 95332acdc28..ba577f2b8c9 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js @@ -22,4 +22,21 @@ frappe.ui.form.on("Accounts Settings", { } ); }, + + add_taxes_from_taxes_and_charges_template(frm) { + toggle_tax_settings(frm, "add_taxes_from_taxes_and_charges_template"); + }, + add_taxes_from_item_tax_template(frm) { + toggle_tax_settings(frm, "add_taxes_from_item_tax_template"); + }, }); + +function toggle_tax_settings(frm, field_name) { + if (frm.doc[field_name]) { + const other_field = + field_name === "add_taxes_from_item_tax_template" + ? "add_taxes_from_taxes_and_charges_template" + : "add_taxes_from_item_tax_template"; + frm.set_value(other_field, 0); + } +} diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index 47aa8a1834e..80b7d996101 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -31,6 +31,7 @@ "determine_address_tax_category_from", "column_break_19", "add_taxes_from_item_tax_template", + "add_taxes_from_taxes_and_charges_template", "book_tax_discount_loss", "round_row_wise_tax", "print_settings", @@ -601,6 +602,13 @@ "fieldname": "allow_pegged_currencies_exchange_rates", "fieldtype": "Check", "label": "Allow Implicit Pegged Currency Conversion" + }, + { + "default": "0", + "description": "If no taxes are set, and Taxes and Charges Template is selected, the system will automatically apply the taxes from the chosen template.", + "fieldname": "add_taxes_from_taxes_and_charges_template", + "fieldtype": "Check", + "label": "Automatically Add Taxes from Taxes and Charges Template" } ], "icon": "icon-cog", diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py index 2a3cada2398..d03ebed353e 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py @@ -25,6 +25,7 @@ class AccountsSettings(Document): acc_frozen_upto: DF.Date | None add_taxes_from_item_tax_template: DF.Check + add_taxes_from_taxes_and_charges_template: DF.Check allow_multi_currency_invoices_against_single_party_account: DF.Check allow_pegged_currencies_exchange_rates: DF.Check allow_stale: DF.Check @@ -74,6 +75,7 @@ class AccountsSettings(Document): # end: auto-generated types def validate(self): + self.validate_auto_tax_settings() old_doc = self.get_doc_before_save() clear_cache = False @@ -140,3 +142,13 @@ class AccountsSettings(Document): if self.has_value_changed("reconciliation_queue_size"): if cint(self.reconciliation_queue_size) < 5 or cint(self.reconciliation_queue_size) > 100: frappe.throw(_("Queue Size should be between 5 and 100")) + + def validate_auto_tax_settings(self): + if self.add_taxes_from_item_tax_template and self.add_taxes_from_taxes_and_charges_template: + frappe.throw( + _("You cannot enable both the settings '{0}' and '{1}'.").format( + frappe.bold(self.meta.get_label("add_taxes_from_item_tax_template")), + frappe.bold(self.meta.get_label("add_taxes_from_taxes_and_charges_template")), + ), + title=_("Auto Tax Settings Error"), + ) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index f183db99842..1030a32f161 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -836,6 +836,10 @@ class TestSalesInvoice(FrappeTestCase): w = self.make() self.assertEqual(w.outstanding_amount, w.base_rounded_total) + @IntegrationTestCase.change_settings( + "Accounts Settings", + {"add_taxes_from_item_tax_template": 0, "add_taxes_from_taxes_and_charges_template": 0}, + ) def test_rounded_total_with_cash_discount(self): si = frappe.copy_doc(test_records[2]) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index e33f8f8b64c..2885490b31f 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1134,10 +1134,24 @@ class AccountsController(TransactionBase): return True def set_taxes_and_charges(self): +<<<<<<< HEAD if frappe.db.get_single_value("Accounts Settings", "add_taxes_from_item_tax_template"): if hasattr(self, "taxes_and_charges") and not self.get("taxes") and not self.get("is_pos"): if tax_master_doctype := self.meta.get_field("taxes_and_charges").options: self.append_taxes_from_master(tax_master_doctype) +======= + if self.get("taxes") or self.get("is_pos"): + return + + if frappe.get_single_value( + "Accounts Settings", "add_taxes_from_taxes_and_charges_template" + ) and hasattr(self, "taxes_and_charges"): + if tax_master_doctype := self.meta.get_field("taxes_and_charges").options: + self.append_taxes_from_master(tax_master_doctype) + + if frappe.get_single_value("Accounts Settings", "add_taxes_from_item_tax_template"): + self.append_taxes_from_item_tax_template() +>>>>>>> 4cb1fa2b6b (fix: auto append_taxes_from_item_tax_template in backend) def append_taxes_from_master(self, tax_master_doctype=None): if self.get("taxes_and_charges"): @@ -1169,6 +1183,12 @@ class AccountsController(TransactionBase): "account_head": account_head, "rate": 0, "description": account_head, +<<<<<<< HEAD +======= + "set_by_item_tax_template": 1, + "category": "Total", + "add_deduct_tax": "Add", +>>>>>>> 4cb1fa2b6b (fix: auto append_taxes_from_item_tax_template in backend) }, ) diff --git a/erpnext/controllers/tests/test_accounts_controller.py b/erpnext/controllers/tests/test_accounts_controller.py index 28536893ab5..b3b7427d32f 100644 --- a/erpnext/controllers/tests/test_accounts_controller.py +++ b/erpnext/controllers/tests/test_accounts_controller.py @@ -931,7 +931,14 @@ class TestAccountsController(FrappeTestCase): self.assertEqual(exc_je_for_si, []) self.assertEqual(exc_je_for_pe, []) +<<<<<<< HEAD @change_settings("Accounts Settings", {"add_taxes_from_item_tax_template": 1}) +======= + @IntegrationTestCase.change_settings( + "Accounts Settings", + {"add_taxes_from_item_tax_template": 0, "add_taxes_from_taxes_and_charges_template": 1}, + ) +>>>>>>> 4cb1fa2b6b (fix: auto append_taxes_from_item_tax_template in backend) def test_18_fetch_taxes_based_on_taxes_and_charges_template(self): # Create a Sales Taxes and Charges Template if not frappe.db.exists("Sales Taxes and Charges Template", "_Test Tax - _TC"): @@ -960,6 +967,30 @@ class TestAccountsController(FrappeTestCase): self.assertEqual(sinv.total_taxes_and_charges, 4.5) + @IntegrationTestCase.change_settings( + "Accounts Settings", + {"add_taxes_from_item_tax_template": 1, "add_taxes_from_taxes_and_charges_template": 0}, + ) + def test_19_fetch_taxes_based_on_item_tax_template_template(self): + # Create a Sales Invoice + sinv = frappe.new_doc("Sales Invoice") + sinv.customer = self.customer + sinv.company = self.company + sinv.currency = "INR" + sinv.append( + "items", + { + "item_code": "_Test Item", + "qty": 1, + "rate": 50, + "item_tax_template": "_Test Account Excise Duty @ 10 - _TC", + }, + ) + sinv.insert() + + self.assertEqual(sinv.taxes[0].account_head, "_Test Account Excise Duty - _TC") + self.assertEqual(sinv.total_taxes_and_charges, 5) + def test_20_journal_against_sales_invoice(self): # Invoice in Foreign Currency si = self.create_sales_invoice(qty=1, conversion_rate=80, rate=1) diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py index 0e58b950e99..98a2ae04c67 100644 --- a/erpnext/selling/doctype/quotation/test_quotation.py +++ b/erpnext/selling/doctype/quotation/test_quotation.py @@ -179,6 +179,10 @@ class TestQuotation(FrappeTestCase): sales_order.delivery_date = nowdate() sales_order.insert() + @IntegrationTestCase.change_settings( + "Accounts Settings", + {"add_taxes_from_item_tax_template": 0, "add_taxes_from_taxes_and_charges_template": 0}, + ) def test_make_sales_order_with_terms(self): from erpnext.selling.doctype.quotation.quotation import make_sales_order @@ -716,6 +720,10 @@ class TestQuotation(FrappeTestCase): quotation.items[0].conversion_factor = 2.23 self.assertRaises(frappe.ValidationError, quotation.save) + @IntegrationTestCase.change_settings( + "Accounts Settings", + {"add_taxes_from_item_tax_template": 1, "add_taxes_from_taxes_and_charges_template": 0}, + ) def test_item_tax_template_for_quotation(self): from erpnext.stock.doctype.item.test_item import make_item @@ -757,10 +765,7 @@ class TestQuotation(FrappeTestCase): item_doc.save() quotation = make_quotation(item_code="_Test Item Tax Template QTN", qty=1, rate=100, do_not_submit=1) - self.assertFalse(quotation.taxes) - quotation.append_taxes_from_item_tax_template() - quotation.save() self.assertTrue(quotation.taxes) for row in quotation.taxes: self.assertEqual(row.account_head, "_Test Vat - _TC")