From 4448e1a36020955d0942c19a7ed08800d17a0202 Mon Sep 17 00:00:00 2001 From: Ninad1306 Date: Mon, 9 Dec 2024 14:09:23 +0530 Subject: [PATCH 01/10] fix: use bulk insert to ignore validations --- .../v15/migrate_boe_taxes_to_ic_taxes.py | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/india_compliance/patches/v15/migrate_boe_taxes_to_ic_taxes.py b/india_compliance/patches/v15/migrate_boe_taxes_to_ic_taxes.py index ad0cbe2ea5..36f36f9161 100644 --- a/india_compliance/patches/v15/migrate_boe_taxes_to_ic_taxes.py +++ b/india_compliance/patches/v15/migrate_boe_taxes_to_ic_taxes.py @@ -1,4 +1,6 @@ import frappe +from frappe.model.document import bulk_insert +from frappe.model.naming import _generate_random_string def execute(): @@ -8,16 +10,33 @@ def execute(): boe_taxes = frappe.qb.DocType("Bill of Entry Taxes") boe_taxes_docs = frappe.qb.from_(boe_taxes).select("*").run(as_dict=True) + ic_taxes_names = set( + frappe.get_all("India Compliance Taxes and Charges", pluck="name") + ) + ic_taxes = [] + for doc in boe_taxes_docs: ic_taxes_doc = frappe.get_doc( { **doc, "doctype": "India Compliance Taxes and Charges", - "name": None, + "name": set_name(doc.name, ic_taxes_names), "base_total": doc.total, } ) - ic_taxes_doc.insert(ignore_if_duplicate=True) + + ic_taxes.append(ic_taxes_doc) + + bulk_insert("India Compliance Taxes and Charges", ic_taxes) # Drop the old table frappe.db.delete("Bill of Entry Taxes") + + +def set_name(name, names): + new_name = name + while new_name in names: + new_name = _generate_random_string(10) + + names.add(new_name) + return new_name From 34aa57dc1aaa6de67ed29b5960e9318f65e12105 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 12 Dec 2024 17:59:28 +0530 Subject: [PATCH 02/10] fix: change regional override as per erpnext changes (backport #2835) --- india_compliance/gst_india/overrides/payment_entry.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/india_compliance/gst_india/overrides/payment_entry.py b/india_compliance/gst_india/overrides/payment_entry.py index b3dc948061..1dd7c35b77 100644 --- a/india_compliance/gst_india/overrides/payment_entry.py +++ b/india_compliance/gst_india/overrides/payment_entry.py @@ -332,6 +332,7 @@ def get_advance_payment_entries_for_regional( party_account, order_doctype, order_list=None, + default_advance_account=None, include_unallocated=True, against_all_orders=False, limit=None, @@ -347,6 +348,7 @@ def get_advance_payment_entries_for_regional( party_account=party_account, order_doctype=order_doctype, order_list=order_list, + default_advance_account=default_advance_account, include_unallocated=include_unallocated, against_all_orders=against_all_orders, limit=limit, From 46af03aac74fe8c29dee16eccd7fd143ff06f1e3 Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Mon, 9 Dec 2024 16:08:14 +0530 Subject: [PATCH 03/10] fix: taxable value for invoice without qty and value (cherry picked from commit fb7a785cdd65e2aa1d2cc8ac72da45dde804b9fc) --- .../gst_india/overrides/transaction.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/india_compliance/gst_india/overrides/transaction.py b/india_compliance/gst_india/overrides/transaction.py index 700c47ed51..f2a5e2c9f9 100644 --- a/india_compliance/gst_india/overrides/transaction.py +++ b/india_compliance/gst_india/overrides/transaction.py @@ -72,6 +72,7 @@ def update_taxable_values(doc): total_charges = 0 apportioned_charges = 0 tax_witholding_amount = 0 + has_no_qty_value = False if doc.taxes: if any( @@ -103,8 +104,10 @@ def update_taxable_values(doc): # base net total may be zero if invoice has zero rated items + shipping total_value = doc.base_net_total if doc.base_net_total else doc.total_qty + # credit note without item qty and value but with charges if not total_value: - return + total_value = len(doc.items) + has_no_qty_value = True for item in doc.items: item.taxable_value = item.base_net_amount @@ -112,7 +115,12 @@ def update_taxable_values(doc): if not total_charges: continue - proportionate_value = item.base_net_amount if doc.base_net_total else item.qty + if has_no_qty_value: + proportionate_value = 1 + elif doc.base_net_total: + proportionate_value = item.base_net_amount + else: + proportionate_value = item.qty applicable_charges = flt( proportionate_value * (total_charges / total_value), @@ -498,7 +506,7 @@ def validate_for_charge_type(self): ) if row.charge_type == "On Previous Row Total": - previous_row_references.add(row.row_id) + previous_row_references.add(flt(row.row_id)) # validating charge type "On Item Quantity" and non_cess_advol_account self.validate_charge_type_for_cess_non_advol_accounts(row) From a077eb3c7042b6b4dcd52a3e40606947f8937b91 Mon Sep 17 00:00:00 2001 From: Sanket322 Date: Wed, 11 Dec 2024 22:47:02 +0530 Subject: [PATCH 04/10] test: added the test case (cherry picked from commit fbb6d2eb522f766fa5e70fb85106a0a5aa27aa1a) --- .../gst_india/overrides/test_transaction.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/india_compliance/gst_india/overrides/test_transaction.py b/india_compliance/gst_india/overrides/test_transaction.py index 773ec9e475..eaeaa04876 100644 --- a/india_compliance/gst_india/overrides/test_transaction.py +++ b/india_compliance/gst_india/overrides/test_transaction.py @@ -419,6 +419,41 @@ def test_taxable_value_with_charges_after_tax(self): doc.insert() self.assertDocumentEqual({"taxable_value": 100}, doc.items[0]) + def test_credit_not_without_quantity(self): + if self.doctype != "Sales Invoice": + return + + doc = create_transaction( + **self.transaction_details, is_return=True, do_not_save=True + ) + append_item(doc) + + for item in doc.items: + item.qty = 0 + item.rate = 0 + item.price_list_rate = 0 + + # Adding charges + doc.append( + "taxes", + { + "charge_type": "Actual", + "account_head": "Freight and Forwarding Charges - _TIRC", + "description": "Freight", + "tax_amount": 20, + "cost_center": "Main - _TIRC", + }, + ) + + # Adding taxes + _append_taxes( + doc, ("CGST", "SGST"), charge_type="On Previous Row Total", row_id=1 + ) + doc.insert() + + for item in doc.items: + self.assertDocumentEqual({"taxable_value": 10}, item) + def test_validate_place_of_supply(self): doc = create_transaction(**self.transaction_details, do_not_save=True) doc.place_of_supply = "96-Others" From c5ae826d8e4c2d8fd36581b85830b676f8f3627c Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 12 Dec 2024 17:44:45 +0530 Subject: [PATCH 05/10] test: additionally test gst details for credit note with zero value (cherry picked from commit 159ed7573494dc0c89798b4eb16e68ce02b1b221) --- india_compliance/gst_india/overrides/test_transaction.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/india_compliance/gst_india/overrides/test_transaction.py b/india_compliance/gst_india/overrides/test_transaction.py index eaeaa04876..db4a3fe222 100644 --- a/india_compliance/gst_india/overrides/test_transaction.py +++ b/india_compliance/gst_india/overrides/test_transaction.py @@ -419,7 +419,7 @@ def test_taxable_value_with_charges_after_tax(self): doc.insert() self.assertDocumentEqual({"taxable_value": 100}, doc.items[0]) - def test_credit_not_without_quantity(self): + def test_credit_note_without_quantity(self): if self.doctype != "Sales Invoice": return @@ -451,8 +451,11 @@ def test_credit_not_without_quantity(self): ) doc.insert() + # Ensure correct taxable_value and gst details for item in doc.items: - self.assertDocumentEqual({"taxable_value": 10}, item) + self.assertDocumentEqual( + {"taxable_value": 10, "cgst_amount": 0.9, "sgst_amount": 0.9}, item + ) def test_validate_place_of_supply(self): doc = create_transaction(**self.transaction_details, do_not_save=True) From 5f1850cab20bc986595ca76ff862042c8405ef6e Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Wed, 11 Dec 2024 10:33:09 +0530 Subject: [PATCH 06/10] fix: correct categorisation of is_export and fetching taxes accordingly --- india_compliance/gst_india/overrides/transaction.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/india_compliance/gst_india/overrides/transaction.py b/india_compliance/gst_india/overrides/transaction.py index 700c47ed51..970941fbae 100644 --- a/india_compliance/gst_india/overrides/transaction.py +++ b/india_compliance/gst_india/overrides/transaction.py @@ -1031,7 +1031,12 @@ def get_gst_details(party_details, doctype, company, *, update_place_of_supply=F == party_details.get(party_gstin_field) ) # Internal transfer ) - or (is_sales_transaction and is_export_without_payment_of_gst(party_details)) + or ( + is_sales_transaction + and is_export_without_payment_of_gst( + frappe._dict({**party_details, "doctype": doctype}) + ) + ) or ( not is_sales_transaction and ( From caf8e75390f4d203c41c4929743567c0c07f523b Mon Sep 17 00:00:00 2001 From: Smit Vora Date: Thu, 12 Dec 2024 18:18:06 +0530 Subject: [PATCH 07/10] fix(patch): ignore validate when creating item tax template (#2831) (cherry picked from commit 49137584050e360c748067cca4d8cffa4cb2d22c) --- .../patches/post_install/improve_item_tax_template.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/india_compliance/patches/post_install/improve_item_tax_template.py b/india_compliance/patches/post_install/improve_item_tax_template.py index 436c94a0cb..7df878f3b1 100644 --- a/india_compliance/patches/post_install/improve_item_tax_template.py +++ b/india_compliance/patches/post_install/improve_item_tax_template.py @@ -125,6 +125,7 @@ def create_or_update_item_tax_templates(companies): elif doc.gst_rate == 0: doc.gst_treatment = "Nil-Rated" + doc.flags.ignore_validate = True # eg: account_type validation doc.save() # create new templates for nil rated, exempted, non gst @@ -261,6 +262,7 @@ def remove_old_item_variant_settings(): if field.field_name in ("is_nil_exempt", "is_non_gst"): item_variant.fields.remove(field) + item_variant.flags.ignore_validate = True item_variant.save() From 0d868c70878bc2bea00071d52ddd32ce48f0bb1c Mon Sep 17 00:00:00 2001 From: Sanket Shah <113279972+Sanket322@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:19:01 +0530 Subject: [PATCH 08/10] fix: add documentation links in help (#2810) * fix: add documentation links in help * fix: added e-waybill links * fix: formatting changes * fix: added links for company and gst settings * fix: remove e-waybill links and add blog links --------- Co-authored-by: Sanket322 (cherry picked from commit 28d45b2cb5c418eba62e2111d0d5bd7a29ff7d64) --- india_compliance/public/js/help_links.js | 151 ++++++++++++++++++ .../public/js/india_compliance.bundle.js | 1 + 2 files changed, 152 insertions(+) create mode 100644 india_compliance/public/js/help_links.js diff --git a/india_compliance/public/js/help_links.js b/india_compliance/public/js/help_links.js new file mode 100644 index 0000000000..940e6f9ca4 --- /dev/null +++ b/india_compliance/public/js/help_links.js @@ -0,0 +1,151 @@ +frappe.provide("frappe.help.help_links"); + +const docsUrl = "https://docs.indiacompliance.app/docs/"; +const blogUrl = "https://docs.indiacompliance.app/blog/"; + +//India Compliance Account +frappe.help.help_links["india-compliance-account"] = [ + { + label: "India Compliance Account", + url: docsUrl + "getting-started/india_compliance_account", + }, +]; + +//GST Settings +frappe.help.help_links["Form/GST Settings"] = [ + { + label: "Setting Up GST accounts", + url: docsUrl + "configuration/gst_setup#gst-accounts" + }, + { + label: "Setting Up API", + url: docsUrl + "ewaybill-and-einvoice/gst_settings" + }, +]; + +//Company +frappe.help.help_links["Form/Company"] = [ + { + label: "Print Settings", + url: docsUrl + "configuration/gst_setup#print-format", + } +]; + + +//Doctypes +//Sales Invoice +if (!frappe.help.help_links["Form/Sales Invoice"]) { + frappe.help.help_links["Form/Sales Invoice"] = []; +} + +frappe.help.help_links["Form/Sales Invoice"].push( + { + label: "e-Waybill", + url: docsUrl + "ewaybill-and-einvoice/generating_e_waybill", + }, + { + label: "e-Invoice", + url: docsUrl + "ewaybill-and-einvoice/generating_e_invoice", + }, +); + +//Stock Entry +frappe.help.help_links["Form/Stock Entry"].push({ + label: "Subcontracting Workflow", + url: blogUrl + "posts/post5", +}) + +//Subcontracting Receipt +frappe.help.help_links["Form/Subcontracting Receipt"] = [ + { + label: "Subcontracting Workflow", + url: blogUrl + "posts/post5", + }, + { + label: "GST Job Work Stock Movement report", + url: docsUrl + "gst-reports/miscellaneous_reports#gst-job-work-stock-movement-report", + }, +] + +//Journal Entry +frappe.help.help_links["Form/Journal Entry"] = [ + { + label: "Reversal of Input Tax Credit", + url: docsUrl + "configuration/other_transaction#reversal-of-input-tax-credit", + } +] + +// GST Reports +frappe.help.help_links["Form/GSTR-1 Beta"] = [ + { + label: "GSTR-1 Beta", + url: docsUrl + "gst-reports/gstr1", + }, +]; + +frappe.help.help_links["Form/GSTR 3B Report"] = [ + { + label: "GSTR 3B Report", + url: docsUrl + "gst-reports/gstr3b", + }, +]; + +frappe.help.help_links["List/GSTR 3B Report"] = [ + { + label: "GSTR 3B Report", + url: docsUrl + "gst-reports/gstr3b", + }, +]; + + +//Query Reports +frappe.help.help_links["query-report/GST Job Work Stock Movement"] = [ + { + label: "GST Job Work Stock Movement", + url: docsUrl + "gst-reports/miscellaneous_reports#gst-job-work-stock-movement-report", + }, +]; + +frappe.help.help_links["query-report/GST Balance"] = [ + { + label: "GST Balance", + url: docsUrl + "gst-reports/miscellaneous_reports#gst-balance-report", + }, +]; + +frappe.help.help_links["query-report/GST Sales Register Beta"] = [ + { + label: "GST Sales Register Beta", + url: docsUrl + "gst-reports/miscellaneous_reports#gst-sales-register-beta-report", + }, +]; + +frappe.help.help_links["query-report/GST Purchase Register"] = [ + { + label: "GST Purchase Register", + url: docsUrl + "gst-reports/miscellaneous_reports#gst-purchase-register-beta-report", + }, +]; + +//Purchase Reconciliation +frappe.help.help_links["Form/Purchase Reconciliation Tool"] = [ + { + label: "Reconciling Purchase", + url: docsUrl + "purchase-reconciliation/reconciling_purchase", + }, +]; + +//Miscellaneous +frappe.help.help_links["query-report/Audit Trail"] = [ + { + label: "Audit Trail", + url: docsUrl + "miscellaneous/audit_trail", + }, +]; + +frappe.help.help_links["Form/Lower Deduction Certificate"] = [ + { + label: "Lower Deduction Certificate", + url: docsUrl + "miscellaneous/lower_deduction_certificate", + }, +]; \ No newline at end of file diff --git a/india_compliance/public/js/india_compliance.bundle.js b/india_compliance/public/js/india_compliance.bundle.js index d43ba882a2..580889b4d8 100644 --- a/india_compliance/public/js/india_compliance.bundle.js +++ b/india_compliance/public/js/india_compliance.bundle.js @@ -8,3 +8,4 @@ import "./new_gst_category_notification"; import "./quick_info_popover"; import "./custom_number_card"; import "./taxes_controller"; +import "./help_links"; From 52dba383bb2581968324e8e32cdd0c3e0ffc08af Mon Sep 17 00:00:00 2001 From: Sanket Shah <113279972+Sanket322@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:53:53 +0530 Subject: [PATCH 09/10] fix: Error Handling for download of GSTR2A/2B (#2832) Co-authored-by: Sanket322 (cherry picked from commit 90788529e4869c78ec9902866550afbb8557f5b1) --- .../purchase_reconciliation_tool.js | 13 +++++++++++++ .../purchase_reconciliation_tool.py | 17 +++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/india_compliance/gst_india/doctype/purchase_reconciliation_tool/purchase_reconciliation_tool.js b/india_compliance/gst_india/doctype/purchase_reconciliation_tool/purchase_reconciliation_tool.js index bfe0b7461f..3a119d73b5 100644 --- a/india_compliance/gst_india/doctype/purchase_reconciliation_tool/purchase_reconciliation_tool.js +++ b/india_compliance/gst_india/doctype/purchase_reconciliation_tool/purchase_reconciliation_tool.js @@ -70,6 +70,8 @@ frappe.ui.form.on("Purchase Reconciliation Tool", { await frappe.require("purchase_reconciliation_tool.bundle.js"); frm.trigger("company"); frm.purchase_reconciliation_tool = new PurchaseReconciliationTool(frm); + + frm.events.handle_download_failure(frm); }, onload(frm) { @@ -229,6 +231,17 @@ frappe.ui.form.on("Purchase Reconciliation Tool", { } }); }, + + handle_download_failure(frm) { + frappe.realtime.on("gstr_2a_2b_download_failed", message => { + frm.dashboard.hide(); + frappe.msgprint({ + title: __("2A/2B Download Failed"), + message: message.error, + indicator: "red" + }); + }) + }, }); class PurchaseReconciliationTool { diff --git a/india_compliance/gst_india/doctype/purchase_reconciliation_tool/purchase_reconciliation_tool.py b/india_compliance/gst_india/doctype/purchase_reconciliation_tool/purchase_reconciliation_tool.py index 3c9cf1ad9a..ebb090c2e1 100644 --- a/india_compliance/gst_india/doctype/purchase_reconciliation_tool/purchase_reconciliation_tool.py +++ b/india_compliance/gst_india/doctype/purchase_reconciliation_tool/purchase_reconciliation_tool.py @@ -460,11 +460,20 @@ def download_gstr( if not periods: return - if return_type == ReturnType.GSTR2A: - return download_gstr_2a(company_gstin, periods, gst_categories) + try: + if return_type == ReturnType.GSTR2A: + return download_gstr_2a(company_gstin, periods, gst_categories) - if return_type == ReturnType.GSTR2B: - return download_gstr_2b(company_gstin, periods) + if return_type == ReturnType.GSTR2B: + return download_gstr_2b(company_gstin, periods) + + except Exception as e: + frappe.publish_realtime( + "gstr_2a_2b_download_failed", + {"error": str(e)}, + user=frappe.session.user, + doctype="Purchase Reconciliation Tool", + ) def get_periods_to_download(company_gstin, return_type, periods): From 9e0febca5a45c5282f8b8fc31bef5fb74f9a6c1e Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Thu, 12 Dec 2024 21:43:10 +0530 Subject: [PATCH 10/10] chore: compatibiltiy for erpnext --- india_compliance/patches/check_version_compatibility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/india_compliance/patches/check_version_compatibility.py b/india_compliance/patches/check_version_compatibility.py index 2067317b31..fb12de4091 100644 --- a/india_compliance/patches/check_version_compatibility.py +++ b/india_compliance/patches/check_version_compatibility.py @@ -18,7 +18,7 @@ { "app_name": "ERPNext", "current_version": version.parse(erpnext.__version__), - "required_versions": {"version-14": "14.70.7", "version-15": "15.27.7"}, + "required_versions": {"version-14": "14.70.7", "version-15": "15.45.5"}, }, ]