Merge branch 'develop' of https://github.com/frappe/erpnext into bootstrapped_gst_setup_develop
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index fe531d3..b11e1b6 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 @@
 	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 @@
 
 	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 @@
 
 	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/accounts/utils.py b/erpnext/accounts/utils.py
index a8e4b15..1cdbd8d 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -788,7 +788,7 @@
 	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/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py b/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py
index 3c2e59a..b0e662d 100644
--- a/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py
+++ b/erpnext/erpnext_integrations/doctype/mpesa_settings/test_mpesa_settings.py
@@ -7,16 +7,21 @@
 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):
+		# 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")
+		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")
@@ -47,7 +52,6 @@
 		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 +94,6 @@
 		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 +144,6 @@
 		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")
@@ -202,6 +204,7 @@
 
 	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/erpnext_integrations/utils.py b/erpnext/erpnext_integrations/utils.py
index 3840e78..a5e162f 100644
--- a/erpnext/erpnext_integrations/utils.py
+++ b/erpnext/erpnext_integrations/utils.py
@@ -52,7 +52,8 @@
 			"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 @@
 		})
 		mode_of_payment.insert(ignore_permissions=True)
 
+		return mode_of_payment
+	elif mode_of_payment:
+		return frappe.get_doc("Mode of Payment", mode_of_payment)
+
 def get_tracking_url(carrier, tracking_number):
 	# Return the formatted Tracking URL.
 	tracking_url = ''
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
index 578eccf..96ea686 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_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
@@ -82,7 +83,7 @@
 		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]
 		])
@@ -145,7 +146,7 @@
 	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,
diff --git a/erpnext/public/js/setup_wizard.js b/erpnext/public/js/setup_wizard.js
index ef03b01..6f5d67c 100644
--- a/erpnext/public/js/setup_wizard.js
+++ b/erpnext/public/js/setup_wizard.js
@@ -147,7 +147,7 @@
 			}
 
 			// Validate bank name
-			if(me.values.bank_account){
+			if(me.values.bank_account) { 
 				frappe.call({
 					async: false,
 					method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.validate_bank_account",
diff --git a/erpnext/regional/doctype/gst_settings/gst_settings.py b/erpnext/regional/doctype/gst_settings/gst_settings.py
index bc956e9..af3d92e 100644
--- a/erpnext/regional/doctype/gst_settings/gst_settings.py
+++ b/erpnext/regional/doctype/gst_settings/gst_settings.py
@@ -19,6 +19,21 @@
 			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)
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 3857ce1..065f80d 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 @@
 		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 @@
 
 		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 @@
 
 	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 @@
 
 	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 @@
 
 	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 @@
 
 	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 @@
 
 	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 @@
 	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 @@
 	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/regional/india/setup.py b/erpnext/regional/india/setup.py
index 3e0b9b7..5f9d5ed 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -25,6 +25,7 @@
 	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:
@@ -680,7 +681,7 @@
 
 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)
@@ -698,6 +699,53 @@
 	# create records for Tax Withholding Category
 	set_tax_withholding_category(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']
+	rcm_accounts = ['Input Tax CGST RCM', 'Input Tax SGST RCM', 'Input Tax IGST RCM']
+	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, 'account_name': ('in', input_account_names +
+			output_account_names + rcm_accounts)}, ['account_name', 'name'], as_list=1))
+
+	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)
+
+	gst_settings.save()
+
+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 account_names:
+		# Default Account Added does not exists
+		if not gst_accounts.get(account):
+			accounts_not_added = 0
+
+		# Check if already added in GST Settings
+		if gst_accounts.get(account) in existing_account_list:
+			accounts_not_added = 0
+
+	if accounts_not_added:
+		gst_settings.append('gst_accounts', {
+			'company': company,
+			'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
+		})
+
 def set_salary_components(docs):
 	docs.extend([
 		{'doctype': 'Salary Component', 'salary_component': 'Professional Tax',
@@ -731,12 +779,13 @@
 	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_validate = True
 			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:
@@ -749,11 +798,12 @@
 					doc.append("rates", d.get('rates')[0])
 
 			doc.flags.ignore_permissions = True
+			doc.flags.ignore_validate = 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 +962,6 @@
 	]
 
 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 +979,7 @@
 
 		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/regional/report/e_invoice_summary/e_invoice_summary.json b/erpnext/regional/report/e_invoice_summary/e_invoice_summary.json
index 4deb073..d0000ad 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",
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 8fd905d..36a7d20 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -110,7 +110,7 @@
 				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}):
@@ -440,16 +440,15 @@
 
 	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)))
+			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):
diff --git a/erpnext/setup/setup_wizard/data/country_wise_tax.json b/erpnext/setup/setup_wizard/data/country_wise_tax.json
index daaa626..34af093 100644
--- a/erpnext/setup/setup_wizard/data/country_wise_tax.json
+++ b/erpnext/setup/setup_wizard/data/country_wise_tax.json
@@ -1164,33 +1164,292 @@
 	},
 
 	"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": {
 			"*": {
 				"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": "CGST",
+									"account_name": "Output Tax CGST",
 									"tax_rate": 9.00
 								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Output Tax IGST",
+									"tax_rate": 18.00
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax SGST",
+									"tax_rate": 9.00,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax CGST",
+									"tax_rate": 9.00,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax IGST",
+									"tax_rate": 18.00,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax SGST RCM",
+									"tax_rate": 9.00,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax CGST RCM",
+									"tax_rate": 9.00,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax IGST RCM",
+									"tax_rate": 18.00,
+									"root_type": "Asset"
+								}
 							}
 						]
 					},
 					{
-						"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,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax CGST",
+									"tax_rate": 2.5,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax IGST",
+									"tax_rate": 5.0,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax SGST RCM",
+									"tax_rate": 2.50,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax CGST RCM",
+									"tax_rate": 2.50,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax IGST RCM",
+									"tax_rate": 5.00,
+									"root_type": "Asset"
+								}
+							}
+						]
+					},
+					{
+						"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,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax CGST",
+									"tax_rate": 6.0,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax IGST",
+									"tax_rate": 12.0,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax SGST RCM",
+									"tax_rate": 6.00,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax CGST RCM",
+									"tax_rate": 6.00,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax IGST RCM",
+									"tax_rate": 12.00,
+									"root_type": "Asset"
+								}
+							}
+						]
+					},
+					{
+						"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,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax CGST",
+									"tax_rate": 14.0,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax IGST",
+									"tax_rate": 28.0,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax SGST RCM",
+									"tax_rate": 14.00,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax CGST RCM",
+									"tax_rate": 14.00,
+									"root_type": "Asset"
+								}
+							},
+							{
+								"tax_type": {
+									"account_name": "Input Tax IGST RCM",
+									"tax_rate": 28.00,
+									"root_type": "Asset"
 								}
 							}
 						]
@@ -1229,36 +1488,117 @@
 						]
 					}
 				],
-				"*": [
+				"sales_tax_templates": [
 					{
-						"title": "In State GST",
+						"title": "Output GST In-state",
 						"taxes": [
 							{
 								"account_head": {
-									"account_name": "SGST",
-									"tax_rate": 9.00
+									"account_name": "Output Tax SGST",
+									"tax_rate": 9.00,
+									"account_type": "Tax"
 								}
 							},
 							{
 								"account_head": {
-									"account_name": "CGST",
-									"tax_rate": 9.00
+									"account_name": "Output Tax CGST",
+									"tax_rate": 9.00,
+									"account_type": "Tax"
 								}
 							}
-						]
+						],
+						"tax_category": "In-State"
 					},
 					{
-						"title": "Out of State GST",
+						"title": "Output GST Out-state",
 						"taxes": [
 							{
 								"account_head": {
-									"account_name": "IGST",
-									"tax_rate": 18.00
+									"account_name": "Output Tax IGST",
+									"tax_rate": 18.00,
+									"account_type": "Tax"
 								}
 							}
-						]
+						],
+						"tax_category": "Out-State"
+					}
+				],
+				"purchase_tax_templates": [
+					{
+						"title": "Input GST In-state",
+						"taxes": [
+							{
+								"account_head": {
+									"account_name": "Input Tax SGST",
+									"tax_rate": 9.00,
+									"root_type": "Asset",
+									"account_type": "Tax"
+								}
+							},
+							{
+								"account_head": {
+									"account_name": "Input Tax CGST",
+									"tax_rate": 9.00,
+									"root_type": "Asset",
+									"account_type": "Tax"
+								}
+							}
+						],
+						"tax_category": "In-State"
 					},
 					{
+						"title": "Input GST Out-state",
+						"taxes": [
+							{
+								"account_head": {
+									"account_name": "Input Tax IGST",
+									"tax_rate": 18.00,
+									"root_type": "Asset",
+									"account_type": "Tax"
+								}
+							}
+						],
+						"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"
+					}
+				],
+				"*": [
+					{
 						"title": "VAT 5%",
 						"taxes": [
 							{
@@ -1349,7 +1689,7 @@
 		"Italy VAT 4%":{
 			"account_name": "IVA 4%",
 			"tax_rate": 4.00
-		}		
+		}
 	},
 
 	"Ivory Coast": {
diff --git a/erpnext/setup/setup_wizard/operations/company_setup.py b/erpnext/setup/setup_wizard/operations/company_setup.py
index 3f0bb14..4edf948 100644
--- a/erpnext/setup/setup_wizard/operations/company_setup.py
+++ b/erpnext/setup/setup_wizard/operations/company_setup.py
@@ -42,29 +42,6 @@
 		'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)
diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py
index 7ae81d7..cd49a18 100644
--- a/erpnext/setup/setup_wizard/operations/install_fixtures.py
+++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py
@@ -448,6 +448,8 @@
 	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):
@@ -479,17 +481,17 @@
 	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
+	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 +500,13 @@
 		try:
 			doc = bank_account.insert()
 
-			frappe.db.set_value("Company", args.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.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
diff --git a/erpnext/setup/setup_wizard/operations/taxes_setup.py b/erpnext/setup/setup_wizard/operations/taxes_setup.py
index f4fe18e..6ea0ca4 100644
--- a/erpnext/setup/setup_wizard/operations/taxes_setup.py
+++ b/erpnext/setup/setup_wizard/operations/taxes_setup.py
@@ -26,7 +26,8 @@
 	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):
@@ -77,16 +78,15 @@
 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('*', {})
+	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 tax_categories:
 		for tax_category in tax_categories:
-			make_tax_catgory(tax_category)
+			make_tax_category(tax_category)
 
 	if sales_tax_templates:
 		for template in sales_tax_templates:
@@ -101,6 +101,17 @@
 			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
@@ -130,8 +141,14 @@
 			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)
 
+	# 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)
+	return doc
 
 def make_item_tax_template(company_name, template):
 	"""Create an Item Tax Template.
@@ -156,8 +173,24 @@
 			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)
 
+	# 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)
+	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['title']):
+		tax_category['doctype'] = doctype
+		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,8 +208,7 @@
 		or_filters={
 			'account_name': account.get('account_name'),
 			'account_number': account.get('account_number')
-		}
-	)
+		})
 
 	if existing_accounts:
 		return frappe.get_doc('Account', existing_accounts[0].name)
@@ -191,8 +223,11 @@
 	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'
@@ -237,7 +272,11 @@
 		'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