From a3d9185ea79cb94b3f170e61c3a010d036d486c0 Mon Sep 17 00:00:00 2001 From: ljain112 Date: Wed, 27 Dec 2023 19:51:05 +0530 Subject: [PATCH 1/5] fix: include non-existing hsn codes (cherry picked from commit 8225ad44b955f881255872e63576017e17704396) --- .../hsn_wise_summary_of_outward_supplies.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/india_compliance/gst_india/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py b/india_compliance/gst_india/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py index 25a21a4a3..ae89bd516 100644 --- a/india_compliance/gst_india/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py +++ b/india_compliance/gst_india/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py @@ -182,11 +182,11 @@ def get_items(filters): sum(`tabSales Invoice Item`.taxable_value) AS taxable_value, `tabSales Invoice Item`.parent, `tabSales Invoice Item`.item_code, - `tabGST HSN Code`.description + COALESCE(`tabGST HSN Code`.description, 'NA') AS description FROM `tabSales Invoice` INNER JOIN `tabSales Invoice Item` ON `tabSales Invoice`.name = `tabSales Invoice Item`.parent - INNER JOIN `tabGST HSN Code` ON `tabSales Invoice Item`.gst_hsn_code = `tabGST HSN Code`.name + LEFT JOIN `tabGST HSN Code` ON `tabSales Invoice Item`.gst_hsn_code = `tabGST HSN Code`.name WHERE `tabSales Invoice`.docstatus = 1 AND `tabSales Invoice`.company_gstin != IFNULL(`tabSales Invoice`.billing_address_gstin, '') From 87e3093453ff4ba0bb7f980490ee105fa397b4de Mon Sep 17 00:00:00 2001 From: ljain112 Date: Thu, 28 Dec 2023 18:45:10 +0530 Subject: [PATCH 2/5] fix: patch to update gst treatment in transaction (cherry picked from commit c0a92c918580f311730ac1f96621db1097986c76) --- india_compliance/install.py | 1 + india_compliance/patches.txt | 1 + ...atment_for_taxable_nil_transaction_item.py | 49 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 india_compliance/patches/post_install/update_gst_treatment_for_taxable_nil_transaction_item.py diff --git a/india_compliance/install.py b/india_compliance/install.py index e8dcdcd71..a6d8e6ab1 100644 --- a/india_compliance/install.py +++ b/india_compliance/install.py @@ -41,6 +41,7 @@ "update_itc_classification_field", "improve_item_tax_template", "update_vehicle_no_field_in_purchase_receipt", + "update_gst_treatment_for_taxable_nil_transaction_item", # it should be always after improve item tax template ) diff --git a/india_compliance/patches.txt b/india_compliance/patches.txt index a450ab2df..9cf9442d4 100644 --- a/india_compliance/patches.txt +++ b/india_compliance/patches.txt @@ -37,3 +37,4 @@ india_compliance.patches.v14.update_purchase_reco_email_template india_compliance.patches.v14.delete_purchase_receipt_standard_custom_fields india_compliance.patches.post_install.improve_item_tax_template #1 india_compliance.patches.post_install.update_vehicle_no_field_in_purchase_receipt +india_compliance.patches.post_install.update_gst_treatment_for_taxable_nil_transaction_item diff --git a/india_compliance/patches/post_install/update_gst_treatment_for_taxable_nil_transaction_item.py b/india_compliance/patches/post_install/update_gst_treatment_for_taxable_nil_transaction_item.py new file mode 100644 index 000000000..6b9258729 --- /dev/null +++ b/india_compliance/patches/post_install/update_gst_treatment_for_taxable_nil_transaction_item.py @@ -0,0 +1,49 @@ +import frappe + +DOCTYPES = ("Sales Invoice Item", "Purchase Invoice Item") + + +def execute(): + update_taxable_items() + update_nil_rated_items() + + +def update_taxable_items(): + # Patch invoices where gst_treatment is Nil-Rated but tax is applied. + # Cases where is_nil_exempt was checked but Item tax template was selected. + for dt in DOCTYPES: + doctype = frappe.qb.DocType(dt) + + ( + frappe.qb.update(doctype) + .set(doctype.gst_treatment, "Taxable") + .where(doctype.gst_treatment.notin(("Zero-Rated", "Taxable"))) + .where( + ( + doctype.cgst_amount + + doctype.igst_amount + + doctype.sgst_amount + + doctype.cess_amount + ) + != 0 + ) + .run() + ) + + +def update_nil_rated_items(): + # Patch invoices where Item Tax Template is Nil-Rated. + + nil_rated_templates = frappe.get_all( + "Item Tax Template", filters={"gst_treatment": "Nil-Rated"}, pluck="name" + ) + for dt in DOCTYPES: + doctype = frappe.qb.DocType(dt) + + ( + frappe.qb.update(doctype) + .set(doctype.gst_treatment, "Nil-Rated") + .where(doctype.item_tax_template.isin(nil_rated_templates)) + .where(doctype.gst_treatment == "Taxable") + .run() + ) From 4fe664ab2f4009869a15c5aae5cef8cc36988e64 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 28 Dec 2023 19:01:43 +0530 Subject: [PATCH 3/5] refactor: update gst treatment for transactions in more structured way (#1492) * refactor: update gst treatment for transactions in more structured way * fix: treat item as nil rated if no taxes are applied * fix: test cases * refactor: seperate functionality for no taxes --------- Co-authored-by: ljain112 (cherry picked from commit 8dd34cb711c38beb099f6b6e1bed9b80c535873e) --- .../gst_india/data/test_e_invoice.json | 62 ++++----- .../overrides/test_transaction_data.py | 13 +- .../gst_india/overrides/transaction.py | 128 ++++++++++-------- .../gst_india/utils/test_e_invoice.py | 42 ++++-- .../gst_india/utils/test_e_waybill.py | 2 +- 5 files changed, 146 insertions(+), 101 deletions(-) diff --git a/india_compliance/gst_india/data/test_e_invoice.json b/india_compliance/gst_india/data/test_e_invoice.json index da1bf3bd0..5859cc3f4 100644 --- a/india_compliance/gst_india/data/test_e_invoice.json +++ b/india_compliance/gst_india/data/test_e_invoice.json @@ -27,30 +27,30 @@ }, "ItemList": [ { - "AssAmt": 100000, + "AssAmt": 100000.0, "CesAmt": 0, "CesNonAdvlAmt": 0, "CesRt": 0, - "CgstAmt": 0, + "CgstAmt": 9000.0, "Discount": 0, - "GstRt": 0, + "GstRt": 18, "HsnCd": "61149090", "IgstAmt": 0, "IsServc": "N", "PrdDesc": "Test Trading Goods 1", - "Qty": 1000, - "SgstAmt": 0, + "Qty": 1000.0, + "SgstAmt": 9000.0, "SlNo": "1", - "TotAmt": 100000, - "TotItemVal": 100000, + "TotAmt": 100000.0, + "TotItemVal": 118000.0 , "Unit": "NOS", - "UnitPrice": 100 + "UnitPrice": 100.0 } ], "PayDtls": { "CrDay": 0, "PaidAmt": 0, - "PaymtDue": 100000 + "PaymtDue": 118000.0 }, "SellerDtls": { "Addr1": "Test Address - 1", @@ -67,15 +67,15 @@ "TaxSch": "GST" }, "ValDtls": { - "AssVal": 100000, + "AssVal": 100000.0, "CesVal": 0, - "CgstVal": 0, + "CgstVal": 9000.0, "Discount": 0, "IgstVal": 0, - "OthChrg": 0, - "RndOffAmt": 0, - "SgstVal": 0, - "TotInvVal": 100000 + "OthChrg": 0.0, + "RndOffAmt": 0.0, + "SgstVal": 9000.0, + "TotInvVal": 118000.0 }, "Version": "1.1" }, @@ -131,18 +131,18 @@ "CesAmt": 0, "CesNonAdvlAmt": 0, "CesRt": 0, - "CgstAmt": 0, + "CgstAmt": 9.0, "Discount": 0, - "GstRt": 0.0, + "GstRt": 18.0, "HsnCd": "999900", "IgstAmt": 0, "IsServc": "Y", "PrdDesc": "Test Service Item", "Qty": 1.0, - "SgstAmt": 0, + "SgstAmt": 9.0, "SlNo": "1", "TotAmt": 100.0, - "TotItemVal": 100.0, + "TotItemVal": 118.0, "Unit": "NOS", "UnitPrice": 100.0 } @@ -150,7 +150,7 @@ "PayDtls": { "CrDay": 0, "PaidAmt": 0, - "PaymtDue": 100.0 + "PaymtDue": 118.0 }, "SellerDtls": { "Addr1": "Test Address - 1", @@ -169,13 +169,13 @@ "ValDtls": { "AssVal": 100.0, "CesVal": 0, - "CgstVal": 0, + "CgstVal": 9.0, "Discount": 0, "IgstVal": 0, "OthChrg": 0.0, "RndOffAmt": 0.0, - "SgstVal": 0, - "TotInvVal": 100.0 + "SgstVal": 9.0, + "TotInvVal": 118.0 }, "Version": "1.1" }, @@ -474,18 +474,18 @@ "CesAmt": 0, "CesNonAdvlAmt": 0, "CesRt": 0, - "CgstAmt": 0, + "CgstAmt": 9.0, "Discount": 0, - "GstRt": 0.0, + "GstRt": 18.0, "HsnCd": "61149090", "IgstAmt": 0, "IsServc": "N", "PrdDesc": "Test Trading Goods 1", "Qty": 0.0, - "SgstAmt": 0, + "SgstAmt": 9.0, "SlNo": "1", "TotAmt": 100.0, - "TotItemVal": 100.0, + "TotItemVal": 118.0, "Unit": "NOS", "UnitPrice": 100.0 } @@ -493,7 +493,7 @@ "PayDtls": { "CrDay": 0, "PaidAmt": 0, - "PaymtDue": 100.0 + "PaymtDue": 118.0 }, "SellerDtls": { "Addr1": "Test Address - 1", @@ -512,13 +512,13 @@ "ValDtls": { "AssVal": 100.0, "CesVal": 0, - "CgstVal": 0, + "CgstVal": 9.0, "Discount": 0, "IgstVal": 0, "OthChrg": 0.0, "RndOffAmt": 0.0, - "SgstVal": 0, - "TotInvVal": 100.0 + "SgstVal": 9.0, + "TotInvVal": 118.0 }, "Version": "1.1" }, diff --git a/india_compliance/gst_india/overrides/test_transaction_data.py b/india_compliance/gst_india/overrides/test_transaction_data.py index bafc3de3c..4511bfa5b 100644 --- a/india_compliance/gst_india/overrides/test_transaction_data.py +++ b/india_compliance/gst_india/overrides/test_transaction_data.py @@ -140,7 +140,10 @@ def test_validate_transaction(self): def test_set_transaction_details(self): """Check transaction data""" - doc = create_sales_invoice(do_not_submit=True) + doc = create_sales_invoice( + do_not_submit=True, + is_in_state=True, + ) gst_transaction_data = GSTTransactionData(doc) gst_transaction_data.set_transaction_details() @@ -155,13 +158,13 @@ def test_set_transaction_details(self): "total_taxable_value": 100.0, "total_non_taxable_value": 0.0, "rounding_adjustment": 0.0, - "grand_total": 100.0, + "grand_total": 118.0, "grand_total_in_foreign_currency": "", "discount_amount": 0, "company_gstin": "24AAQCA8719H1ZC", "name": doc.name, - "total_cgst_amount": 0, - "total_sgst_amount": 0, + "total_cgst_amount": 9.0, + "total_sgst_amount": 9.0, "total_igst_amount": 0, "total_cess_amount": 0, "total_cess_non_advol_amount": 0, @@ -259,7 +262,7 @@ def test_get_all_item_details(self): "cess_non_advol_rate": 0, "tax_rate": 0.0, "total_value": 100.0, - "gst_treatment": "Taxable", + "gst_treatment": "Nil-Rated", } ], ) diff --git a/india_compliance/gst_india/overrides/transaction.py b/india_compliance/gst_india/overrides/transaction.py index a002c53dc..3f37b9746 100644 --- a/india_compliance/gst_india/overrides/transaction.py +++ b/india_compliance/gst_india/overrides/transaction.py @@ -960,7 +960,6 @@ def get(self, docs, doctype, company): if not doc.get("items") or not doc.get("taxes"): continue - self.update_item_count() self.set_item_wise_tax_details() self.set_tax_amount_precisions(doctype) @@ -976,11 +975,10 @@ def update(self, doc): Update Item GST Details for a single document """ self.doc = doc - if not self.doc.get("items") or not self.doc.get("taxes"): + if not self.doc.get("items"): return self.set_gst_accounts(doc.doctype, doc.company) - self.update_item_count() self.set_item_wise_tax_details() self.set_tax_amount_precisions(doc.doctype) self.update_item_tax_details() @@ -994,13 +992,6 @@ def set_gst_accounts(self, doctype, company): gst_account_map = get_gst_accounts_by_type(company, account_type, throw=False) self.gst_account_map = {v: k for k, v in gst_account_map.items()} - def update_item_count(self): - self.item_count = frappe._dict() - for item in self.doc.get("items"): - key = item.item_code or item.item_name - self.item_count.setdefault(key, 0) - self.item_count[key] += 1 - def set_item_wise_tax_details(self): """ Item Tax Details complied @@ -1027,6 +1018,11 @@ def set_item_wise_tax_details(self): for row in GST_TAX_TYPES: item_defaults.update({f"{row}_rate": 0, f"{row}_amount": 0}) + for row in self.doc.get("items"): + key = row.item_code or row.item_name + tax_details.setdefault(key, item_defaults.copy()) + tax_details[key]["count"] += 1 + for row in self.doc.taxes: if ( not row.tax_amount @@ -1044,14 +1040,11 @@ def set_item_wise_tax_details(self): for item_name in set(old.keys()): item_taxes = tax_details.setdefault(item_name, item_defaults.copy()) - count = self.item_count.get(item_name, 0) - if not count: + if not item_taxes.count: # Do not compute if Item is not present in Item table # There can be difference in Item Table and Item Wise Tax Details continue - item_taxes["count"] = count - tax_rate, tax_amount = old[item_name] # cases when charge type == "Actual" @@ -1123,57 +1116,82 @@ def set_tax_amount_precisions(self, doctype): self.precision.update({field: precision}) -def set_gst_treatment_for_item(doc): - is_overseas = is_overseas_doc(doc) - is_sales_transaction = doc.doctype in SALES_DOCTYPES +class ItemGSTTreatment: + def set(self, doc): + self.doc = doc + is_sales_transaction = doc.doctype in SALES_DOCTYPES - default_gst_treatment = "Taxable" - gst_accounts = get_all_gst_accounts(doc.company) + if is_overseas_doc(doc) and is_sales_transaction: + self.set_for_overseas() + return - for row in doc.taxes: - if row.charge_type in ("Actual", "On Item Quantity"): - continue + self.gst_accounts = get_all_gst_accounts(self.doc.company) + has_gst_accounts = any( + row.account_head in self.gst_accounts for row in self.doc.taxes + ) - if row.account_head not in gst_accounts: - continue + if not has_gst_accounts: + self.set_for_no_taxes() + return - if row.rate == 0: - default_gst_treatment = "Nil-Rated" + self.update_gst_treatment_map() + self.set_default_treatment() - break + def set_for_overseas(self): + for item in self.doc.items: + item.gst_treatment = "Zero-Rated" - item_templates = set() - gst_treatments = set() - gst_treatment_map = {} + def set_for_no_taxes(self): + for item in self.doc.items: + if item.gst_treatment not in ("Exempted", "Non-GST"): + item.gst_treatment = "Nil-Rated" + + def update_gst_treatment_map(self): + item_templates = set() + gst_treatments = set() + gst_treatment_map = {} + + for item in self.doc.items: + item_templates.add(item.item_tax_template) + gst_treatments.add(item.gst_treatment) + + if "Zero-Rated" in gst_treatments: + # doc changed from overseas to local sale post validate + _gst_treatments = frappe.get_all( + "Item Tax Template", + filters={"name": ("in", item_templates)}, + fields=["name", "gst_treatment"], + ) + gst_treatment_map = {row.name: row.gst_treatment for row in _gst_treatments} - for item in doc.items: - item_templates.add(item.item_tax_template) - gst_treatments.add(item.gst_treatment) - - if "Zero-Rated" in gst_treatments and not is_overseas: - # doc changed from overseas to local sale post validate - _gst_treatments = frappe.get_all( - "Item Tax Template", - filters={"name": ("in", item_templates)}, - fields=["name", "gst_treatment"], - ) - gst_treatment_map = {row.name: row.gst_treatment for row in _gst_treatments} + self.gst_treatment_map = gst_treatment_map - for item in doc.items: - if not item.gst_treatment or not item.item_tax_template: - item.gst_treatment = default_gst_treatment + def set_default_treatment(self): + default_treatment = self.get_default_treatment() - if not is_sales_transaction: - continue + for item in self.doc.items: + if item.gst_treatment == "Zero-Rated": + item.gst_treatment = self.gst_treatment_map.get(item.item_tax_template) - if is_overseas: - # IGST sec 16(2) - ITC can be claimed for exempt supply - item.gst_treatment = "Zero-Rated" + if not item.gst_treatment or not item.item_tax_template: + item.gst_treatment = default_treatment - elif item.gst_treatment == "Zero-Rated": - item.gst_treatment = ( - gst_treatment_map.get(item.item_tax_template) or default_gst_treatment - ) + def get_default_treatment(self): + default = "Taxable" + + for row in self.doc.taxes: + if row.charge_type in ("Actual", "On Item Quantity"): + continue + + if row.account_head not in self.gst_accounts: + continue + + if row.rate == 0: + default = "Nil-Rated" + + break + + return default def set_reverse_charge_as_per_gst_settings(doc): @@ -1288,7 +1306,7 @@ def update_gst_details(doc, method=None): if doc.doctype in DOCTYPES_WITH_GST_DETAIL: ItemGSTDetails().update(doc) - set_gst_treatment_for_item(doc) + ItemGSTTreatment().set(doc) def after_mapping(target_doc, method=None, source_doc=None): diff --git a/india_compliance/gst_india/utils/test_e_invoice.py b/india_compliance/gst_india/utils/test_e_invoice.py index 3eced1e6f..68504ce0e 100644 --- a/india_compliance/gst_india/utils/test_e_invoice.py +++ b/india_compliance/gst_india/utils/test_e_invoice.py @@ -53,7 +53,10 @@ def setUpClass(cls): def test_request_data_for_different_shipping_dispatch_address(self): test_data = self.e_invoice_test_data.goods_item_with_ewaybill si = create_sales_invoice( - **test_data.get("kwargs"), qty=1000, do_not_submit=True + **test_data.get("kwargs"), + qty=1000, + do_not_submit=True, + is_in_state=True, ) self.assertDictEqual( @@ -182,7 +185,7 @@ def test_progressive_item_tax_amount(self): @change_settings("Selling Settings", {"allow_multiple_items": 1}) def test_validate_transaction(self): """Validation test for more than 1000 items in sales invoice""" - si = create_sales_invoice(do_not_submit=True) + si = create_sales_invoice(do_not_submit=True, is_in_state=True) item_row = si.get("items")[0] for _ in range(0, 1000): @@ -211,7 +214,11 @@ def test_generate_e_invoice_with_goods_item(self): """Generate test e-Invoice for goods item""" test_data = self.e_invoice_test_data.get("goods_item_with_ewaybill") - si = create_sales_invoice(**test_data.get("kwargs"), qty=1000) + si = create_sales_invoice( + **test_data.get("kwargs"), + qty=1000, + is_in_state=True, + ) # Assert if request data given in Json self.assertDictEqual(test_data.get("request_data"), EInvoiceData(si).get_data()) @@ -255,7 +262,10 @@ def test_generate_e_invoice_with_goods_item(self): def test_generate_e_invoice_with_service_item(self): """Generate test e-Invoice for Service Item""" test_data = self.e_invoice_test_data.get("service_item") - si = create_sales_invoice(**test_data.get("kwargs")) + si = create_sales_invoice( + **test_data.get("kwargs"), + is_in_state=True, + ) # Assert if request data given in Json self.assertDictEqual(test_data.get("request_data"), EInvoiceData(si).get_data()) @@ -436,10 +446,15 @@ def test_debit_note_e_invoice_with_goods_item(self): si = create_sales_invoice( customer_address=test_data.get("kwargs").get("customer_address"), shipping_address_name=test_data.get("kwargs").get("shipping_address_name"), + is_in_state=True, ) test_data.get("kwargs").update({"return_against": si.name}) - debit_note = create_sales_invoice(**test_data.get("kwargs"), do_not_submit=True) + debit_note = create_sales_invoice( + **test_data.get("kwargs"), + do_not_submit=True, + is_in_state=True, + ) debit_note.items[0].qty = 0 debit_note.save() @@ -497,7 +512,7 @@ def test_cancel_e_invoice(self): test_data = self.e_invoice_test_data.get("goods_item_with_ewaybill") - si = create_sales_invoice(**test_data.get("kwargs"), qty=1000) + si = create_sales_invoice(**test_data.get("kwargs"), qty=1000, is_in_state=True) self.assertRaisesRegex( frappe.exceptions.ValidationError, @@ -541,7 +556,11 @@ def test_mark_e_invoice_as_cancelled(self): """Test for mark e-Invoice as cancelled""" test_data = self.e_invoice_test_data.get("goods_item_with_ewaybill") - si = create_sales_invoice(**test_data.get("kwargs"), qty=1000) + si = create_sales_invoice( + **test_data.get("kwargs"), + qty=1000, + is_in_state=True, + ) # Mock response for generating irn self._mock_e_invoice_response(data=test_data) @@ -573,6 +592,7 @@ def test_validate_e_invoice_applicability(self): customer="_Test Registered Customer", gst_category="Registered Regular", do_not_submit=True, + is_in_state=True, ) si.billing_address_gstin = "24AAQCA8719H1ZC" @@ -712,7 +732,7 @@ def test_validate_e_invoice_applicability(self): def test_invoice_update_after_submit(self): test_data = self.e_invoice_test_data.get("goods_item_with_ewaybill") - si = create_sales_invoice(**test_data.get("kwargs"), qty=1000) + si = create_sales_invoice(**test_data.get("kwargs"), qty=1000, is_in_state=True) self._mock_e_invoice_response(data=test_data) generate_e_invoice(si.name) @@ -731,7 +751,11 @@ def test_invoice_update_after_submit(self): def test_e_invoice_for_duplicate_irn(self): test_data = self.e_invoice_test_data.get("goods_item_with_ewaybill") - si = create_sales_invoice(**test_data.get("kwargs"), qty=1000) + si = create_sales_invoice( + **test_data.get("kwargs"), + qty=1000, + is_in_state=True, + ) # Mock response for generating irn self._mock_e_invoice_response(data=test_data) diff --git a/india_compliance/gst_india/utils/test_e_waybill.py b/india_compliance/gst_india/utils/test_e_waybill.py index c9507587b..393e3ca0f 100644 --- a/india_compliance/gst_india/utils/test_e_waybill.py +++ b/india_compliance/gst_india/utils/test_e_waybill.py @@ -388,7 +388,7 @@ def test_get_all_item_details(self): "cess_non_advol_rate": 0, "tax_rate": 0.0, "total_value": 100.0, - "gst_treatment": "Taxable", + "gst_treatment": "Nil-Rated", } ], EWaybillData(si).get_all_item_details(), From 99c798e3c2ba111d6cecd0279840ab02230375c7 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Fri, 29 Dec 2023 12:32:59 +0530 Subject: [PATCH 4/5] fix: declare response while getting outstanding docs (cherry picked from commit 30e0f19f0759faec87c5f93662f62bb366274624) --- india_compliance/gst_india/client_scripts/payment_entry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/india_compliance/gst_india/client_scripts/payment_entry.js b/india_compliance/gst_india/client_scripts/payment_entry.js index 834af9573..e3363369d 100644 --- a/india_compliance/gst_india/client_scripts/payment_entry.js +++ b/india_compliance/gst_india/client_scripts/payment_entry.js @@ -45,7 +45,7 @@ function override_get_outstanding_documents(frm) { const new_fn = function () { old_fn(...arguments); frappe.after_ajax(() => { - response = frappe?.last_response?.message || []; + const response = frappe?.last_response?.message || []; const reconciliation_status_dict = response.reduce((acc, d) => { acc[d.voucher_no] = d.reconciliation_status; From 5f36f0bbf1934fe61841569faca40eb163a71a6a Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Fri, 29 Dec 2023 13:14:27 +0530 Subject: [PATCH 5/5] fix: limit exporter values to columns available (cherry picked from commit 7cf37707f3875aa18ea0dc7b633418d535976684) --- india_compliance/gst_india/utils/exporter.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/india_compliance/gst_india/utils/exporter.py b/india_compliance/gst_india/utils/exporter.py index f3695abb4..739346b93 100644 --- a/india_compliance/gst_india/utils/exporter.py +++ b/india_compliance/gst_india/utils/exporter.py @@ -130,6 +130,9 @@ def add_data(self, data, **kwargs): for row in self.parse_data(data): for idx, val in enumerate(row, 1): + if idx > len(self.headers): + break + cell = self.ws.cell(row=self.row_dimension, column=idx) self.apply_format(row=self.row_dimension, column=idx, **kwargs) cell.value = val @@ -311,6 +314,6 @@ def get_range(self, start_row, start_column, end_row, end_column, freeze=False): def get_column_index(self, column_name): """Get column index / position from column name""" - for (idx, field) in enumerate(self.headers, 1): + for idx, field in enumerate(self.headers, 1): if field["fieldname"] == column_name: return idx