From 7866c67dd976e1d54fb56fdce3fd267160b7fc1f Mon Sep 17 00:00:00 2001 From: Ninad1306 Date: Tue, 30 Jul 2024 13:11:08 +0530 Subject: [PATCH 01/11] fix: mapping of sales and purchase template --- .../overrides/subcontracting_transaction.py | 43 +++++++++++++++++++ india_compliance/hooks.py | 1 + 2 files changed, 44 insertions(+) diff --git a/india_compliance/gst_india/overrides/subcontracting_transaction.py b/india_compliance/gst_india/overrides/subcontracting_transaction.py index 0ce07eac72..7f66d54428 100644 --- a/india_compliance/gst_india/overrides/subcontracting_transaction.py +++ b/india_compliance/gst_india/overrides/subcontracting_transaction.py @@ -29,6 +29,49 @@ SUBCONTRACTING_ORDER_RECEIPT_FIELD_MAP = {"total_taxable_value": "total"} +def after_mapping(doc, method, source_doc): + tax_category = frappe.db.get_value( + "Purchase Taxes and Charges Template", + source_doc.taxes_and_charges, + "tax_category", + ) + + tax_categories = frappe.db.get_all( + "Tax Category", fields=["name", "is_inter_state", "is_reverse_charge"] + ) + + is_inter_state_tax_categories = { + tax_category.name + for tax_category in tax_categories + if tax_category.is_inter_state == 1 + } + not_is_reverse_charge_tax_categories = { + tax_category.name + for tax_category in tax_categories + if tax_category.is_reverse_charge == 0 + } + + filters = { + "tax_category": [ + "in", + not_is_reverse_charge_tax_categories - is_inter_state_tax_categories, + ], + } + + if tax_category in is_inter_state_tax_categories: + filters = { + "tax_category": [ + "in", + is_inter_state_tax_categories & not_is_reverse_charge_tax_categories, + ], + } + + doc.taxes_and_charges = frappe.db.get_value( + "Sales Taxes and Charges Template", + filters={"company": source_doc.company, **filters}, + ) + + def get_dashboard_data(data): doctype = ( "Subcontracting Receipt" diff --git a/india_compliance/hooks.py b/india_compliance/hooks.py index 583e1b5edc..b9eb9278da 100644 --- a/india_compliance/hooks.py +++ b/india_compliance/hooks.py @@ -237,6 +237,7 @@ }, "Subcontracting Order": { "validate": "india_compliance.gst_india.overrides.subcontracting_transaction.validate", + "after_mapping": "india_compliance.gst_india.overrides.subcontracting_transaction.after_mapping", }, "Subcontracting Receipt": { "onload": "india_compliance.gst_india.overrides.subcontracting_transaction.onload", From ad57ff88bfeafe6a7c6b30e2fae92abae462ef25 Mon Sep 17 00:00:00 2001 From: Ninad1306 Date: Wed, 31 Jul 2024 13:04:34 +0530 Subject: [PATCH 02/11] fix: fetch sales taxes independant of purchase taxes --- .../overrides/subcontracting_transaction.py | 59 +++++++------------ 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/india_compliance/gst_india/overrides/subcontracting_transaction.py b/india_compliance/gst_india/overrides/subcontracting_transaction.py index 7f66d54428..7a54e81f28 100644 --- a/india_compliance/gst_india/overrides/subcontracting_transaction.py +++ b/india_compliance/gst_india/overrides/subcontracting_transaction.py @@ -8,7 +8,9 @@ from india_compliance.gst_india.overrides.transaction import ( GSTAccounts, get_place_of_supply, + get_tax_template, ignore_gst_validations, + is_inter_state_supply, set_gst_tax_type, validate_gst_category, validate_gst_transporter_id, @@ -30,46 +32,29 @@ def after_mapping(doc, method, source_doc): - tax_category = frappe.db.get_value( - "Purchase Taxes and Charges Template", - source_doc.taxes_and_charges, - "tax_category", - ) + if ignore_gst_validations(doc): + doc.taxes_and_charges = "" + return - tax_categories = frappe.db.get_all( - "Tax Category", fields=["name", "is_inter_state", "is_reverse_charge"] + master_doctype = "Sales Taxes and Charges Template" + default_tax = get_tax_template( + master_doctype, + doc.company, + is_inter_state_supply(doc), + doc.company_gstin, + 0, ) - is_inter_state_tax_categories = { - tax_category.name - for tax_category in tax_categories - if tax_category.is_inter_state == 1 - } - not_is_reverse_charge_tax_categories = { - tax_category.name - for tax_category in tax_categories - if tax_category.is_reverse_charge == 0 - } - - filters = { - "tax_category": [ - "in", - not_is_reverse_charge_tax_categories - is_inter_state_tax_categories, - ], - } - - if tax_category in is_inter_state_tax_categories: - filters = { - "tax_category": [ - "in", - is_inter_state_tax_categories & not_is_reverse_charge_tax_categories, - ], - } - - doc.taxes_and_charges = frappe.db.get_value( - "Sales Taxes and Charges Template", - filters={"company": source_doc.company, **filters}, - ) + tax_master = frappe.get_doc(master_doctype, default_tax) + taxes_and_charges = [] + + for tax in tax_master.get("taxes"): + if tax.description not in ["CGST", "SGST", "IGST"]: + continue + taxes_and_charges.append(tax) + + doc.taxes_and_charges = default_tax + doc.taxes = taxes_and_charges def get_dashboard_data(data): From 29de93871d3d473641f656632c426ec12fa88785 Mon Sep 17 00:00:00 2001 From: Ninad1306 Date: Wed, 31 Jul 2024 17:03:23 +0530 Subject: [PATCH 03/11] fix: changes as per review --- .../overrides/subcontracting_transaction.py | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/india_compliance/gst_india/overrides/subcontracting_transaction.py b/india_compliance/gst_india/overrides/subcontracting_transaction.py index 7a54e81f28..c92dfedf0c 100644 --- a/india_compliance/gst_india/overrides/subcontracting_transaction.py +++ b/india_compliance/gst_india/overrides/subcontracting_transaction.py @@ -8,7 +8,6 @@ from india_compliance.gst_india.overrides.transaction import ( GSTAccounts, get_place_of_supply, - get_tax_template, ignore_gst_validations, is_inter_state_supply, set_gst_tax_type, @@ -19,7 +18,7 @@ validate_mandatory_fields, validate_place_of_supply, ) -from india_compliance.gst_india.utils import is_api_enabled +from india_compliance.gst_india.utils import get_gst_accounts_by_type, is_api_enabled from india_compliance.gst_india.utils.e_waybill import get_e_waybill_info from india_compliance.gst_india.utils.taxes_controller import ( CustomTaxController, @@ -32,29 +31,46 @@ def after_mapping(doc, method, source_doc): + doc.taxes_and_charges = "" + doc.taxes = [] if ignore_gst_validations(doc): - doc.taxes_and_charges = "" return - master_doctype = "Sales Taxes and Charges Template" - default_tax = get_tax_template( - master_doctype, - doc.company, - is_inter_state_supply(doc), - doc.company_gstin, - 0, - ) + set_taxes(doc) + + +def set_taxes(doc): + tax_types = ["cgst", "sgst"] + if is_inter_state_supply(doc): + tax_types.append("igst") - tax_master = frappe.get_doc(master_doctype, default_tax) - taxes_and_charges = [] + for tax_type in tax_types: + account = get_gst_accounts_by_type(doc.company, "Output").get( + tax_type + "_account" + ) - for tax in tax_master.get("taxes"): - if tax.description not in ["CGST", "SGST", "IGST"]: - continue - taxes_and_charges.append(tax) + if not account: + return - doc.taxes_and_charges = default_tax - doc.taxes = taxes_and_charges + rate, description = frappe.db.get_value( + "Sales Taxes and Charges", + { + "parenttype": "Sales Taxes and Charges Template", + "account_head": account, + }, + ("rate", "description"), + ) or (0, account) + + doc.append( + "taxes", + { + "charge_type": "On Net Total", + "account_head": account, + "rate": rate, + "gst_tax_type": tax_type, + "description": description, + }, + ) def get_dashboard_data(data): From ab2dff5bd99fec6a17fb1e5c80dc4d5ae630f064 Mon Sep 17 00:00:00 2001 From: Ninad1306 Date: Fri, 2 Aug 2024 13:14:18 +0530 Subject: [PATCH 04/11] fix: populate item tax template when mapping subcontracting order --- .../overrides/subcontracting_transaction.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/india_compliance/gst_india/overrides/subcontracting_transaction.py b/india_compliance/gst_india/overrides/subcontracting_transaction.py index c92dfedf0c..7e34f8f5ce 100644 --- a/india_compliance/gst_india/overrides/subcontracting_transaction.py +++ b/india_compliance/gst_india/overrides/subcontracting_transaction.py @@ -1,6 +1,8 @@ import frappe from frappe import _, bold from frappe.contacts.doctype.address.address import get_address_display +from erpnext.accounts.party import get_address_tax_category +from erpnext.stock.get_item_details import get_item_tax_template from india_compliance.gst_india.overrides.sales_invoice import ( update_dashboard_with_gst_logs, @@ -38,6 +40,25 @@ def after_mapping(doc, method, source_doc): set_taxes(doc) + tax_category = source_doc.tax_category + + if not tax_category: + tax_category = get_address_tax_category( + frappe.db.get_value("Supplier", source_doc.supplier, "tax_category"), + source_doc.supplier_address, + ) + + if not tax_category: + return + + args = {"company": doc.company, "tax_category": tax_category} + + for item in doc.items: + out = {} + item_doc = frappe.get_cached_doc("Item", item.item_code) + get_item_tax_template(args, item_doc, out) + item.item_tax_template = out.get("item_tax_template") + def set_taxes(doc): tax_types = ["cgst", "sgst"] From c978afc667670401a2a0ad3581b97779915c4bf7 Mon Sep 17 00:00:00 2001 From: Ninad1306 Date: Fri, 2 Aug 2024 13:18:17 +0530 Subject: [PATCH 05/11] fix: minor fix --- .../gst_india/overrides/subcontracting_transaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/india_compliance/gst_india/overrides/subcontracting_transaction.py b/india_compliance/gst_india/overrides/subcontracting_transaction.py index 7e34f8f5ce..397f2f40f5 100644 --- a/india_compliance/gst_india/overrides/subcontracting_transaction.py +++ b/india_compliance/gst_india/overrides/subcontracting_transaction.py @@ -63,7 +63,7 @@ def after_mapping(doc, method, source_doc): def set_taxes(doc): tax_types = ["cgst", "sgst"] if is_inter_state_supply(doc): - tax_types.append("igst") + tax_types = ["igst"] for tax_type in tax_types: account = get_gst_accounts_by_type(doc.company, "Output").get( From c7cec26ca6d577a3702f8c055085af2cf3ab3d7d Mon Sep 17 00:00:00 2001 From: Ninad1306 Date: Fri, 2 Aug 2024 13:57:53 +0530 Subject: [PATCH 06/11] fix: refactor and fixes --- .../overrides/subcontracting_transaction.py | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/india_compliance/gst_india/overrides/subcontracting_transaction.py b/india_compliance/gst_india/overrides/subcontracting_transaction.py index 397f2f40f5..293ab44d42 100644 --- a/india_compliance/gst_india/overrides/subcontracting_transaction.py +++ b/india_compliance/gst_india/overrides/subcontracting_transaction.py @@ -48,9 +48,6 @@ def after_mapping(doc, method, source_doc): source_doc.supplier_address, ) - if not tax_category: - return - args = {"company": doc.company, "tax_category": tax_category} for item in doc.items: @@ -61,27 +58,26 @@ def after_mapping(doc, method, source_doc): def set_taxes(doc): - tax_types = ["cgst", "sgst"] - if is_inter_state_supply(doc): - tax_types = ["igst"] - - for tax_type in tax_types: - account = get_gst_accounts_by_type(doc.company, "Output").get( - tax_type + "_account" - ) + accounts = get_gst_accounts_by_type(doc.company, "Output") + if not accounts: + return - if not account: - return + rate = frappe.db.get_value( + "Sales Taxes and Charges", + { + "parenttype": "Sales Taxes and Charges Template", + "account_head": accounts.get("igst_account"), + }, + "rate", + ) or (0) - rate, description = frappe.db.get_value( - "Sales Taxes and Charges", - { - "parenttype": "Sales Taxes and Charges Template", - "account_head": account, - }, - ("rate", "description"), - ) or (0, account) + tax_types = ("igst",) + if not is_inter_state_supply(doc): + tax_types = ("cgst", "sgst") + rate = rate / 2 + for tax_type in tax_types: + account = accounts.get(tax_type + "_account") doc.append( "taxes", { @@ -89,7 +85,7 @@ def set_taxes(doc): "account_head": account, "rate": rate, "gst_tax_type": tax_type, - "description": description, + "description": account, }, ) From 7a2d35611e7405d819b364dd816d21d539ecd5bd Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Fri, 2 Aug 2024 16:15:26 +0530 Subject: [PATCH 07/11] fix: run `after_mapping` only for PO --- .../gst_india/overrides/subcontracting_transaction.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/india_compliance/gst_india/overrides/subcontracting_transaction.py b/india_compliance/gst_india/overrides/subcontracting_transaction.py index 293ab44d42..62befafcbb 100644 --- a/india_compliance/gst_india/overrides/subcontracting_transaction.py +++ b/india_compliance/gst_india/overrides/subcontracting_transaction.py @@ -33,8 +33,12 @@ def after_mapping(doc, method, source_doc): + if source_doc.doctype != "Purchase Order": + return + doc.taxes_and_charges = "" doc.taxes = [] + if ignore_gst_validations(doc): return From 80ca8bfb76811a3fc846e8c262da8a76739d35b3 Mon Sep 17 00:00:00 2001 From: Ninad1306 Date: Fri, 2 Aug 2024 17:29:05 +0530 Subject: [PATCH 08/11] fix: improved query --- .../overrides/subcontracting_transaction.py | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/india_compliance/gst_india/overrides/subcontracting_transaction.py b/india_compliance/gst_india/overrides/subcontracting_transaction.py index 62befafcbb..7a4fd947eb 100644 --- a/india_compliance/gst_india/overrides/subcontracting_transaction.py +++ b/india_compliance/gst_india/overrides/subcontracting_transaction.py @@ -1,6 +1,9 @@ +from pypika import Order + import frappe from frappe import _, bold from frappe.contacts.doctype.address.address import get_address_display +from frappe.utils import flt from erpnext.accounts.party import get_address_tax_category from erpnext.stock.get_item_details import get_item_tax_template @@ -44,6 +47,9 @@ def after_mapping(doc, method, source_doc): set_taxes(doc) + if not doc.items: + return + tax_category = source_doc.tax_category if not tax_category: @@ -62,23 +68,30 @@ def after_mapping(doc, method, source_doc): def set_taxes(doc): - accounts = get_gst_accounts_by_type(doc.company, "Output") + accounts = get_gst_accounts_by_type(doc.company, "Output", throw=False) if not accounts: return - rate = frappe.db.get_value( - "Sales Taxes and Charges", - { - "parenttype": "Sales Taxes and Charges Template", - "account_head": accounts.get("igst_account"), - }, - "rate", - ) or (0) + sales = frappe.qb.DocType("Sales Taxes and Charges") + sales_template = frappe.qb.DocType("Sales Taxes and Charges Template") + + rate = ( + frappe.qb.from_(sales) + .left_join(sales_template) + .on(sales_template.name == sales.parent) + .select(sales.rate or 0) + .where(sales.parenttype == "Sales Taxes and Charges Template") + .where(sales.account_head == accounts.get("igst_account")) + .where(sales_template.disabled == 0) + .orderby(sales_template.is_default, order=Order.desc) + .limit(1) + .run(pluck=True) + )[0] tax_types = ("igst",) if not is_inter_state_supply(doc): tax_types = ("cgst", "sgst") - rate = rate / 2 + rate = flt(rate / 2) for tax_type in tax_types: account = accounts.get(tax_type + "_account") From 5e51de24805f51443f12907baf7d6f76a7f8d56a Mon Sep 17 00:00:00 2001 From: Ninad1306 Date: Fri, 2 Aug 2024 17:34:48 +0530 Subject: [PATCH 09/11] fix: sales and purchase mapping has to be validated --- .../gst_india/overrides/subcontracting_transaction.py | 11 +++++++++-- india_compliance/hooks.py | 3 ++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/india_compliance/gst_india/overrides/subcontracting_transaction.py b/india_compliance/gst_india/overrides/subcontracting_transaction.py index 7a4fd947eb..3b28ad8d78 100644 --- a/india_compliance/gst_india/overrides/subcontracting_transaction.py +++ b/india_compliance/gst_india/overrides/subcontracting_transaction.py @@ -35,7 +35,7 @@ SUBCONTRACTING_ORDER_RECEIPT_FIELD_MAP = {"total_taxable_value": "total"} -def after_mapping(doc, method, source_doc): +def after_mapping_subcontracting_order(doc, method, source_doc): if source_doc.doctype != "Purchase Order": return @@ -67,6 +67,14 @@ def after_mapping(doc, method, source_doc): item.item_tax_template = out.get("item_tax_template") +def after_mapping_stock_entry(doc, method, source_doc): + if source_doc.doctype == "Subcontracting Order": + return + + doc.taxes_and_charges = "" + doc.taxes = [] + + def set_taxes(doc): accounts = get_gst_accounts_by_type(doc.company, "Output", throw=False) if not accounts: @@ -84,7 +92,6 @@ def set_taxes(doc): .where(sales.account_head == accounts.get("igst_account")) .where(sales_template.disabled == 0) .orderby(sales_template.is_default, order=Order.desc) - .limit(1) .run(pluck=True) )[0] diff --git a/india_compliance/hooks.py b/india_compliance/hooks.py index b9eb9278da..aa54bd893d 100644 --- a/india_compliance/hooks.py +++ b/india_compliance/hooks.py @@ -234,10 +234,11 @@ "Stock Entry": { "onload": "india_compliance.gst_india.overrides.subcontracting_transaction.onload", "validate": "india_compliance.gst_india.overrides.subcontracting_transaction.validate", + "after_mapping": "india_compliance.gst_india.overrides.subcontracting_transaction.after_mapping_stock_entry", }, "Subcontracting Order": { "validate": "india_compliance.gst_india.overrides.subcontracting_transaction.validate", - "after_mapping": "india_compliance.gst_india.overrides.subcontracting_transaction.after_mapping", + "after_mapping": "india_compliance.gst_india.overrides.subcontracting_transaction.after_mapping_subcontracting_order", }, "Subcontracting Receipt": { "onload": "india_compliance.gst_india.overrides.subcontracting_transaction.onload", From 58d3cdf3076ff2f1bfdde0ffbf318d8a7824941d Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Fri, 2 Aug 2024 18:13:27 +0530 Subject: [PATCH 10/11] fix: minor changes --- .../overrides/subcontracting_transaction.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/india_compliance/gst_india/overrides/subcontracting_transaction.py b/india_compliance/gst_india/overrides/subcontracting_transaction.py index 3b28ad8d78..260d03c1ae 100644 --- a/india_compliance/gst_india/overrides/subcontracting_transaction.py +++ b/india_compliance/gst_india/overrides/subcontracting_transaction.py @@ -80,18 +80,20 @@ def set_taxes(doc): if not accounts: return - sales = frappe.qb.DocType("Sales Taxes and Charges") - sales_template = frappe.qb.DocType("Sales Taxes and Charges Template") + sales_tax_template = frappe.qb.DocType("Sales Taxes and Charges Template") + sales_tax_template_row = frappe.qb.DocType("Sales Taxes and Charges") rate = ( - frappe.qb.from_(sales) - .left_join(sales_template) - .on(sales_template.name == sales.parent) - .select(sales.rate or 0) - .where(sales.parenttype == "Sales Taxes and Charges Template") - .where(sales.account_head == accounts.get("igst_account")) - .where(sales_template.disabled == 0) - .orderby(sales_template.is_default, order=Order.desc) + frappe.qb.from_(sales_tax_template_row) + .left_join(sales_tax_template) + .on(sales_tax_template.name == sales_tax_template_row.parent) + .select(sales_tax_template_row.rate or 0) + .where(sales_tax_template_row.parenttype == "Sales Taxes and Charges Template") + .where(sales_tax_template_row.account_head == accounts.get("igst_account")) + .where(sales_tax_template.disabled == 0) + .orderby(sales_tax_template.is_default, order=Order.desc) + .orderby(sales_tax_template.modified, order=Order.desc) + .limit(1) .run(pluck=True) )[0] From 96e2a780bc0e28cb2e19e1494db037fd9f94ca85 Mon Sep 17 00:00:00 2001 From: Ninad1306 Date: Fri, 2 Aug 2024 18:16:18 +0530 Subject: [PATCH 11/11] fix: semantic error --- .../gst_india/overrides/subcontracting_transaction.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/india_compliance/gst_india/overrides/subcontracting_transaction.py b/india_compliance/gst_india/overrides/subcontracting_transaction.py index 260d03c1ae..e350291e1e 100644 --- a/india_compliance/gst_india/overrides/subcontracting_transaction.py +++ b/india_compliance/gst_india/overrides/subcontracting_transaction.py @@ -87,7 +87,7 @@ def set_taxes(doc): frappe.qb.from_(sales_tax_template_row) .left_join(sales_tax_template) .on(sales_tax_template.name == sales_tax_template_row.parent) - .select(sales_tax_template_row.rate or 0) + .select(sales_tax_template_row.rate) .where(sales_tax_template_row.parenttype == "Sales Taxes and Charges Template") .where(sales_tax_template_row.account_head == accounts.get("igst_account")) .where(sales_tax_template.disabled == 0) @@ -95,7 +95,7 @@ def set_taxes(doc): .orderby(sales_tax_template.modified, order=Order.desc) .limit(1) .run(pluck=True) - )[0] + )[0] or 0 tax_types = ("igst",) if not is_inter_state_supply(doc):