From 244da766483122ea927656d8567ead66f23301fe Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 20 Apr 2021 23:04:39 +0530 Subject: [PATCH 01/24] feat(India): Separate Input and Output GST tax accounts --- .../setup_wizard/data/country_wise_tax.json | 49 ++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/erpnext/setup/setup_wizard/data/country_wise_tax.json b/erpnext/setup/setup_wizard/data/country_wise_tax.json index daaa626a81a1..ca0bb48e7893 100644 --- a/erpnext/setup/setup_wizard/data/country_wise_tax.json +++ b/erpnext/setup/setup_wizard/data/country_wise_tax.json @@ -1229,35 +1229,70 @@ ] } ], - "*": [ + "sales_tax_templates": [ { - "title": "In State GST", + "title": "Output GST In-state", "taxes": [ { "account_head": { - "account_name": "SGST", + "account_name": "Output Tax SGST", "tax_rate": 9.00 } }, { "account_head": { - "account_name": "CGST", + "account_name": "Output Tax CGST", "tax_rate": 9.00 } } ] }, { - "title": "Out of State GST", + "title": "Output GST Out-state", "taxes": [ { "account_head": { - "account_name": "IGST", + "account_name": "Output Tax IGST", "tax_rate": 18.00 } } ] + } + ], + "purchase_tax_templates": [ + { + "title": "Input GST In-state", + "taxes": [ + { + "account_head": { + "account_name": "Input Tax SGST", + "tax_rate": 9.00, + "root_type": "Asset" + } + }, + { + "account_head": { + "account_name": "Input Tax CGST", + "tax_rate": 9.00, + "root_type": "Asset" + } + } + ] }, + { + "title": "Input GST Out-state", + "taxes": [ + { + "account_head": { + "account_name": "Input Tax IGST", + "tax_rate": 18.00, + "root_type": "Asset" + } + } + ] + } + ], + "*": [ { "title": "VAT 5%", "taxes": [ @@ -1349,7 +1384,7 @@ "Italy VAT 4%":{ "account_name": "IVA 4%", "tax_rate": 4.00 - } + } }, "Ivory Coast": { From 530713ba6324ce55dd2168079a72fac56c5ec320 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Tue, 20 Apr 2021 23:23:07 +0530 Subject: [PATCH 02/24] fix: Item Tax templates for GST --- .../setup_wizard/data/country_wise_tax.json | 148 +++++++++++++++++- 1 file changed, 142 insertions(+), 6 deletions(-) diff --git a/erpnext/setup/setup_wizard/data/country_wise_tax.json b/erpnext/setup/setup_wizard/data/country_wise_tax.json index ca0bb48e7893..7822096259d3 100644 --- a/erpnext/setup/setup_wizard/data/country_wise_tax.json +++ b/erpnext/setup/setup_wizard/data/country_wise_tax.json @@ -1168,29 +1168,165 @@ "*": { "item_tax_templates": [ { - "title": "In State GST", + "title": "GST 9%", "taxes": [ { "tax_type": { - "account_name": "SGST", + "account_name": "Output Tax SGST", + "tax_rate": 9.00 + } + }, + { + "tax_type": { + "account_name": "Output Tax CGST", "tax_rate": 9.00 } }, { "tax_type": { - "account_name": "CGST", + "account_name": "Output Tax IGST", + "tax_rate": 18.00 + } + }, + { + "tax_type": { + "account_name": "Input Tax SGST", "tax_rate": 9.00 } + }, + { + "tax_type": { + "account_name": "Input Tax CGST", + "tax_rate": 9.00 + } + }, + { + "tax_type": { + "account_name": "Input Tax IGST", + "tax_rate": 18.00 + } } ] }, { - "title": "Out of State GST", + "title": "GST 5%", "taxes": [ { "tax_type": { - "account_name": "IGST", - "tax_rate": 18.00 + "account_name": "Output Tax SGST", + "tax_rate": 2.5 + } + }, + { + "tax_type": { + "account_name": "Output Tax CGST", + "tax_rate": 2.5 + } + }, + { + "tax_type": { + "account_name": "Output Tax IGST", + "tax_rate": 5.0 + } + }, + { + "tax_type": { + "account_name": "Input Tax SGST", + "tax_rate": 2.5 + } + }, + { + "tax_type": { + "account_name": "Input Tax CGST", + "tax_rate": 2.5 + } + }, + { + "tax_type": { + "account_name": "Input Tax IGST", + "tax_rate": 5.0 + } + } + ] + }, + { + "title": "GST 12%", + "taxes": [ + { + "tax_type": { + "account_name": "Output Tax SGST", + "tax_rate": 6.0 + } + }, + { + "tax_type": { + "account_name": "Output Tax CGST", + "tax_rate": 6.0 + } + }, + { + "tax_type": { + "account_name": "Output Tax IGST", + "tax_rate": 12.0 + } + }, + { + "tax_type": { + "account_name": "Input Tax SGST", + "tax_rate": 6.0 + } + }, + { + "tax_type": { + "account_name": "Input Tax CGST", + "tax_rate": 6.0 + } + }, + { + "tax_type": { + "account_name": "Input Tax IGST", + "tax_rate": 12.0 + } + } + ] + }, + { + "title": "GST 28%", + "taxes": [ + { + "tax_type": { + "account_name": "Output Tax SGST", + "tax_rate": 14.0 + } + }, + { + "tax_type": { + "account_name": "Output Tax CGST", + "tax_rate": 14.0 + } + }, + { + "tax_type": { + "account_name": "Output Tax IGST", + "tax_rate": 28.0 + } + }, + { + "tax_type": { + "account_name": "Input Tax SGST", + "tax_rate": 14.0 + } + }, + { + "tax_type": { + "account_name": "Input Tax CGST", + "tax_rate": 14.0 + } + }, + { + "tax_type": { + "account_name": "Input Tax IGST", + "tax_rate": 28.0 } } ] From e5f91694b79a6bbce3494f8310daadcf9f5a957c Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 21 Apr 2021 11:49:02 +0530 Subject: [PATCH 03/24] fix: Add tax categories on company setup --- .../setup_wizard/data/country_wise_tax.json | 22 +++++++++++++++++ .../setup_wizard/operations/taxes_setup.py | 24 +++++++++++-------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/erpnext/setup/setup_wizard/data/country_wise_tax.json b/erpnext/setup/setup_wizard/data/country_wise_tax.json index 7822096259d3..14215f030ff5 100644 --- a/erpnext/setup/setup_wizard/data/country_wise_tax.json +++ b/erpnext/setup/setup_wizard/data/country_wise_tax.json @@ -1166,6 +1166,28 @@ "India": { "chart_of_accounts": { "*": { + "tax_categories": [ + { + "title": "In-Sate", + "is_inter_state": 0, + "gst_state": "" + }, + { + "title": "Out-Sate", + "is_inter_state": 1, + "gst_state": "" + }, + { + "title": "Reverse Charge", + "is_inter_state": 0, + "gst_state": "" + }, + { + "title": "Registered Composition", + "is_inter_state": 0, + "gst_state": "" + } + ], "item_tax_templates": [ { "title": "GST 9%", diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py index f4fe18e116c9..974ef5eaa791 100644 --- a/erpnext/setup/setup_wizard/operations/taxes_setup.py +++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py @@ -77,16 +77,11 @@ def simple_to_detailed(templates): def from_detailed_data(company_name, data): """Create Taxes and Charges Templates from detailed data.""" coa_name = frappe.db.get_value('Company', company_name, 'chart_of_accounts') - coa_data = data.get('chart_of_accounts', {}) - tax_templates = coa_data.get(coa_name) or coa_data.get('*', {}) - tax_categories = data.get('tax_categories') - sales_tax_templates = tax_templates.get('sales_tax_templates') or tax_templates.get('*', {}) - purchase_tax_templates = tax_templates.get('purchase_tax_templates') or tax_templates.get('*', {}) - item_tax_templates = tax_templates.get('item_tax_templates') or tax_templates.get('*', {}) - - if tax_categories: - for tax_category in tax_categories: - make_tax_catgory(tax_category) + tax_templates = data.get(coa_name) or data.get('*') + sales_tax_templates = tax_templates.get('sales_tax_templates') or tax_templates.get('*') + purchase_tax_templates = tax_templates.get('purchase_tax_templates') or tax_templates.get('*') + item_tax_templates = tax_templates.get('item_tax_templates') or tax_templates.get('*') + tax_categories = tax_templates.get('tax_categories') if sales_tax_templates: for template in sales_tax_templates: @@ -100,6 +95,10 @@ def from_detailed_data(company_name, data): for template in item_tax_templates: make_item_tax_template(company_name, template) + if tax_categories: + for tax_category in tax_categories: + make_tax_category(tax_category) + def make_taxes_and_charges_template(company_name, doctype, template): template['company'] = company_name @@ -158,6 +157,11 @@ def make_item_tax_template(company_name, template): return frappe.get_doc(template).insert(ignore_permissions=True) +def make_tax_category(tax_category): + """ Make tax category based on title if not already created """ + doctype = 'Tax Category' + if not frappe.db.exists(doctype, tax_category) + frappe.get_doc(tax_category).insert(ignore_permissions=True) def get_or_create_account(company_name, account): """ From 4df1e07d850745eb31dda38088d979f81c068935 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 21 Apr 2021 20:41:57 +0530 Subject: [PATCH 04/24] fix: Update country-wise-tax JSON and tax setup --- .../setup_wizard/data/country_wise_tax.json | 34 ++++++++++++------- .../setup_wizard/operations/taxes_setup.py | 22 ++++++------ 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/erpnext/setup/setup_wizard/data/country_wise_tax.json b/erpnext/setup/setup_wizard/data/country_wise_tax.json index 14215f030ff5..7a61538b0e21 100644 --- a/erpnext/setup/setup_wizard/data/country_wise_tax.json +++ b/erpnext/setup/setup_wizard/data/country_wise_tax.json @@ -1168,12 +1168,12 @@ "*": { "tax_categories": [ { - "title": "In-Sate", + "title": "In-State", "is_inter_state": 0, "gst_state": "" }, { - "title": "Out-Sate", + "title": "Out-State", "is_inter_state": 1, "gst_state": "" }, @@ -1394,16 +1394,19 @@ { "account_head": { "account_name": "Output Tax SGST", - "tax_rate": 9.00 + "tax_rate": 9.00, + "account_type": "Tax" } }, { "account_head": { "account_name": "Output Tax CGST", - "tax_rate": 9.00 + "tax_rate": 9.00, + "account_type": "Tax" } } - ] + ], + "tax_category": "In-State" }, { "title": "Output GST Out-state", @@ -1411,10 +1414,12 @@ { "account_head": { "account_name": "Output Tax IGST", - "tax_rate": 18.00 + "tax_rate": 18.00, + "account_type": "Tax" } } - ] + ], + "tax_category": "Out-State" } ], "purchase_tax_templates": [ @@ -1425,17 +1430,20 @@ "account_head": { "account_name": "Input Tax SGST", "tax_rate": 9.00, - "root_type": "Asset" + "root_type": "Asset", + "account_type": "Tax" } }, { "account_head": { "account_name": "Input Tax CGST", "tax_rate": 9.00, - "root_type": "Asset" + "root_type": "Asset", + "account_type": "Tax" } } - ] + ], + "tax_category": "In-State" }, { "title": "Input GST Out-state", @@ -1444,10 +1452,12 @@ "account_head": { "account_name": "Input Tax IGST", "tax_rate": 18.00, - "root_type": "Asset" + "root_type": "Asset", + "account_type": "Tax" } } - ] + ], + "tax_category": "Out-State" } ], "*": [ diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py index 974ef5eaa791..59f1e58078ba 100644 --- a/erpnext/setup/setup_wizard/operations/taxes_setup.py +++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py @@ -83,6 +83,10 @@ def from_detailed_data(company_name, data): item_tax_templates = tax_templates.get('item_tax_templates') or tax_templates.get('*') tax_categories = tax_templates.get('tax_categories') + if tax_categories: + for tax_category in tax_categories: + make_tax_category(tax_category) + if sales_tax_templates: for template in sales_tax_templates: make_taxes_and_charges_template(company_name, 'Sales Taxes and Charges Template', template) @@ -95,10 +99,6 @@ def from_detailed_data(company_name, data): for template in item_tax_templates: make_item_tax_template(company_name, template) - if tax_categories: - for tax_category in tax_categories: - make_tax_category(tax_category) - def make_taxes_and_charges_template(company_name, doctype, template): template['company'] = company_name @@ -160,8 +160,9 @@ def make_item_tax_template(company_name, template): def make_tax_category(tax_category): """ Make tax category based on title if not already created """ doctype = 'Tax Category' - if not frappe.db.exists(doctype, tax_category) - frappe.get_doc(tax_category).insert(ignore_permissions=True) + if not frappe.db.exists(doctype, tax_category): + tax_category['doctype'] = doctype + frappe.get_doc(tax_category).insert(ignore_permissions=True) def get_or_create_account(company_name, account): """ @@ -173,12 +174,13 @@ def get_or_create_account(company_name, account): existing_accounts = frappe.get_list('Account', filters={ - 'company': company_name, - 'root_type': root_type + 'account_name': account.get('account_name'), + 'account_number': account.get('account_number', '') }, or_filters={ - 'account_name': account.get('account_name'), - 'account_number': account.get('account_number') + 'company': company_name, + 'root_type': root_type, + 'is_group': 0 } ) From f6236578ff441ad31288b92e267548f231f92d01 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 21 Apr 2021 20:42:20 +0530 Subject: [PATCH 05/24] fix: Issues on new company setup --- erpnext/regional/india/setup.py | 4 ++-- .../regional/report/e_invoice_summary/e_invoice_summary.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 3e0b9b733b6f..31e936d410be 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -731,12 +731,12 @@ def set_tax_withholding_category(company): docs = get_tds_details(accounts, fiscal_year) for d in docs: - try: + if not frappe.db.exists("Tax Withholding Category", d.get("name")): doc = frappe.get_doc(d) doc.flags.ignore_permissions = True doc.flags.ignore_mandatory = True doc.insert() - except frappe.DuplicateEntryError: + else: doc = frappe.get_doc("Tax Withholding Category", d.get("name")) if accounts: diff --git a/erpnext/regional/report/e_invoice_summary/e_invoice_summary.json b/erpnext/regional/report/e_invoice_summary/e_invoice_summary.json index 4deb073a53df..d0000ad50dfc 100644 --- a/erpnext/regional/report/e_invoice_summary/e_invoice_summary.json +++ b/erpnext/regional/report/e_invoice_summary/e_invoice_summary.json @@ -11,7 +11,7 @@ "is_standard": "Yes", "json": "{}", "letter_head": "Logo", - "modified": "2021-03-12 12:36:48.689413", + "modified": "2021-03-13 12:36:48.689413", "modified_by": "Administrator", "module": "Regional", "name": "E-Invoice Summary", From e12984d80f49e5eaaf1f988cf9b4b9c2e1abd420 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Fri, 30 Apr 2021 16:35:52 +0530 Subject: [PATCH 06/24] fix: Ignore validations for Tax Setup --- erpnext/regional/india/setup.py | 10 ++++-- erpnext/setup/doctype/company/company.py | 2 +- .../setup_wizard/operations/taxes_setup.py | 34 ++++++++++++++----- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 31e936d410be..c554630aaefb 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -25,6 +25,7 @@ def setup_company_independent_fixtures(patch=False): frappe.enqueue('erpnext.regional.india.setup.add_hsn_sac_codes', now=frappe.flags.in_test) create_gratuity_rule() add_print_formats() + update_accounts_settings_for_taxes() def add_hsn_sac_codes(): if frappe.flags.in_test and frappe.flags.created_hsn_codes: @@ -733,6 +734,7 @@ def set_tax_withholding_category(company): for d in docs: if not frappe.db.exists("Tax Withholding Category", d.get("name")): doc = frappe.get_doc(d) + doc.flags.ignore_validate = True doc.flags.ignore_permissions = True doc.flags.ignore_mandatory = True doc.insert() @@ -749,11 +751,12 @@ def set_tax_withholding_category(company): doc.append("rates", d.get('rates')[0]) doc.flags.ignore_permissions = True + doc.flags.ignore_validdate = True doc.flags.ignore_mandatory = True + doc.flags.ignore_links = True doc.save() def set_tds_account(docs, company): - abbr = frappe.get_value("Company", company, "abbr") parent_account = frappe.db.get_value("Account", filters = {"account_name": "Duties and Taxes", "company": company}) if parent_account: docs.extend([ @@ -912,7 +915,6 @@ def get_tds_details(accounts, fiscal_year): ] def create_gratuity_rule(): - # Standard Indain Gratuity Rule if not frappe.db.exists("Gratuity Rule", "Indian Standard Gratuity Rule"): rule = frappe.new_doc("Gratuity Rule") @@ -930,3 +932,7 @@ def create_gratuity_rule(): rule.flags.ignore_mandatory = True rule.save() + +def update_accounts_settings_for_taxes(): + if frappe.db.count('Company') == 1: + frappe.db.set_value('Accounts Settings', None, "add_taxes_from_item_tax_template", 0) \ No newline at end of file diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index 8fd905d7a798..8fc0cbefa1d0 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -110,7 +110,7 @@ def on_update(self): self.create_default_warehouses() if frappe.flags.country_change: - install_country_fixtures(self.name) + install_country_fixtures(self.name, self.country) self.create_default_tax_template() if not frappe.db.get_value("Department", {"company": self.name}): diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py index 59f1e58078ba..6da3f386f8b5 100644 --- a/erpnext/setup/setup_wizard/operations/taxes_setup.py +++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py @@ -129,8 +129,11 @@ def make_taxes_and_charges_template(company_name, doctype, template): if fieldname not in tax_row: tax_row[fieldname] = default_value - return frappe.get_doc(template).insert(ignore_permissions=True) - + doc = frappe.get_doc(template) + doc.flags.ignore_links = True + doc.flags.ignore_validate = True + doc.insert(ignore_permissions=True) + return doc def make_item_tax_template(company_name, template): """Create an Item Tax Template. @@ -155,14 +158,21 @@ def make_item_tax_template(company_name, template): if 'tax_rate' not in tax_row: tax_row['tax_rate'] = account_data.get('tax_rate') - return frappe.get_doc(template).insert(ignore_permissions=True) + doc = frappe.get_doc(template) + doc.flags.ignore_links = True + doc.flags.ignore_validate = True + doc.insert(ignore_permissions=True) + return doc def make_tax_category(tax_category): """ Make tax category based on title if not already created """ doctype = 'Tax Category' if not frappe.db.exists(doctype, tax_category): tax_category['doctype'] = doctype - frappe.get_doc(tax_category).insert(ignore_permissions=True) + doc = frappe.get_doc(tax_category) + doc.flags.ignore_links = True + doc.flags.ignore_validate = True + doc.insert(ignore_permissions=True) def get_or_create_account(company_name, account): """ @@ -175,7 +185,8 @@ def get_or_create_account(company_name, account): existing_accounts = frappe.get_list('Account', filters={ 'account_name': account.get('account_name'), - 'account_number': account.get('account_number', '') + 'account_number': account.get('account_number', ''), + 'company': company_name }, or_filters={ 'company': company_name, @@ -197,8 +208,11 @@ def get_or_create_account(company_name, account): account['root_type'] = root_type account['is_group'] = 0 - return frappe.get_doc(account).insert(ignore_permissions=True, ignore_mandatory=True) - + doc = frappe.get_doc(account) + doc.flags.ignore_links = True + doc.flags.ignore_validate = True + doc.insert(ignore_permissions=True, ignore_mandatory=True) + return doc def get_or_create_tax_group(company_name, root_type): # Look for a group account of type 'Tax' @@ -243,7 +257,11 @@ def get_or_create_tax_group(company_name, root_type): 'account_type': 'Tax', 'account_name': account_name, 'parent_account': root_account.name - }).insert(ignore_permissions=True) + }) + + tax_group_account.flags.ignore_links = True + tax_group_account.flags.ignore_validate = True + tax_group_account.insert(ignore_permissions=True) tax_group_name = tax_group_account.name From fb56022f17df555100b3df350f158f458cc461b3 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 2 May 2021 12:22:16 +0530 Subject: [PATCH 07/24] fix: Remove redundant get_doc --- erpnext/regional/india/setup.py | 2 +- erpnext/setup/doctype/company/company.py | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index c554630aaefb..95fc6801cce0 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -681,7 +681,7 @@ def make_custom_fields(update=True): def make_fixtures(company=None): docs = [] - company = company.name if company else frappe.db.get_value("Global Defaults", None, "default_company") + company = company or frappe.db.get_value("Global Defaults", None, "default_company") set_salary_components(docs) set_tds_account(docs, company) diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index 8fc0cbefa1d0..d112e8eef9bc 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -440,13 +440,12 @@ def get_name_with_abbr(name, company): return " - ".join(parts) -def install_country_fixtures(company): - company_doc = frappe.get_doc("Company", company) - path = frappe.get_app_path('erpnext', 'regional', frappe.scrub(company_doc.country)) +def install_country_fixtures(company, country): + path = frappe.get_app_path('erpnext', 'regional', frappe.scrub(country)) if os.path.exists(path.encode("utf-8")): try: - module_name = "erpnext.regional.{0}.setup.setup".format(frappe.scrub(company_doc.country)) - frappe.get_attr(module_name)(company_doc, False) + module_name = "erpnext.regional.{0}.setup.setup".format(frappe.scrub(country)) + frappe.get_attr(module_name)(company, False) except Exception as e: frappe.log_error() frappe.throw(_("Failed to setup defaults for country {0}. Please contact support@erpnext.com").format(frappe.bold(company_doc.country))) From 5e77da324c7e85d05a527b6216842c0a93dd7f22 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 2 May 2021 12:23:11 +0530 Subject: [PATCH 08/24] fix: Gracefully handle duplicate bank account name to make setup faster --- erpnext/accounts/doctype/account/account.py | 6 +++++ .../chart_of_accounts/chart_of_accounts.py | 18 ------------- erpnext/public/js/setup_wizard.js | 26 ------------------- 3 files changed, 6 insertions(+), 44 deletions(-) diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index 1be2fbf5c817..645f49bcdc46 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -28,6 +28,12 @@ def autoname(self): from erpnext.accounts.utils import get_autoname_with_number self.name = get_autoname_with_number(self.account_number, self.account_name, None, self.company) + def before_insert(self): + # Update Bank account name if conflicting with any other account + if frappe.flags.in_install and self.account_type == 'Bank': + if frappe.db.get_value('Account', {'account_name': self.account_name}): + self.account_name = self.account_name + '-1' + def validate(self): from erpnext.accounts.utils import validate_field_number if frappe.local.flags.allow_unverified_charts: diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py index 927adc7086cd..9b6842d896cc 100644 --- a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py +++ b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py @@ -188,24 +188,6 @@ def build_account_tree(tree, parent, all_accounts): # call recursively to build a subtree for current account build_account_tree(tree[child.account_name], child, all_accounts) -@frappe.whitelist() -def validate_bank_account(coa, bank_account): - accounts = [] - chart = get_chart(coa) - - if chart: - def _get_account_names(account_master): - for account_name, child in iteritems(account_master): - if account_name not in ["account_number", "account_type", - "root_type", "is_group", "tax_rate"]: - accounts.append(account_name) - - _get_account_names(child) - - _get_account_names(chart) - - return (bank_account in accounts) - @frappe.whitelist() def build_tree_from_json(chart_template, chart_data=None): ''' get chart template from its folder and parse the json to be rendered as tree ''' diff --git a/erpnext/public/js/setup_wizard.js b/erpnext/public/js/setup_wizard.js index ef03b01698c3..a3045724fee9 100644 --- a/erpnext/public/js/setup_wizard.js +++ b/erpnext/public/js/setup_wizard.js @@ -139,36 +139,10 @@ erpnext.setup.slides_settings = [ }, validate: function () { - let me = this; - let exist; - if (!this.validate_fy_dates()) { return false; } - // Validate bank name - if(me.values.bank_account){ - frappe.call({ - async: false, - method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.validate_bank_account", - args: { - "coa": me.values.chart_of_accounts, - "bank_account": me.values.bank_account - }, - callback: function (r) { - if(r.message){ - exist = r.message; - me.get_field("bank_account").set_value(""); - let message = __('Account {0} already exists. Please enter a different name for your bank account.', - [me.values.bank_account] - ); - frappe.msgprint(message); - } - } - }); - return !exist; // Return False if exist = true - } - return true; }, From a62868cdbc66a2a24d87f17637014c6802c0e00f Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 2 May 2021 18:22:29 +0530 Subject: [PATCH 09/24] fix: Add validation for GST Settings --- .../regional/doctype/gst_settings/gst_settings.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/erpnext/regional/doctype/gst_settings/gst_settings.py b/erpnext/regional/doctype/gst_settings/gst_settings.py index bc956e9fa886..af3d92e59a7a 100644 --- a/erpnext/regional/doctype/gst_settings/gst_settings.py +++ b/erpnext/regional/doctype/gst_settings/gst_settings.py @@ -19,6 +19,21 @@ def onload(self): from tabAddress where country = "India" and ifnull(gstin, '')!='' ''') self.set_onload('data', data) + def validate(self): + # Validate duplicate accounts + self.validate_duplicate_accounts() + + def validate_duplicate_accounts(self): + account_list = [] + for account in self.get('gst_accounts'): + for fieldname in ['cgst_account', 'sgst_account', 'igst_account', 'cess_account']: + if account.get(fieldname) in account_list: + frappe.throw(_("Account {0} appears multiple times").format( + frappe.bold(account.get(fieldname)))) + + if account.get(fieldname): + account_list.append(account.get(fieldname)) + @frappe.whitelist() def send_reminder(): frappe.has_permission('GST Settings', throw=True) From af58e3883fda7538d1fc952dca91ea48b4261ce2 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sun, 2 May 2021 22:29:48 +0530 Subject: [PATCH 10/24] fix: Add GST accounts to GST Settings --- erpnext/regional/india/setup.py | 52 ++++++++++++++++++++++++ erpnext/setup/doctype/company/company.py | 2 +- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 95fc6801cce0..8ccbc54c5ea5 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -15,6 +15,7 @@ def setup(company=None, patch=True): setup_company_independent_fixtures(patch=patch) if not patch: make_fixtures(company) + setup_gst_settings(company) # TODO: for all countries def setup_company_independent_fixtures(patch=False): @@ -699,6 +700,57 @@ def make_fixtures(company=None): # create records for Tax Withholding Category set_tax_withholding_category(company) +def setup_gst_settings(company): + # Will only add default GST accounts if present + input_account_names = ['Input Tax CGST', 'Input Tax SGST', 'Input Tax IGST'] + output_account_names = ['Output Tax CGST', 'Output Tax SGST', 'Output Tax IGST'] + gst_settings = frappe.get_single('GST Settings') + existing_account_list = [] + + for account in gst_settings.get('gst_accounts'): + for key in ['cgst_account', 'sgst_account', 'igst_account']: + existing_account_list.append(account.get(key)) + + gst_accounts = frappe._dict(frappe.get_all("Account", + {'company': company, 'name': ('like', "%GST%")}, ['account_name', 'name'], as_list=1)) + + all_input_account_exists = 0 + all_output_account_exists = 0 + + for account in input_account_names: + if not gst_accounts.get(account): + all_input_account_exists = 1 + + # Check if already added in GST Settings + if gst_accounts.get(account) in existing_account_list: + all_input_account_exists = 1 + + for account in output_account_names: + if not gst_accounts.get(account): + all_output_account_exists = 1 + + # Check if already added in GST Settings + if gst_accounts.get(account) in existing_account_list: + all_output_account_exists = 1 + + if not all_input_account_exists: + gst_settings.append('gst_accounts', { + 'company': company, + 'cgst_account': gst_accounts.get(input_account_names[0]), + 'sgst_account': gst_accounts.get(input_account_names[1]), + 'igst_account': gst_accounts.get(input_account_names[2]) + }) + + if not all_output_account_exists: + gst_settings.append('gst_accounts', { + 'company': company, + 'cgst_account': gst_accounts.get(output_account_names[0]), + 'sgst_account': gst_accounts.get(output_account_names[1]), + 'igst_account': gst_accounts.get(output_account_names[2]) + }) + + gst_settings.save() + def set_salary_components(docs): docs.extend([ {'doctype': 'Salary Component', 'salary_component': 'Professional Tax', diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index d112e8eef9bc..36a7d20a8ffb 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -448,7 +448,7 @@ def install_country_fixtures(company, country): frappe.get_attr(module_name)(company, False) except Exception as e: frappe.log_error() - frappe.throw(_("Failed to setup defaults for country {0}. Please contact support@erpnext.com").format(frappe.bold(company_doc.country))) + frappe.throw(_("Failed to setup defaults for country {0}. Please contact support@erpnext.com").format(frappe.bold(country))) def update_company_current_month_sales(company): From cb3e0e713f8995a4d9f171a87953d004c78e9494 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sat, 29 May 2021 23:54:51 +0530 Subject: [PATCH 11/24] fix: Add accounts and templates for reverse charge --- erpnext/accounts/doctype/account/account.py | 6 - erpnext/accounts/utils.py | 2 +- erpnext/regional/india/setup.py | 50 ++++---- erpnext/setup/doctype/company/company.py | 2 +- .../setup_wizard/data/country_wise_tax.json | 115 +++++++++++++++++- .../setup_wizard/operations/company_setup.py | 23 ---- 6 files changed, 139 insertions(+), 59 deletions(-) diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index 645f49bcdc46..1be2fbf5c817 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -28,12 +28,6 @@ def autoname(self): from erpnext.accounts.utils import get_autoname_with_number self.name = get_autoname_with_number(self.account_number, self.account_name, None, self.company) - def before_insert(self): - # Update Bank account name if conflicting with any other account - if frappe.flags.in_install and self.account_type == 'Bank': - if frappe.db.get_value('Account', {'account_name': self.account_name}): - self.account_name = self.account_name + '-1' - def validate(self): from erpnext.accounts.utils import validate_field_number if frappe.local.flags.allow_unverified_charts: diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index a8e4b153f812..1cdbd8d38a61 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -788,7 +788,7 @@ def get_children(doctype, parent, company, is_root=False): return acc def create_payment_gateway_account(gateway, payment_channel="Email"): - from erpnext.setup.setup_wizard.operations.company_setup import create_bank_account + from erpnext.setup.setup_wizard.operations.install_fixtures import create_bank_account company = frappe.db.get_value("Global Defaults", None, "default_company") if not company: diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 8ccbc54c5ea5..39705f6e4425 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -704,6 +704,7 @@ def setup_gst_settings(company): # Will only add default GST accounts if present input_account_names = ['Input Tax CGST', 'Input Tax SGST', 'Input Tax IGST'] output_account_names = ['Output Tax CGST', 'Output Tax SGST', 'Output Tax IGST'] + rcm_accounts = ['Input Tax CGST RCM', 'Input Tax SGST RCM', 'Input Tax IGST RCM'] gst_settings = frappe.get_single('GST Settings') existing_account_list = [] @@ -712,45 +713,40 @@ def setup_gst_settings(company): existing_account_list.append(account.get(key)) gst_accounts = frappe._dict(frappe.get_all("Account", - {'company': company, 'name': ('like', "%GST%")}, ['account_name', 'name'], as_list=1)) + {'company': company, 'account_name': ('in', input_account_names + + output_account_names + rcm_accounts)}, ['account_name', 'name'], as_list=1)) - all_input_account_exists = 0 - all_output_account_exists = 0 + add_accounts_in_gst_settings(company, input_account_names, gst_accounts, + existing_account_list, gst_settings) + add_accounts_in_gst_settings(company, output_account_names, gst_accounts, + existing_account_list, gst_settings) + add_accounts_in_gst_settings(company, rcm_accounts, gst_accounts, + existing_account_list, gst_settings, is_reverse_charge=1) - for account in input_account_names: - if not gst_accounts.get(account): - all_input_account_exists = 1 + gst_settings.save() - # Check if already added in GST Settings - if gst_accounts.get(account) in existing_account_list: - all_input_account_exists = 1 +def add_accounts_in_gst_settings(company, account_names, gst_accounts, + existing_account_list, gst_settings, is_reverse_charge=0): + accounts_not_added = 1 - for account in output_account_names: + for account in account_names: + # Default Account Added does not exists if not gst_accounts.get(account): - all_output_account_exists = 1 + accounts_not_added = 0 # Check if already added in GST Settings if gst_accounts.get(account) in existing_account_list: - all_output_account_exists = 1 + accounts_not_added = 0 - if not all_input_account_exists: + if accounts_not_added: gst_settings.append('gst_accounts', { 'company': company, - 'cgst_account': gst_accounts.get(input_account_names[0]), - 'sgst_account': gst_accounts.get(input_account_names[1]), - 'igst_account': gst_accounts.get(input_account_names[2]) + 'cgst_account': gst_accounts.get(account_names[0]), + 'sgst_account': gst_accounts.get(account_names[1]), + 'igst_account': gst_accounts.get(account_names[2]), + 'is_reverse_charge_account': is_reverse_charge }) - if not all_output_account_exists: - gst_settings.append('gst_accounts', { - 'company': company, - 'cgst_account': gst_accounts.get(output_account_names[0]), - 'sgst_account': gst_accounts.get(output_account_names[1]), - 'igst_account': gst_accounts.get(output_account_names[2]) - }) - - gst_settings.save() - def set_salary_components(docs): docs.extend([ {'doctype': 'Salary Component', 'salary_component': 'Professional Tax', @@ -803,7 +799,7 @@ def set_tax_withholding_category(company): doc.append("rates", d.get('rates')[0]) doc.flags.ignore_permissions = True - doc.flags.ignore_validdate = True + doc.flags.ignore_validate = True doc.flags.ignore_mandatory = True doc.flags.ignore_links = True doc.save() diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index 36a7d20a8ffb..0b64f0d767b3 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -110,8 +110,8 @@ def on_update(self): self.create_default_warehouses() if frappe.flags.country_change: - install_country_fixtures(self.name, self.country) self.create_default_tax_template() + install_country_fixtures(self.name, self.country) if not frappe.db.get_value("Department", {"company": self.name}): from erpnext.setup.setup_wizard.operations.install_fixtures import install_post_company_fixtures diff --git a/erpnext/setup/setup_wizard/data/country_wise_tax.json b/erpnext/setup/setup_wizard/data/country_wise_tax.json index 7a61538b0e21..6df57f173803 100644 --- a/erpnext/setup/setup_wizard/data/country_wise_tax.json +++ b/erpnext/setup/setup_wizard/data/country_wise_tax.json @@ -1178,7 +1178,12 @@ "gst_state": "" }, { - "title": "Reverse Charge", + "title": "Reverse Charge In-State", + "is_inter_state": 0, + "gst_state": "" + }, + { + "title": "Reverse Charge Out-State", "is_inter_state": 0, "gst_state": "" }, @@ -1227,6 +1232,24 @@ "account_name": "Input Tax IGST", "tax_rate": 18.00 } + }, + { + "tax_type": { + "account_name": "Input Tax SGST RCM", + "tax_rate": 9.00 + } + }, + { + "tax_type": { + "account_name": "Input Tax CGST RCM", + "tax_rate": 9.00 + } + }, + { + "tax_type": { + "account_name": "Input Tax IGST RCM", + "tax_rate": 18.00 + } } ] }, @@ -1268,6 +1291,24 @@ "account_name": "Input Tax IGST", "tax_rate": 5.0 } + }, + { + "tax_type": { + "account_name": "Input Tax SGST RCM", + "tax_rate": 2.50 + } + }, + { + "tax_type": { + "account_name": "Input Tax CGST RCM", + "tax_rate": 2.50 + } + }, + { + "tax_type": { + "account_name": "Input Tax IGST RCM", + "tax_rate": 5.00 + } } ] }, @@ -1309,6 +1350,24 @@ "account_name": "Input Tax IGST", "tax_rate": 12.0 } + }, + { + "tax_type": { + "account_name": "Input Tax SGST RCM", + "tax_rate": 6.00 + } + }, + { + "tax_type": { + "account_name": "Input Tax CGST RCM", + "tax_rate": 6.00 + } + }, + { + "tax_type": { + "account_name": "Input Tax IGST RCM", + "tax_rate": 12.00 + } } ] }, @@ -1350,6 +1409,24 @@ "account_name": "Input Tax IGST", "tax_rate": 28.0 } + }, + { + "tax_type": { + "account_name": "Input Tax SGST RCM", + "tax_rate": 14.00 + } + }, + { + "tax_type": { + "account_name": "Input Tax CGST RCM", + "tax_rate": 14.00 + } + }, + { + "tax_type": { + "account_name": "Input Tax IGST RCM", + "tax_rate": 28.00 + } } ] }, @@ -1458,6 +1535,42 @@ } ], "tax_category": "Out-State" + }, + { + "title": "Input GST RCM In-state", + "taxes": [ + { + "account_head": { + "account_name": "Input Tax SGST RCM", + "tax_rate": 9.00, + "root_type": "Asset", + "account_type": "Tax" + } + }, + { + "account_head": { + "account_name": "Input Tax CGST RCM", + "tax_rate": 9.00, + "root_type": "Asset", + "account_type": "Tax" + } + } + ], + "tax_category": "Reverse Charge In-State" + }, + { + "title": "Input GST RCM Out-state", + "taxes": [ + { + "account_head": { + "account_name": "Input Tax IGST RCM", + "tax_rate": 18.00, + "root_type": "Asset", + "account_type": "Tax" + } + } + ], + "tax_category": "Reverse Charge Out-State" } ], "*": [ diff --git a/erpnext/setup/setup_wizard/operations/company_setup.py b/erpnext/setup/setup_wizard/operations/company_setup.py index 3f0bb146499a..4edf9485dc15 100644 --- a/erpnext/setup/setup_wizard/operations/company_setup.py +++ b/erpnext/setup/setup_wizard/operations/company_setup.py @@ -42,29 +42,6 @@ def enable_shopping_cart(args): 'quotation_series': "QTN-", }).insert() -def create_bank_account(args): - if args.get("bank_account"): - company_name = args.get('company_name') - bank_account_group = frappe.db.get_value("Account", - {"account_type": "Bank", "is_group": 1, "root_type": "Asset", - "company": company_name}) - if bank_account_group: - bank_account = frappe.get_doc({ - "doctype": "Account", - 'account_name': args.get("bank_account"), - 'parent_account': bank_account_group, - 'is_group':0, - 'company': company_name, - "account_type": "Bank", - }) - try: - return bank_account.insert() - except RootNotEditable: - frappe.throw(_("Bank account cannot be named as {0}").format(args.get("bank_account"))) - except frappe.DuplicateEntryError: - # bank account same as a CoA entry - pass - def create_email_digest(): from frappe.utils.user import get_system_managers system_managers = get_system_managers(only_name=True) From 4a23ec6e0f1fc7b0e797908df39fd8c0ccb043dc Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 2 Jun 2021 13:26:21 +0530 Subject: [PATCH 12/24] fix: Regional settings setup --- erpnext/regional/india/setup.py | 3 +-- erpnext/setup/doctype/company/company.py | 2 +- .../setup/setup_wizard/operations/taxes_setup.py | 14 +++++++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py index 39705f6e4425..5f9d5ed0d611 100644 --- a/erpnext/regional/india/setup.py +++ b/erpnext/regional/india/setup.py @@ -15,7 +15,6 @@ def setup(company=None, patch=True): setup_company_independent_fixtures(patch=patch) if not patch: make_fixtures(company) - setup_gst_settings(company) # TODO: for all countries def setup_company_independent_fixtures(patch=False): @@ -700,7 +699,7 @@ def make_fixtures(company=None): # create records for Tax Withholding Category set_tax_withholding_category(company) -def setup_gst_settings(company): +def update_regional_tax_settings(country, company): # Will only add default GST accounts if present input_account_names = ['Input Tax CGST', 'Input Tax SGST', 'Input Tax IGST'] output_account_names = ['Output Tax CGST', 'Output Tax SGST', 'Output Tax IGST'] diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py index 0b64f0d767b3..36a7d20a8ffb 100644 --- a/erpnext/setup/doctype/company/company.py +++ b/erpnext/setup/doctype/company/company.py @@ -110,8 +110,8 @@ def on_update(self): self.create_default_warehouses() if frappe.flags.country_change: - self.create_default_tax_template() install_country_fixtures(self.name, self.country) + self.create_default_tax_template() if not frappe.db.get_value("Department", {"company": self.name}): from erpnext.setup.setup_wizard.operations.install_fixtures import install_post_company_fixtures diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py index 6da3f386f8b5..040256bfd1ef 100644 --- a/erpnext/setup/setup_wizard/operations/taxes_setup.py +++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py @@ -26,7 +26,8 @@ def setup_taxes_and_charges(company_name: str, country: str): if 'chart_of_accounts' not in country_wise_tax: country_wise_tax = simple_to_detailed(country_wise_tax) - from_detailed_data(company_name, country_wise_tax) + from_detailed_data(company_name, country_wise_tax.get('chart_of_accounts')) + update_regional_tax_settings(country, company_name) def simple_to_detailed(templates): @@ -100,6 +101,17 @@ def from_detailed_data(company_name, data): make_item_tax_template(company_name, template) +def update_regional_tax_settings(country, company): + path = frappe.get_app_path('erpnext', 'regional', frappe.scrub(country)) + if os.path.exists(path.encode("utf-8")): + try: + module_name = "erpnext.regional.{0}.setup.update_regional_tax_settings".format(frappe.scrub(country)) + frappe.get_attr(module_name)(country, company) + except Exception as e: + # Log error and ignore if failed to setup regional tax settings + frappe.log_error() + pass + def make_taxes_and_charges_template(company_name, doctype, template): template['company'] = company_name template['doctype'] = doctype From 1528f1f622544e776df3e27e338f5967efd2a925 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 2 Jun 2021 14:12:28 +0530 Subject: [PATCH 13/24] fix: Check for tax category --- erpnext/setup/setup_wizard/operations/taxes_setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py index 040256bfd1ef..f6cbabd43992 100644 --- a/erpnext/setup/setup_wizard/operations/taxes_setup.py +++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py @@ -179,7 +179,7 @@ def make_item_tax_template(company_name, template): def make_tax_category(tax_category): """ Make tax category based on title if not already created """ doctype = 'Tax Category' - if not frappe.db.exists(doctype, tax_category): + if not frappe.db.exists(doctype, tax_category['title']): tax_category['doctype'] = doctype doc = frappe.get_doc(tax_category) doc.flags.ignore_links = True From 8ff623624de1d0d4a2763c070492dad32cfed85e Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 23 Jun 2021 12:38:37 +0530 Subject: [PATCH 14/24] fix: Move tax categories up in country wise json --- .../setup_wizard/data/country_wise_tax.json | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/erpnext/setup/setup_wizard/data/country_wise_tax.json b/erpnext/setup/setup_wizard/data/country_wise_tax.json index 6df57f173803..e36bf5cbe0e1 100644 --- a/erpnext/setup/setup_wizard/data/country_wise_tax.json +++ b/erpnext/setup/setup_wizard/data/country_wise_tax.json @@ -1164,35 +1164,35 @@ }, "India": { + "tax_categories": [ + { + "title": "In-State", + "is_inter_state": 0, + "gst_state": "" + }, + { + "title": "Out-State", + "is_inter_state": 1, + "gst_state": "" + }, + { + "title": "Reverse Charge In-State", + "is_inter_state": 0, + "gst_state": "" + }, + { + "title": "Reverse Charge Out-State", + "is_inter_state": 1, + "gst_state": "" + }, + { + "title": "Registered Composition", + "is_inter_state": 0, + "gst_state": "" + } + ], "chart_of_accounts": { "*": { - "tax_categories": [ - { - "title": "In-State", - "is_inter_state": 0, - "gst_state": "" - }, - { - "title": "Out-State", - "is_inter_state": 1, - "gst_state": "" - }, - { - "title": "Reverse Charge In-State", - "is_inter_state": 0, - "gst_state": "" - }, - { - "title": "Reverse Charge Out-State", - "is_inter_state": 0, - "gst_state": "" - }, - { - "title": "Registered Composition", - "is_inter_state": 0, - "gst_state": "" - } - ], "item_tax_templates": [ { "title": "GST 9%", From 18ed2c479d306a724518165eb80436f5e6c36fbb Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 23 Jun 2021 12:44:56 +0530 Subject: [PATCH 15/24] chore: Add comments --- erpnext/setup/setup_wizard/operations/taxes_setup.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py index f6cbabd43992..c42a0416a089 100644 --- a/erpnext/setup/setup_wizard/operations/taxes_setup.py +++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py @@ -142,6 +142,9 @@ def make_taxes_and_charges_template(company_name, doctype, template): tax_row[fieldname] = default_value doc = frappe.get_doc(template) + + # Data in country wise json is already pre validated, hence validations can be ignored + # Ingone validations to make doctypes faster doc.flags.ignore_links = True doc.flags.ignore_validate = True doc.insert(ignore_permissions=True) @@ -171,6 +174,9 @@ def make_item_tax_template(company_name, template): tax_row['tax_rate'] = account_data.get('tax_rate') doc = frappe.get_doc(template) + + # Data in country wise json is already pre validated, hence validations can be ignored + # Ingone validations to make doctypes faster doc.flags.ignore_links = True doc.flags.ignore_validate = True doc.insert(ignore_permissions=True) From 72c030a0c5935ee47c14200f77d8248f883bf877 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 23 Jun 2021 13:17:01 +0530 Subject: [PATCH 16/24] fix: Tests --- erpnext/setup/setup_wizard/operations/install_fixtures.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py index 7ae81d782ac9..652e99274127 100644 --- a/erpnext/setup/setup_wizard/operations/install_fixtures.py +++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py @@ -479,7 +479,7 @@ def update_stock_settings(): stock_settings.save() def create_bank_account(args): - if not args.bank_account: + if not args.get('bank_account'): return company_name = args.company_name From fba36ae85a87443ec479f1a2a5a4b92110f22d83 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Wed, 23 Jun 2021 15:37:17 +0530 Subject: [PATCH 17/24] fix: Test Cases --- erpnext/setup/setup_wizard/operations/install_fixtures.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py index 652e99274127..486043194185 100644 --- a/erpnext/setup/setup_wizard/operations/install_fixtures.py +++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py @@ -482,14 +482,14 @@ def create_bank_account(args): if not args.get('bank_account'): return - company_name = args.company_name + company_name = args.get('company_name') bank_account_group = frappe.db.get_value("Account", {"account_type": "Bank", "is_group": 1, "root_type": "Asset", "company": company_name}) if bank_account_group: bank_account = frappe.get_doc({ "doctype": "Account", - 'account_name': args.bank_account, + 'account_name': args.get('bank_account'), 'parent_account': bank_account_group, 'is_group':0, 'company': company_name, @@ -498,10 +498,10 @@ def create_bank_account(args): try: doc = bank_account.insert() - frappe.db.set_value("Company", args.company_name, "default_bank_account", bank_account.name, update_modified=False) + frappe.db.set_value("Company", args.get('company_name'), "default_bank_account", bank_account.name, update_modified=False) except RootNotEditable: - frappe.throw(_("Bank account cannot be named as {0}").format(args.bank_account)) + frappe.throw(_("Bank account cannot be named as {0}").format(args.get('bank_account'))) except frappe.DuplicateEntryError: # bank account same as a CoA entry pass From 022508cc1ea78da4e1efa262767ee19b6aeb2eb9 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sat, 26 Jun 2021 23:49:32 +0530 Subject: [PATCH 18/24] fix: Revert Changes --- erpnext/public/js/setup_wizard.js | 26 +++++++ .../setup_wizard/data/country_wise_tax.json | 72 ++++++++++++------- .../setup_wizard/operations/taxes_setup.py | 15 ++-- 3 files changed, 81 insertions(+), 32 deletions(-) diff --git a/erpnext/public/js/setup_wizard.js b/erpnext/public/js/setup_wizard.js index a3045724fee9..6f5d67c74621 100644 --- a/erpnext/public/js/setup_wizard.js +++ b/erpnext/public/js/setup_wizard.js @@ -139,10 +139,36 @@ erpnext.setup.slides_settings = [ }, validate: function () { + let me = this; + let exist; + if (!this.validate_fy_dates()) { return false; } + // Validate bank name + if(me.values.bank_account) { + frappe.call({ + async: false, + method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.validate_bank_account", + args: { + "coa": me.values.chart_of_accounts, + "bank_account": me.values.bank_account + }, + callback: function (r) { + if(r.message){ + exist = r.message; + me.get_field("bank_account").set_value(""); + let message = __('Account {0} already exists. Please enter a different name for your bank account.', + [me.values.bank_account] + ); + frappe.msgprint(message); + } + } + }); + return !exist; // Return False if exist = true + } + return true; }, diff --git a/erpnext/setup/setup_wizard/data/country_wise_tax.json b/erpnext/setup/setup_wizard/data/country_wise_tax.json index e36bf5cbe0e1..34af093a231a 100644 --- a/erpnext/setup/setup_wizard/data/country_wise_tax.json +++ b/erpnext/setup/setup_wizard/data/country_wise_tax.json @@ -1218,37 +1218,43 @@ { "tax_type": { "account_name": "Input Tax SGST", - "tax_rate": 9.00 + "tax_rate": 9.00, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax CGST", - "tax_rate": 9.00 + "tax_rate": 9.00, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax IGST", - "tax_rate": 18.00 + "tax_rate": 18.00, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax SGST RCM", - "tax_rate": 9.00 + "tax_rate": 9.00, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax CGST RCM", - "tax_rate": 9.00 + "tax_rate": 9.00, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax IGST RCM", - "tax_rate": 18.00 + "tax_rate": 18.00, + "root_type": "Asset" } } ] @@ -1277,37 +1283,43 @@ { "tax_type": { "account_name": "Input Tax SGST", - "tax_rate": 2.5 + "tax_rate": 2.5, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax CGST", - "tax_rate": 2.5 + "tax_rate": 2.5, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax IGST", - "tax_rate": 5.0 + "tax_rate": 5.0, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax SGST RCM", - "tax_rate": 2.50 + "tax_rate": 2.50, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax CGST RCM", - "tax_rate": 2.50 + "tax_rate": 2.50, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax IGST RCM", - "tax_rate": 5.00 + "tax_rate": 5.00, + "root_type": "Asset" } } ] @@ -1336,37 +1348,43 @@ { "tax_type": { "account_name": "Input Tax SGST", - "tax_rate": 6.0 + "tax_rate": 6.0, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax CGST", - "tax_rate": 6.0 + "tax_rate": 6.0, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax IGST", - "tax_rate": 12.0 + "tax_rate": 12.0, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax SGST RCM", - "tax_rate": 6.00 + "tax_rate": 6.00, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax CGST RCM", - "tax_rate": 6.00 + "tax_rate": 6.00, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax IGST RCM", - "tax_rate": 12.00 + "tax_rate": 12.00, + "root_type": "Asset" } } ] @@ -1395,37 +1413,43 @@ { "tax_type": { "account_name": "Input Tax SGST", - "tax_rate": 14.0 + "tax_rate": 14.0, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax CGST", - "tax_rate": 14.0 + "tax_rate": 14.0, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax IGST", - "tax_rate": 28.0 + "tax_rate": 28.0, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax SGST RCM", - "tax_rate": 14.00 + "tax_rate": 14.00, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax CGST RCM", - "tax_rate": 14.00 + "tax_rate": 14.00, + "root_type": "Asset" } }, { "tax_type": { "account_name": "Input Tax IGST RCM", - "tax_rate": 28.00 + "tax_rate": 28.00, + "root_type": "Asset" } } ] diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py index c42a0416a089..9b7e3d8fcfc6 100644 --- a/erpnext/setup/setup_wizard/operations/taxes_setup.py +++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py @@ -202,16 +202,15 @@ def get_or_create_account(company_name, account): existing_accounts = frappe.get_list('Account', filters={ - 'account_name': account.get('account_name'), - 'account_number': account.get('account_number', ''), - 'company': company_name + 'company': company_name, + 'root_type': root_type }, or_filters={ - 'company': company_name, - 'root_type': root_type, - 'is_group': 0 - } - ) + 'account_name': account.get('account_name'), + 'account_number': account.get('account_number') + }) + + print(company_name, account, existing_accounts) if existing_accounts: return frappe.get_doc('Account', existing_accounts[0].name) From dc89833852ec4f14ad43f864dc34c31c7574d233 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Sat, 26 Jun 2021 23:59:47 +0530 Subject: [PATCH 19/24] fix: Add validate bank account method back --- .../chart_of_accounts/chart_of_accounts.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py index 9b6842d896cc..927adc7086cd 100644 --- a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py +++ b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py @@ -188,6 +188,24 @@ def build_account_tree(tree, parent, all_accounts): # call recursively to build a subtree for current account build_account_tree(tree[child.account_name], child, all_accounts) +@frappe.whitelist() +def validate_bank_account(coa, bank_account): + accounts = [] + chart = get_chart(coa) + + if chart: + def _get_account_names(account_master): + for account_name, child in iteritems(account_master): + if account_name not in ["account_number", "account_type", + "root_type", "is_group", "tax_rate"]: + accounts.append(account_name) + + _get_account_names(child) + + _get_account_names(chart) + + return (bank_account in accounts) + @frappe.whitelist() def build_tree_from_json(chart_template, chart_data=None): ''' get chart template from its folder and parse the json to be rendered as tree ''' From 08d01c82c5115b3ac1c714db8053da02a07176dc Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 28 Jun 2021 10:52:38 +0530 Subject: [PATCH 20/24] fix: Update account heads in GST test cases --- .../sales_invoice/test_sales_invoice.py | 10 +++---- .../gstr_3b_report/test_gstr_3b_report.py | 28 +++++++++---------- .../setup_wizard/operations/taxes_setup.py | 2 -- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index fe531d3b227d..b11e1b671f8d 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -2087,9 +2087,9 @@ def make_sales_invoice_for_ewaybill(): if not gst_account: gst_settings.append("gst_accounts", { "company": "_Test Company", - "cgst_account": "CGST - _TC", - "sgst_account": "SGST - _TC", - "igst_account": "IGST - _TC", + "cgst_account": "Output Tax CGST - _TC", + "sgst_account": "Output Tax SGST - _TC", + "igst_account": "Output Tax IGST - _TC", }) gst_settings.save() @@ -2106,7 +2106,7 @@ def make_sales_invoice_for_ewaybill(): si.append("taxes", { "charge_type": "On Net Total", - "account_head": "CGST - _TC", + "account_head": "Output Tax CGST - _TC", "cost_center": "Main - _TC", "description": "CGST @ 9.0", "rate": 9 @@ -2114,7 +2114,7 @@ def make_sales_invoice_for_ewaybill(): si.append("taxes", { "charge_type": "On Net Total", - "account_head": "SGST - _TC", + "account_head": "Output Tax SGST - _TC", "cost_center": "Main - _TC", "description": "SGST @ 9.0", "rate": 9 diff --git a/erpnext/regional/doctype/gstr_3b_report/test_gstr_3b_report.py b/erpnext/regional/doctype/gstr_3b_report/test_gstr_3b_report.py index 3857ce1cdb84..065f80d610a9 100644 --- a/erpnext/regional/doctype/gstr_3b_report/test_gstr_3b_report.py +++ b/erpnext/regional/doctype/gstr_3b_report/test_gstr_3b_report.py @@ -46,14 +46,14 @@ def test_gstr_3b_report(self): make_sales_invoice() create_purchase_invoices() - if frappe.db.exists("GSTR 3B Report", "GSTR3B-March-2019-_Test Address-Billing"): - report = frappe.get_doc("GSTR 3B Report", "GSTR3B-March-2019-_Test Address-Billing") + if frappe.db.exists("GSTR 3B Report", "GSTR3B-March-2019-_Test Address GST-Billing"): + report = frappe.get_doc("GSTR 3B Report", "GSTR3B-March-2019-_Test Address GST-Billing") report.save() else: report = frappe.get_doc({ "doctype": "GSTR 3B Report", "company": "_Test Company GST", - "company_address": "_Test Address-Billing", + "company_address": "_Test Address GST-Billing", "year": getdate().year, "month": month_number_mapping.get(getdate().month) }).insert() @@ -89,7 +89,7 @@ def test_gst_rounding(self): si.append("taxes", { "charge_type": "On Net Total", - "account_head": "IGST - _GST", + "account_head": "Output Tax IGST - _GST", "cost_center": "Main - _GST", "description": "IGST @ 18.0", "rate": 18 @@ -117,7 +117,7 @@ def make_sales_invoice(): si.append("taxes", { "charge_type": "On Net Total", - "account_head": "IGST - _GST", + "account_head": "Output Tax IGST - _GST", "cost_center": "Main - _GST", "description": "IGST @ 18.0", "rate": 18 @@ -138,7 +138,7 @@ def make_sales_invoice(): si1.append("taxes", { "charge_type": "On Net Total", - "account_head": "IGST - _GST", + "account_head": "Output Tax IGST - _GST", "cost_center": "Main - _GST", "description": "IGST @ 18.0", "rate": 18 @@ -159,7 +159,7 @@ def make_sales_invoice(): si2.append("taxes", { "charge_type": "On Net Total", - "account_head": "IGST - _GST", + "account_head": "Output Tax IGST - _GST", "cost_center": "Main - _GST", "description": "IGST @ 18.0", "rate": 18 @@ -195,7 +195,7 @@ def create_purchase_invoices(): pi.append("taxes", { "charge_type": "On Net Total", - "account_head": "CGST - _GST", + "account_head": "Input Tax CGST - _GST", "cost_center": "Main - _GST", "description": "CGST @ 9.0", "rate": 9 @@ -203,7 +203,7 @@ def create_purchase_invoices(): pi.append("taxes", { "charge_type": "On Net Total", - "account_head": "SGST - _GST", + "account_head": "Input Tax SGST - _GST", "cost_center": "Main - _GST", "description": "SGST @ 9.0", "rate": 9 @@ -410,10 +410,10 @@ def make_company(): company.country = "India" company.insert() - if not frappe.db.exists('Address', '_Test Address-Billing'): + if not frappe.db.exists('Address', '_Test Address GST-Billing'): address = frappe.get_doc({ + "address_title": "_Test Address GST", "address_line1": "_Test Address Line 1", - "address_title": "_Test Address", "address_type": "Billing", "city": "_Test City", "state": "Test State", @@ -444,9 +444,9 @@ def set_account_heads(): if not gst_account: gst_settings.append("gst_accounts", { "company": "_Test Company GST", - "cgst_account": "CGST - _GST", - "sgst_account": "SGST - _GST", - "igst_account": "IGST - _GST", + "cgst_account": "Output Tax CGST - _GST", + "sgst_account": "Output Tax SGST - _GST", + "igst_account": "Output Tax IGST - _GST" }) gst_settings.save() diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py index 9b7e3d8fcfc6..6ea0ca407c37 100644 --- a/erpnext/setup/setup_wizard/operations/taxes_setup.py +++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py @@ -210,8 +210,6 @@ def get_or_create_account(company_name, account): 'account_number': account.get('account_number') }) - print(company_name, account, existing_accounts) - if existing_accounts: return frappe.get_doc('Account', existing_accounts[0].name) From ead7239d91006236c8a4b96ea5b43baf6d0e6ae3 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 5 Jul 2021 10:09:42 +0530 Subject: [PATCH 21/24] fix: Test cases for M-pesa --- .../doctype/mpesa_settings/test_mpesa_settings.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py index 3c2e59ab8211..2dfd5aad5dbb 100644 --- a/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py +++ b/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py @@ -9,13 +9,17 @@ from erpnext.accounts.doctype.pos_invoice.test_pos_invoice import create_pos_invoice class TestMpesaSettings(unittest.TestCase): + def setUp(self): + # create payment gateway in setup + create_mpesa_settings(payment_gateway_name="_Test") + create_mpesa_settings(payment_gateway_name="_Account Balance") + create_mpesa_settings(payment_gateway_name="Payment") + def tearDown(self): frappe.db.sql('delete from `tabMpesa Settings`') frappe.db.sql('delete from `tabIntegration Request` where integration_request_service = "Mpesa"') def test_creation_of_payment_gateway(self): - create_mpesa_settings(payment_gateway_name="_Test") - mode_of_payment = frappe.get_doc("Mode of Payment", "Mpesa-_Test") self.assertTrue(frappe.db.exists("Payment Gateway Account", {'payment_gateway': "Mpesa-_Test"})) self.assertTrue(mode_of_payment.name) @@ -47,7 +51,6 @@ def test_processing_of_account_balance(self): integration_request.delete() def test_processing_of_callback_payload(self): - create_mpesa_settings(payment_gateway_name="Payment") mpesa_account = frappe.db.get_value("Payment Gateway Account", {"payment_gateway": 'Mpesa-Payment'}, "payment_account") frappe.db.set_value("Account", mpesa_account, "account_currency", "KES") frappe.db.set_value("Customer", "_Test Customer", "default_currency", "KES") @@ -90,7 +93,6 @@ def test_processing_of_callback_payload(self): pos_invoice.delete() def test_processing_of_multiple_callback_payload(self): - create_mpesa_settings(payment_gateway_name="Payment") mpesa_account = frappe.db.get_value("Payment Gateway Account", {"payment_gateway": 'Mpesa-Payment'}, "payment_account") frappe.db.set_value("Account", mpesa_account, "account_currency", "KES") frappe.db.set_value("Mpesa Settings", "Payment", "transaction_limit", "500") @@ -141,7 +143,6 @@ def test_processing_of_multiple_callback_payload(self): pos_invoice.delete() def test_processing_of_only_one_succes_callback_payload(self): - create_mpesa_settings(payment_gateway_name="Payment") mpesa_account = frappe.db.get_value("Payment Gateway Account", {"payment_gateway": 'Mpesa-Payment'}, "payment_account") frappe.db.set_value("Account", mpesa_account, "account_currency", "KES") frappe.db.set_value("Mpesa Settings", "Payment", "transaction_limit", "500") From ddcc7fb537890fd76d3d10f49e02d0c1021dad68 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 5 Jul 2021 13:46:03 +0530 Subject: [PATCH 22/24] fix: Create mode of payment if doesn't exists --- .../doctype/mpesa_settings/test_mpesa_settings.py | 3 ++- erpnext/erpnext_integrations/utils.py | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py index 2dfd5aad5dbb..f592c180a3bf 100644 --- a/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py +++ b/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py @@ -7,6 +7,7 @@ import unittest from erpnext.erpnext_integrations.doctype.mpesa_settings.mpesa_settings import process_balance_info, verify_transaction from erpnext.accounts.doctype.pos_invoice.test_pos_invoice import create_pos_invoice +from erpnext.erpnext_integrations.utils import create_mode_of_payment class TestMpesaSettings(unittest.TestCase): def setUp(self): @@ -20,7 +21,7 @@ def tearDown(self): frappe.db.sql('delete from `tabIntegration Request` where integration_request_service = "Mpesa"') def test_creation_of_payment_gateway(self): - mode_of_payment = frappe.get_doc("Mode of Payment", "Mpesa-_Test") + mode_of_payment = create_mode_of_payment('Mpesa-_Test', payment_type="Phone") self.assertTrue(frappe.db.exists("Payment Gateway Account", {'payment_gateway': "Mpesa-_Test"})) self.assertTrue(mode_of_payment.name) self.assertEqual(mode_of_payment.type, "Phone") diff --git a/erpnext/erpnext_integrations/utils.py b/erpnext/erpnext_integrations/utils.py index 3840e781b4c0..b764701103d7 100644 --- a/erpnext/erpnext_integrations/utils.py +++ b/erpnext/erpnext_integrations/utils.py @@ -52,7 +52,8 @@ def create_mode_of_payment(gateway, payment_type="General"): "payment_gateway": gateway }, ['payment_account']) - if not frappe.db.exists("Mode of Payment", gateway) and payment_gateway_account: + mode_of_payment = frappe.db.exists("Mode of Payment", gateway) + if not mode_of_payment and payment_gateway_account: mode_of_payment = frappe.get_doc({ "doctype": "Mode of Payment", "mode_of_payment": gateway, @@ -66,6 +67,10 @@ def create_mode_of_payment(gateway, payment_type="General"): }) mode_of_payment.insert(ignore_permissions=True) + return mode_of_payment + else: + return frappe.get_doc("Mode of Payment", mode_of_payment) + def get_tracking_url(carrier, tracking_number): # Return the formatted Tracking URL. tracking_url = '' From fc8f3a8d0ddc6e2077cca61aea85842e9f39d1a2 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 5 Jul 2021 14:45:33 +0530 Subject: [PATCH 23/24] fix: Test cases --- erpnext/erpnext_integrations/utils.py | 2 +- erpnext/hr/doctype/expense_claim/test_expense_claim.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/erpnext_integrations/utils.py b/erpnext/erpnext_integrations/utils.py index b764701103d7..a5e162f8b5dd 100644 --- a/erpnext/erpnext_integrations/utils.py +++ b/erpnext/erpnext_integrations/utils.py @@ -68,7 +68,7 @@ def create_mode_of_payment(gateway, payment_type="General"): mode_of_payment.insert(ignore_permissions=True) return mode_of_payment - else: + elif mode_of_payment: return frappe.get_doc("Mode of Payment", mode_of_payment) def get_tracking_url(carrier, tracking_number): diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py index 578eccf787d6..141561fcdccd 100644 --- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py @@ -72,7 +72,8 @@ def test_expense_claim_status(self): def test_expense_claim_gl_entry(self): payable_account = get_payable_account(company_name) taxes = generate_taxes() - expense_claim = make_expense_claim(payable_account, 300, 200, company_name, "Travel Expenses - _TC4", do_not_submit=True, taxes=taxes) + expense_claim = make_expense_claim(payable_account, 300, 200, company_name, "Travel Expenses - _TC4", + do_not_submit=True, taxes=taxes) expense_claim.submit() gl_entries = frappe.db.sql("""select account, debit, credit @@ -145,7 +146,7 @@ def generate_taxes(): parent_account = frappe.db.get_value('Account', {'company': company_name, 'is_group':1, 'account_type': 'Tax'}, 'name') - account = create_account(company=company_name, account_name="CGST", account_type="Tax", parent_account=parent_account) + account = create_account(company=company_name, account_name="Output Tax CGST", account_type="Tax", parent_account=parent_account) return {'taxes':[{ "account_head": account, "rate": 0, From 75c55435d97e58ad9ab7b39e04e5d7432d033d44 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 5 Jul 2021 17:08:27 +0530 Subject: [PATCH 24/24] fix: Test Cases --- .../doctype/mpesa_settings/test_mpesa_settings.py | 1 + erpnext/hr/doctype/expense_claim/test_expense_claim.py | 2 +- erpnext/setup/setup_wizard/operations/install_fixtures.py | 7 ++++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py index f592c180a3bf..b0e662d3f32e 100644 --- a/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py +++ b/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py @@ -204,6 +204,7 @@ def create_mpesa_settings(payment_gateway_name="Express"): doc = frappe.get_doc(dict( #nosec doctype="Mpesa Settings", + sandbox=1, payment_gateway_name=payment_gateway_name, consumer_key="5sMu9LVI1oS3oBGPJfh3JyvLHwZOdTKn", consumer_secret="VI1oS3oBGPJfh3JyvLHw", diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py index 141561fcdccd..96ea686706cb 100644 --- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py +++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py @@ -83,7 +83,7 @@ def test_expense_claim_gl_entry(self): self.assertTrue(gl_entries) expected_values = dict((d[0], d) for d in [ - ['CGST - _TC4',18.0, 0.0], + ['Output Tax CGST - _TC4',18.0, 0.0], [payable_account, 0.0, 218.0], ["Travel Expenses - _TC4", 200.0, 0.0] ]) diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py index 486043194185..cd49a1805295 100644 --- a/erpnext/setup/setup_wizard/operations/install_fixtures.py +++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py @@ -448,6 +448,8 @@ def install_defaults(args=None): set_active_domains(args) update_stock_settings() update_shopping_cart_settings(args) + + args.update({"set_default": 1}) create_bank_account(args) def set_global_defaults(args): @@ -498,7 +500,10 @@ def create_bank_account(args): try: doc = bank_account.insert() - frappe.db.set_value("Company", args.get('company_name'), "default_bank_account", bank_account.name, update_modified=False) + if args.get('set_default'): + frappe.db.set_value("Company", args.get('company_name'), "default_bank_account", bank_account.name, update_modified=False) + + return doc except RootNotEditable: frappe.throw(_("Bank account cannot be named as {0}").format(args.get('bank_account')))