From 599d7a686e3b8c4a5972497f3107f716f420c3e8 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 4 Dec 2020 18:07:46 +0530 Subject: [PATCH 1/8] fix: Tax template update on supplier --- erpnext/regional/india/taxes.js | 1 + erpnext/regional/india/utils.py | 31 +++++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/erpnext/regional/india/taxes.js b/erpnext/regional/india/taxes.js index 44891a76a0b..950ba069fb1 100644 --- a/erpnext/regional/india/taxes.js +++ b/erpnext/regional/india/taxes.js @@ -16,6 +16,7 @@ erpnext.setup_auto_gst_taxation = (doctype) => { 'shipping_address': frm.doc.shipping_address || '', 'shipping_address_name': frm.doc.shipping_address_name || '', 'customer_address': frm.doc.customer_address || '', + 'supplier_address': frm.doc.supplier_address, 'customer': frm.doc.customer, 'supplier': frm.doc.supplier, 'supplier_gstin': frm.doc.supplier_gstin, diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 1968076c53d..741c9533b18 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -12,6 +12,7 @@ from erpnext.regional.india import number_state_mapping from six import string_types from erpnext.accounts.general_ledger import make_gl_entries from erpnext.accounts.utils import get_account_currency +from frappe.model.utils import get_fetch_values def validate_gstin_for_india(doc, method): if hasattr(doc, 'gst_state') and doc.gst_state: @@ -155,7 +156,15 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N party_details = json.loads(party_details) party_details = frappe._dict(party_details) + update_party_details(party_details, doctype) + party_details.place_of_supply = get_place_of_supply(party_details, doctype) + + if is_internal_transfer(party_details, doctype): + party_details.taxes_and_charges = '' + party_details.taxes = '' + return party_details + if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"): master_doctype = "Sales Taxes and Charges Template" @@ -196,8 +205,23 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N party_details["taxes_and_charges"] = default_tax party_details.taxes = get_taxes_and_charges(master_doctype, default_tax) - if return_taxes: - return party_details + return party_details + +def update_party_details(party_details, doctype): + for address_field in ['shipping_address', 'company_address', 'supplier_address', 'shipping_address_name', 'customer_address']: + if party_details.get(address_field): + party_details.update(get_fetch_values(doctype, address_field, party_details.get(address_field))) + +def is_internal_transfer(party_details, doctype): + if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"): + destination_gstin = party_details.company_gstin + elif doctype in ("Purchase Invoice", "Purchase Order", "Purchase Receipt"): + destination_gstin = party_details.supplier_gstin + + if party_details.gstin == destination_gstin: + return True + else: + False def get_tax_template_based_on_category(master_doctype, company, party_details): if not party_details.get('tax_category'): @@ -502,6 +526,9 @@ def get_address_details(data, doc, company_address, billing_address): data.actualToStateCode = data.toStateCode shipping_address = billing_address + if doc.gst_category == 'SEZ': + data.toStateCode = 99 + return data def get_item_list(data, doc): From 8cfde675ac0703059fa111d2eeb732d04a322adb Mon Sep 17 00:00:00 2001 From: pateljannat Date: Tue, 17 Nov 2020 09:47:10 +0530 Subject: [PATCH 2/8] fix: place of supply change when address changes --- erpnext/public/js/utils.js | 15 +++++++++++++++ erpnext/regional/india/utils.py | 1 + erpnext/selling/sales_common.js | 1 + 3 files changed, 17 insertions(+) diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 9b1c94e5ba0..139d5593705 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -304,6 +304,21 @@ $.extend(erpnext.utils, { } frappe.ui.form.make_quick_entry(doctype, null, null, new_doc); }); + }, + + set_place_of_supply: function(frm){ + frappe.call({ + method: "erpnext.regional.india.utils.get_place_of_supply", + args: { + "party_details": frm.doc, + "doctype": frm.doc.doctype + }, + callback: function(r){ + if(r.message){ + frm.set_value("place_of_supply", r.message) + } + } + }) } }); diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 741c9533b18..06154ebef9b 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -136,6 +136,7 @@ def test_method(): '''test function''' return 'overridden' +@frappe.whitelist() def get_place_of_supply(party_details, doctype): if not frappe.get_meta('Address').has_field('gst_state'): return diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 15a9a1ab882..802fb5661db 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -117,6 +117,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ customer_address: function() { erpnext.utils.get_address_display(this.frm, "customer_address"); erpnext.utils.set_taxes_from_address(this.frm, "customer_address", "customer_address", "shipping_address_name"); + erpnext.utils.set_place_of_supply(this.frm) }, shipping_address_name: function() { From f226927b6a857254054f513c69c0e6577742f7eb Mon Sep 17 00:00:00 2001 From: pateljannat Date: Tue, 17 Nov 2020 20:34:51 +0530 Subject: [PATCH 3/8] fix: place of supply change on address change --- erpnext/public/js/controllers/buying.js | 1 + erpnext/public/js/utils.js | 28 ++++++++++++------------- erpnext/regional/india/utils.py | 3 +++ 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js index 802cc056c6a..e4369ffe96b 100644 --- a/erpnext/public/js/controllers/buying.js +++ b/erpnext/public/js/controllers/buying.js @@ -133,6 +133,7 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ supplier_address: function() { erpnext.utils.get_address_display(this.frm); erpnext.utils.set_taxes_from_address(this.frm, "supplier_address", "supplier_address", "supplier_address"); + erpnext.utils.set_place_of_supply(this.frm) }, buying_price_list: function() { diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 139d5593705..baac95798e2 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -116,6 +116,19 @@ $.extend(erpnext.utils, { } }, + set_place_of_supply: function(frm){ + frappe.call({ + method: "erpnext.regional.india.utils.get_place_of_supply", + args: { + "party_details": frm.doc, + "doctype": frm.doc.doctype + }, + callback: function(r){ + frm.set_value("place_of_supply", r.message) + } + }) + }, + add_indicator_for_multicompany: function(frm, info) { frm.dashboard.stats_area.removeClass('hidden'); frm.dashboard.stats_area_row.addClass('flex'); @@ -304,21 +317,6 @@ $.extend(erpnext.utils, { } frappe.ui.form.make_quick_entry(doctype, null, null, new_doc); }); - }, - - set_place_of_supply: function(frm){ - frappe.call({ - method: "erpnext.regional.india.utils.get_place_of_supply", - args: { - "party_details": frm.doc, - "doctype": frm.doc.doctype - }, - callback: function(r){ - if(r.message){ - frm.set_value("place_of_supply", r.message) - } - } - }) } }); diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 06154ebef9b..9da835224b0 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -139,6 +139,9 @@ def test_method(): @frappe.whitelist() def get_place_of_supply(party_details, doctype): if not frappe.get_meta('Address').has_field('gst_state'): return + if isinstance(party_details, string_types): + party_details = json.loads(party_details) + party_details = frappe._dict(party_details) if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"): address_name = party_details.shipping_address_name or party_details.customer_address From dafbb80ec53d383a37f2f65cd507e4627e22fbac Mon Sep 17 00:00:00 2001 From: pateljannat Date: Wed, 18 Nov 2020 12:51:13 +0530 Subject: [PATCH 4/8] fix: reversing previous commits and adding condition in regional controller --- erpnext/public/js/controllers/buying.js | 1 - erpnext/public/js/utils.js | 13 ------------- erpnext/regional/india/taxes.js | 4 ++++ erpnext/regional/india/utils.py | 18 +++++++----------- erpnext/selling/sales_common.js | 1 - 5 files changed, 11 insertions(+), 26 deletions(-) diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js index e4369ffe96b..802cc056c6a 100644 --- a/erpnext/public/js/controllers/buying.js +++ b/erpnext/public/js/controllers/buying.js @@ -133,7 +133,6 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ supplier_address: function() { erpnext.utils.get_address_display(this.frm); erpnext.utils.set_taxes_from_address(this.frm, "supplier_address", "supplier_address", "supplier_address"); - erpnext.utils.set_place_of_supply(this.frm) }, buying_price_list: function() { diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index baac95798e2..9b1c94e5ba0 100755 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -116,19 +116,6 @@ $.extend(erpnext.utils, { } }, - set_place_of_supply: function(frm){ - frappe.call({ - method: "erpnext.regional.india.utils.get_place_of_supply", - args: { - "party_details": frm.doc, - "doctype": frm.doc.doctype - }, - callback: function(r){ - frm.set_value("place_of_supply", r.message) - } - }) - }, - add_indicator_for_multicompany: function(frm, info) { frm.dashboard.stats_area.removeClass('hidden'); frm.dashboard.stats_area_row.addClass('flex'); diff --git a/erpnext/regional/india/taxes.js b/erpnext/regional/india/taxes.js index 950ba069fb1..33de01adad8 100644 --- a/erpnext/regional/india/taxes.js +++ b/erpnext/regional/india/taxes.js @@ -35,6 +35,10 @@ erpnext.setup_auto_gst_taxation = (doctype) => { callback: function(r) { if(r.message) { frm.set_value('taxes_and_charges', r.message.taxes_and_charges); + frm.set_value('place_of_supply', r.message.place_of_supply); + } else if (frm.doc.is_internal_supplier || frm.doc.is_internal_customer) { + frm.set_value('taxes_and_charges', ''); + frm.set_value('taxes', []); } } }); diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 9da835224b0..d2a6c2dbcfa 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -136,12 +136,8 @@ def test_method(): '''test function''' return 'overridden' -@frappe.whitelist() def get_place_of_supply(party_details, doctype): if not frappe.get_meta('Address').has_field('gst_state'): return - if isinstance(party_details, string_types): - party_details = json.loads(party_details) - party_details = frappe._dict(party_details) if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"): address_name = party_details.shipping_address_name or party_details.customer_address @@ -175,11 +171,11 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N get_tax_template_for_sez(party_details, master_doctype, company, 'Customer') get_tax_template_based_on_category(master_doctype, company, party_details) - if party_details.get('taxes_and_charges') and return_taxes: + if party_details.get('taxes_and_charges'): return party_details if not party_details.company_gstin: - return + return party_details elif doctype in ("Purchase Invoice", "Purchase Order", "Purchase Receipt"): master_doctype = "Purchase Taxes and Charges Template" @@ -187,15 +183,15 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N get_tax_template_for_sez(party_details, master_doctype, company, 'Supplier') get_tax_template_based_on_category(master_doctype, company, party_details) - if party_details.get('taxes_and_charges') and return_taxes: + if party_details.get('taxes_and_charges'): return party_details if not party_details.supplier_gstin: - return + return party_details - if not party_details.place_of_supply: return + if not party_details.place_of_supply: return party_details - if not party_details.company_gstin: return + if not party_details.company_gstin: return party_details if ((doctype in ("Sales Invoice", "Delivery Note", "Sales Order") and party_details.company_gstin and party_details.company_gstin[:2] != party_details.place_of_supply[:2]) or (doctype in ("Purchase Invoice", @@ -205,7 +201,7 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N default_tax = get_tax_template(master_doctype, company, 0, party_details.company_gstin[:2]) if not default_tax: - return + return party_details party_details["taxes_and_charges"] = default_tax party_details.taxes = get_taxes_and_charges(master_doctype, default_tax) diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 802fb5661db..15a9a1ab882 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -117,7 +117,6 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ customer_address: function() { erpnext.utils.get_address_display(this.frm, "customer_address"); erpnext.utils.set_taxes_from_address(this.frm, "customer_address", "customer_address", "shipping_address_name"); - erpnext.utils.set_place_of_supply(this.frm) }, shipping_address_name: function() { From 56d5b6804698aef496bdcbc5c0b75d67ec5d13b8 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Wed, 18 Nov 2020 15:57:16 +0530 Subject: [PATCH 5/8] fix: linter issue for translation syntax --- erpnext/regional/india/utils.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index d2a6c2dbcfa..13a07a054cb 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -87,7 +87,7 @@ def validate_gstin_check_digit(gstin, label='GSTIN'): factor = 2 if factor == 1 else 1 if gstin[-1] != code_point_chars[((mod - (total % mod)) % mod)]: frappe.throw(_("""Invalid {0}! The check digit validation has failed. - Please ensure you've typed the {0} correctly.""".format(label))) + Please ensure you've typed the {0} correctly.""").format(label)) def get_itemised_tax_breakup_header(item_doctype, tax_accounts): if frappe.get_meta(item_doctype).has_field('gst_hsn_code'): @@ -163,7 +163,7 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N if is_internal_transfer(party_details, doctype): party_details.taxes_and_charges = '' party_details.taxes = '' - return party_details + return if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"): master_doctype = "Sales Taxes and Charges Template" @@ -171,11 +171,11 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N get_tax_template_for_sez(party_details, master_doctype, company, 'Customer') get_tax_template_based_on_category(master_doctype, company, party_details) - if party_details.get('taxes_and_charges'): + if party_details.get('taxes_and_charges') and return_taxes: return party_details if not party_details.company_gstin: - return party_details + return elif doctype in ("Purchase Invoice", "Purchase Order", "Purchase Receipt"): master_doctype = "Purchase Taxes and Charges Template" @@ -183,15 +183,15 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N get_tax_template_for_sez(party_details, master_doctype, company, 'Supplier') get_tax_template_based_on_category(master_doctype, company, party_details) - if party_details.get('taxes_and_charges'): + if party_details.get('taxes_and_charges') and return_taxes: return party_details if not party_details.supplier_gstin: - return party_details + return - if not party_details.place_of_supply: return party_details + if not party_details.place_of_supply: return - if not party_details.company_gstin: return party_details + if not party_details.company_gstin: return if ((doctype in ("Sales Invoice", "Delivery Note", "Sales Order") and party_details.company_gstin and party_details.company_gstin[:2] != party_details.place_of_supply[:2]) or (doctype in ("Purchase Invoice", @@ -201,11 +201,12 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N default_tax = get_tax_template(master_doctype, company, 0, party_details.company_gstin[:2]) if not default_tax: - return party_details + return party_details["taxes_and_charges"] = default_tax party_details.taxes = get_taxes_and_charges(master_doctype, default_tax) - return party_details + if return_taxes: + return party_details def update_party_details(party_details, doctype): for address_field in ['shipping_address', 'company_address', 'supplier_address', 'shipping_address_name', 'customer_address']: @@ -245,7 +246,6 @@ def get_tax_template(master_doctype, company, is_inter_state, state_code): (not default_tax and not tax_category.gst_state): default_tax = frappe.db.get_value(master_doctype, {'disabled': 0, 'tax_category': tax_category.name}, 'name') - return default_tax def get_tax_template_for_sez(party_details, master_doctype, company, party_type): From 45d8204e1e1183196e2324ef712a8748c0314330 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Thu, 19 Nov 2020 11:37:08 +0530 Subject: [PATCH 6/8] fix: company filter added again --- erpnext/regional/india/utils.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 13a07a054cb..8c764b7e8aa 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -163,7 +163,7 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N if is_internal_transfer(party_details, doctype): party_details.taxes_and_charges = '' party_details.taxes = '' - return + return party_details if doctype in ("Sales Invoice", "Delivery Note", "Sales Order"): master_doctype = "Sales Taxes and Charges Template" @@ -171,11 +171,11 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N get_tax_template_for_sez(party_details, master_doctype, company, 'Customer') get_tax_template_based_on_category(master_doctype, company, party_details) - if party_details.get('taxes_and_charges') and return_taxes: + if party_details.get('taxes_and_charges'): return party_details if not party_details.company_gstin: - return + return party_details elif doctype in ("Purchase Invoice", "Purchase Order", "Purchase Receipt"): master_doctype = "Purchase Taxes and Charges Template" @@ -183,15 +183,15 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N get_tax_template_for_sez(party_details, master_doctype, company, 'Supplier') get_tax_template_based_on_category(master_doctype, company, party_details) - if party_details.get('taxes_and_charges') and return_taxes: + if party_details.get('taxes_and_charges'): return party_details if not party_details.supplier_gstin: - return + return party_details - if not party_details.place_of_supply: return + if not party_details.place_of_supply: return party_details - if not party_details.company_gstin: return + if not party_details.company_gstin: return party_details if ((doctype in ("Sales Invoice", "Delivery Note", "Sales Order") and party_details.company_gstin and party_details.company_gstin[:2] != party_details.place_of_supply[:2]) or (doctype in ("Purchase Invoice", @@ -201,12 +201,11 @@ def get_regional_address_details(party_details, doctype, company, return_taxes=N default_tax = get_tax_template(master_doctype, company, 0, party_details.company_gstin[:2]) if not default_tax: - return + return party_details party_details["taxes_and_charges"] = default_tax party_details.taxes = get_taxes_and_charges(master_doctype, default_tax) - if return_taxes: - return party_details + return party_details def update_party_details(party_details, doctype): for address_field in ['shipping_address', 'company_address', 'supplier_address', 'shipping_address_name', 'customer_address']: @@ -245,7 +244,7 @@ def get_tax_template(master_doctype, company, is_inter_state, state_code): if tax_category.gst_state == number_state_mapping[state_code] or \ (not default_tax and not tax_category.gst_state): default_tax = frappe.db.get_value(master_doctype, - {'disabled': 0, 'tax_category': tax_category.name}, 'name') + {'company': company, 'disabled': 0, 'tax_category': tax_category.name}, 'name') return default_tax def get_tax_template_for_sez(party_details, master_doctype, company, party_type): From af60e854004b87db3f800e54cda4b6e10de26662 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Thu, 19 Nov 2020 20:11:45 +0530 Subject: [PATCH 7/8] fix: removing return_taxes condition --- erpnext/regional/india/taxes.js | 3 +-- erpnext/regional/india/utils.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/erpnext/regional/india/taxes.js b/erpnext/regional/india/taxes.js index 33de01adad8..b3da21c2bb3 100644 --- a/erpnext/regional/india/taxes.js +++ b/erpnext/regional/india/taxes.js @@ -29,8 +29,7 @@ erpnext.setup_auto_gst_taxation = (doctype) => { args: { party_details: JSON.stringify(party_details), doctype: frm.doc.doctype, - company: frm.doc.company, - return_taxes: 1 + company: frm.doc.company }, callback: function(r) { if(r.message) { diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 8c764b7e8aa..1bd1f6c0c77 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -150,8 +150,7 @@ def get_place_of_supply(party_details, doctype): return cstr(address.gst_state_number) + "-" + cstr(address.gst_state) @frappe.whitelist() -def get_regional_address_details(party_details, doctype, company, return_taxes=None): - +def get_regional_address_details(party_details, doctype, company): if isinstance(party_details, string_types): party_details = json.loads(party_details) party_details = frappe._dict(party_details) From 2a92d1b94a26ce77024e7d35ff491ee11c54c3df Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 16 Dec 2020 13:00:55 +0530 Subject: [PATCH 8/8] fix: Tax template update on customer address change --- erpnext/regional/india/taxes.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/regional/india/taxes.js b/erpnext/regional/india/taxes.js index b3da21c2bb3..455879294a8 100644 --- a/erpnext/regional/india/taxes.js +++ b/erpnext/regional/india/taxes.js @@ -9,6 +9,9 @@ erpnext.setup_auto_gst_taxation = (doctype) => { tax_category: function(frm) { frm.trigger('get_tax_template'); }, + customer_address: function(frm) { + frm.trigger('get_tax_template'); + }, get_tax_template: function(frm) { if (!frm.doc.company) return;