diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index ac706666547..c987231fe17 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -97,6 +97,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum row.update({"rate": d.base_net_rate, "amount": d.base_net_amount}) total_tax = 0 + total_other_charges = 0 for tax in tax_columns: item_tax = itemised_tax.get(d.name, {}).get(tax, {}) row.update( @@ -105,10 +106,18 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum frappe.scrub(tax + " Amount"): item_tax.get("tax_amount", 0), } ) - total_tax += flt(item_tax.get("tax_amount")) + if item_tax.get("is_other_charges"): + total_other_charges += flt(item_tax.get("tax_amount")) + else: + total_tax += flt(item_tax.get("tax_amount")) row.update( - {"total_tax": total_tax, "total": d.base_net_amount + total_tax, "currency": company_currency} + { + "total_tax": total_tax, + "total_other_charges": total_other_charges, + "total": d.base_net_amount + total_tax, + "currency": company_currency, + } ) if filters.get("group_by"): @@ -477,7 +486,7 @@ def get_tax_accounts( tax_details = frappe.db.sql( """ select - name, parent, description, item_wise_tax_detail, + name, parent, description, item_wise_tax_detail, account_head, charge_type, {add_deduct_tax}, base_tax_amount_after_discount_amount from `tab%s` where @@ -493,11 +502,22 @@ def get_tax_accounts( tuple([doctype] + list(invoice_item_row)), ) + account_doctype = frappe.qb.DocType("Account") + + query = ( + frappe.qb.from_(account_doctype) + .select(account_doctype.name) + .where((account_doctype.account_type == "Tax")) + ) + + tax_accounts = query.run() + for ( name, parent, description, item_wise_tax_detail, + account_head, charge_type, add_deduct_tax, tax_amount, @@ -540,7 +560,11 @@ def get_tax_accounts( ) itemised_tax.setdefault(d.name, {})[description] = frappe._dict( - {"tax_rate": tax_rate, "tax_amount": tax_value} + { + "tax_rate": tax_rate, + "tax_amount": tax_value, + "is_other_charges": 0 if tuple([account_head]) in tax_accounts else 1, + } ) except ValueError: @@ -583,6 +607,13 @@ def get_tax_accounts( "options": "currency", "width": 100, }, + { + "label": _("Total Other Charges"), + "fieldname": "total_other_charges", + "fieldtype": "Currency", + "options": "currency", + "width": 100, + }, { "label": _("Total"), "fieldname": "total", diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 87fa72d74f0..143fe408c34 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -945,7 +945,12 @@ class Item(Document): if doctype == "Product Bundle": filters = {"new_item_code": self.name} - if doctype in ( + if linked_doc := frappe.db.get_value( + doctype, filters, ["new_item_code as docname"], as_dict=True + ): + return linked_doc.update({"doctype": doctype}) + + elif doctype in ( "Purchase Invoice Item", "Sales Invoice Item", ): diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py index 89da72195fc..1cee553be5b 100644 --- a/erpnext/stock/doctype/item/test_item.py +++ b/erpnext/stock/doctype/item/test_item.py @@ -786,6 +786,36 @@ class TestItem(FrappeTestCase): item.save() self.assertTrue(len(item.customer_code) > 140) + def test_update_is_stock_item(self): + # Step - 1: Create an Item with Maintain Stock enabled + item = make_item(properties={"is_stock_item": 1}) + + # Step - 2: Disable Maintain Stock + item.is_stock_item = 0 + item.save() + item.reload() + self.assertEqual(item.is_stock_item, 0) + + # Step - 3: Create Product Bundle + pb = frappe.new_doc("Product Bundle") + pb.new_item_code = item.name + pb.flags.ignore_mandatory = True + pb.save() + + # Step - 4: Try to enable Maintain Stock, should throw a validation error + item.is_stock_item = 1 + self.assertRaises(frappe.ValidationError, item.save) + item.reload() + + # Step - 5: Delete Product Bundle + pb.delete() + + # Step - 6: Again try to enable Maintain Stock + item.is_stock_item = 1 + item.save() + item.reload() + self.assertEqual(item.is_stock_item, 1) + def set_item_variant_settings(fields): doc = frappe.get_doc("Item Variant Settings")