GST tax invoice print format and more (#9616)

* GST Tax Invoice print format and more. Fixes #9545 #9566 #9608

* Reload gst print format only for Indian users

* Fixes as Codacy
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 1a55d84..dc547e3 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -305,6 +305,23 @@
 		}
 
 		this.frm.refresh_fields();
+	},
+	
+	company_address: function() {
+		var me = this;
+		if(this.frm.doc.company_address) {
+			frappe.call({
+				method: "frappe.contacts.doctype.address.address.get_address_display",
+				args: {"address_dict": this.frm.doc.company_address },
+				callback: function(r) {
+					if(r.message) {
+						me.frm.set_value("company_address_display", r.message)
+					}
+				}
+			})
+		} else {
+			this.frm.set_value("company_address_display", "");
+		}
 	}
 });
 
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index a2e9ddf..4c05b94 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -190,7 +190,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "remember_last_selected_value": 0, 
@@ -206,37 +206,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "due_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Payment Due Date", 
-   "length": 0, 
-   "no_copy": 1, 
-   "oldfieldname": "due_date", 
-   "oldfieldtype": "Date", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fieldname": "project", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -253,7 +222,7 @@
    "oldfieldtype": "Link", 
    "options": "Project", 
    "permlevel": 0, 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -314,7 +283,7 @@
    "no_copy": 0, 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "remember_last_selected_value": 0, 
@@ -345,7 +314,7 @@
    "options": "POS Profile", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -516,6 +485,37 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "due_date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Payment Due Date", 
+   "length": 0, 
+   "no_copy": 1, 
+   "oldfieldname": "due_date", 
+   "oldfieldtype": "Date", 
+   "permlevel": 0, 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "amended_from", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -850,6 +850,37 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "territory", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Territory", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Territory", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 1, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "col_break4", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -949,13 +980,13 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Company Address", 
+   "label": "Company Address Name", 
    "length": 0, 
    "no_copy": 0, 
    "options": "Address", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -971,24 +1002,23 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "territory", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
+   "fieldname": "company_address_display", 
+   "fieldtype": "Small Text", 
+   "hidden": 1, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Territory", 
+   "label": "Company Address", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Territory", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -1479,7 +1509,7 @@
    "options": "Sales Invoice Timesheet", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -1886,10 +1916,40 @@
    "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
+   "collapsible": 1, 
+   "columns": 0, 
+   "fieldname": "sec_tax_breakup", 
+   "fieldtype": "Section Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Item-wise Tax Breakup", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
    "fieldname": "other_charges_calculation", 
-   "fieldtype": "HTML", 
+   "fieldtype": "Text", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -1899,12 +1959,12 @@
    "in_standard_filter": 0, 
    "label": "Taxes and Charges Calculation", 
    "length": 0, 
-   "no_copy": 0, 
+   "no_copy": 1, 
    "oldfieldtype": "HTML", 
    "permlevel": 0, 
    "print_hide": 1, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -2984,7 +3044,7 @@
    "options": "Account", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -4450,7 +4510,7 @@
    "options": "Print Format", 
    "permlevel": 0, 
    "precision": "", 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -4511,7 +4571,7 @@
    "length": 0, 
    "no_copy": 1, 
    "permlevel": 0, 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -4542,7 +4602,7 @@
    "length": 0, 
    "no_copy": 1, 
    "permlevel": 0, 
-   "print_hide": 0, 
+   "print_hide": 1, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
    "remember_last_selected_value": 0, 
@@ -4627,7 +4687,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2017-06-29 10:47:49.522969", 
+ "modified": "2017-07-04 17:11:09.477003", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Sales Invoice", 
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 2e044cc..071e72b 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1105,6 +1105,22 @@
 			for i, k in enumerate(expected_values["keys"]):
 				self.assertEquals(d.get(k), expected_values[d.item_code][i])
 
+	def test_item_wise_tax_breakup(self):
+		si = create_sales_invoice(qty=100, rate=50, do_not_save=True)
+		si.append("taxes", {
+			"charge_type": "On Net Total",
+			"account_head": "_Test Account Service Tax - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Service Tax",
+			"rate": 10
+		})
+		si.insert()
+		
+		tax_breakup_html = '''\n<div class="tax-break-up" style="overflow-x: auto;">\n\t<table class="table table-bordered table-hover">\n\t\t<thead><tr><th class="text-left" style="min-width: 120px;">Item Name</th>\n<th class="text-right" style="min-width: 80px;">Taxable Amount</th>\n<th class="text-right" style="min-width: 80px;">_Test Account Service Tax - _TC</th></tr></thead>\n\t\t<tbody><tr><td>_Test Item</td><td class="text-right">5000.0</td><td class="text-right">(10.0%) \u20b9 500.00</td></tr></tbody>\n\t</table>\n</div>'''
+		
+		self.assertEqual(si.other_charges_calculation, tax_breakup_html)
+		
+
 def create_sales_invoice(**args):
 	si = frappe.new_doc("Sales Invoice")
 	args = frappe._dict(args)
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 50f6b61..b0fe395 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -5,7 +5,7 @@
 import json
 import frappe, erpnext
 from frappe import _, scrub
-from frappe.utils import cint, flt, round_based_on_smallest_currency_fraction
+from frappe.utils import cint, flt, cstr, fmt_money, round_based_on_smallest_currency_fraction
 from erpnext.controllers.accounts_controller import validate_conversion_rate, \
 	validate_taxes_and_charges, validate_inclusive_tax
 
@@ -24,6 +24,9 @@
 
 		if self.doc.doctype in ["Sales Invoice", "Purchase Invoice"]:
 			self.calculate_total_advance()
+			
+		if self.doc.meta.get_field("other_charges_calculation"):
+			self.set_item_wise_tax_breakup()
 
 	def _calculate(self):
 		self.calculate_item_values()
@@ -504,3 +507,106 @@
 				rate_with_margin = flt(item.price_list_rate) + flt(margin_value)
 
 		return rate_with_margin
+
+	def set_item_wise_tax_breakup(self):
+		item_tax = {}
+		tax_accounts = []
+		
+		item_tax, tax_accounts = self.get_item_tax(item_tax, tax_accounts)
+		
+		headings = get_table_column_headings(tax_accounts)
+		
+		distinct_items = self.get_distinct_items()
+		
+		rows = get_table_rows(distinct_items, item_tax, tax_accounts)
+		
+		if not rows:
+			self.doc.other_charges_calculation = ""
+		else:
+			self.doc.other_charges_calculation = '''
+<div class="tax-break-up" style="overflow-x: auto;">
+	<table class="table table-bordered table-hover">
+		<thead><tr>{headings}</tr></thead>
+		<tbody>{rows}</tbody>
+	</table>
+</div>'''.format(**{
+	"headings": "\n".join(headings),
+	"rows": "\n".join(rows)
+})
+
+	def get_item_tax(self, item_tax, tax_accounts):
+		company_currency = erpnext.get_company_currency(self.doc.company)
+
+		for tax in self.doc.taxes:
+			tax_amount_precision = tax.precision("tax_amount")
+			tax_rate_precision = tax.precision("rate");
+			
+			item_tax_map = self._load_item_tax_rate(tax.item_wise_tax_detail)
+			for item_code, tax_data in item_tax_map.items():
+				if not item_tax.get(item_code):
+					item_tax[item_code] = {}
+					
+				if isinstance(tax_data, list):
+					tax_rate = ""
+					if tax_data[0]:
+						if tax.charge_type == "Actual":
+							tax_rate = fmt_money(flt(tax_data[0], tax_amount_precision),
+								tax_amount_precision, company_currency)
+						else:
+							tax_rate = cstr(flt(tax_data[0], tax_rate_precision)) + "%"
+							
+						tax_amount = fmt_money(flt(tax_data[1], tax_amount_precision),
+							tax_amount_precision, company_currency)
+							
+						item_tax[item_code][tax.name] = [tax_rate, tax_amount]
+					else:
+						item_tax[item_code][tax.name] = [cstr(flt(tax_data, tax_rate_precision)) + "%", ""]
+			tax_accounts.append([tax.name, tax.account_head])
+		
+		return item_tax, tax_accounts
+
+	
+	def get_distinct_items(self):
+		distinct_item_names = []
+		distinct_items = []
+		for item in self.doc.items:
+			item_code = item.item_code or item.item_name
+			if item_code not in distinct_item_names:
+				distinct_item_names.append(item_code)
+				distinct_items.append(item)
+				
+		return distinct_items
+
+def get_table_column_headings(tax_accounts):
+	headings_name = [_("Item Name"), _("Taxable Amount")] + [d[1] for d in tax_accounts]
+	headings = []
+	for head in headings_name:
+		if head == _("Item Name"):
+			headings.append('<th style="min-width: 120px;" class="text-left">' + (head or "") + "</th>")
+		else:
+			headings.append('<th style="min-width: 80px;" class="text-right">' + (head or "") + "</th>")
+			
+	return headings
+
+def get_table_rows(distinct_items, item_tax, tax_accounts):
+	rows = []
+	for item in distinct_items:
+		item_tax_record = item_tax.get(item.item_code or item.item_name)
+		if not item_tax_record:
+			continue
+		
+		taxes = []
+		for head in tax_accounts:
+			if item_tax_record[head[0]]:
+				taxes.append("<td class='text-right'>(" + item_tax_record[head[0]][0] + ") "
+					 + item_tax_record[head[0]][1] + "</td>")
+			else:
+				taxes.append("<td></td>")
+		
+		rows.append("<tr><td>{item_name}</td><td class='text-right'>{taxable_amount}</td>{taxes}</tr>".format(**{
+			"item_name": item.item_name,
+			"taxable_amount": item.net_amount,
+			"taxes": "\n".join(taxes)
+		}))
+		
+	return rows
\ No newline at end of file
diff --git a/erpnext/docs/assets/img/regional/india/address-template-gstin.png b/erpnext/docs/assets/img/regional/india/address-template-gstin.png
new file mode 100644
index 0000000..8740609
--- /dev/null
+++ b/erpnext/docs/assets/img/regional/india/address-template-gstin.png
Binary files differ
diff --git a/erpnext/docs/assets/img/regional/india/sample-gst-tax-invoice.png b/erpnext/docs/assets/img/regional/india/sample-gst-tax-invoice.png
new file mode 100644
index 0000000..4f4a9b1
--- /dev/null
+++ b/erpnext/docs/assets/img/regional/india/sample-gst-tax-invoice.png
Binary files differ
diff --git a/erpnext/docs/license.html b/erpnext/docs/license.html
index 4740c5c..1d50b78 100644
--- a/erpnext/docs/license.html
+++ b/erpnext/docs/license.html
@@ -640,8 +640,8 @@
 the exclusion of warranty; and each file should have at least the
 "copyright" line and a pointer to where the full notice is found.</p>
 
-<pre><code>    &lt;one line to give the program's name and a brief idea of what it does.&gt;
-    Copyright (C) &lt;year&gt;  &lt;name of author&gt;
+<pre><code>    &lt;one line="" to="" give="" the="" program's="" name="" and="" a="" brief="" idea="" of="" what="" it="" does.=""&gt;
+    Copyright (C) &lt;year&gt;  &lt;name of="" author=""&gt;
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/erpnext/docs/user/manual/en/regional/india/gst-setup.md b/erpnext/docs/user/manual/en/regional/india/gst-setup.md
index 48e5066..0ba8284 100644
--- a/erpnext/docs/user/manual/en/regional/india/gst-setup.md
+++ b/erpnext/docs/user/manual/en/regional/india/gst-setup.md
@@ -14,6 +14,13 @@
 
 <img class="screenshot" alt="GST in Company" src="{{docs_base_url}}/assets/img/regional/india/gstin-company.gif">
 
+**Include GSTIN number in the Address Template**
+
+Open Address Template record for India, and add GSTIN number there if not exists.
+
+<img class="screenshot" alt="GST in Company" src="{{docs_base_url}}/assets/img/regional/india/address-template-gstin.png">
+
+
 ### 2. Setting up HSN Codes
 
 According to the GST Law, your itemised invoices must contain the HSN Code related to that Item. ERPNext comes pre-installed with all 12,000+ HSN Codes so that you can easily select the relevant HSN Code in your Item
@@ -54,6 +61,12 @@
 
 <img class="screenshot" alt="GST Invoice" src="{{docs_base_url}}/assets/img/regional/india/gst-invoice.gif">
 
+### 6. Print GST Tax Invoice
+
+To print Tax Invoice as per GSTN guidelines, please select **GST Tax Invoice** print format. This print format includes company address, GSTIN numbers, HSN/SAC Code and item-wise tax breakup.
+
+<img class="screenshot" alt="Sample GST Tax Invoice" src="{{docs_base_url}}/assets/img/regional/india/sample-gst-tax-invoice.png">
+
 ### Reports
 
 ERPNext comes with most of your reports you need to prepare your GST Returns. Go to Accounts > GST India head for the list.
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 30a24f8..e7cf5f2 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -410,4 +410,5 @@
 erpnext.patches.v8_1.delete_deprecated_reports
 erpnext.patches.v8_1.setup_gst_india #2017-06-27
 execute:frappe.reload_doc('regional', 'doctype', 'gst_hsn_code')
-erpnext.patches.v8_1.removed_roles_from_gst_report_non_indian_account
\ No newline at end of file
+erpnext.patches.v8_1.removed_roles_from_gst_report_non_indian_account
+erpnext.patches.v8_1.gst_fixes
diff --git a/erpnext/patches/v8_1/gst_fixes.py b/erpnext/patches/v8_1/gst_fixes.py
new file mode 100644
index 0000000..5454f0f
--- /dev/null
+++ b/erpnext/patches/v8_1/gst_fixes.py
@@ -0,0 +1,27 @@
+import frappe
+
+def execute():
+	frappe.db.sql("""update `tabCustom Field` set label = 'HSN/SAC Code'
+		where fieldname='gst_hsn_code' and label='GST HSN Code'
+	""")
+
+	frappe.db.sql("""update `tabCustom Field` set print_hide = 1
+		where fieldname in ('customer_gstin', 'supplier_gstin', 'company_gstin')
+	""")
+
+	frappe.db.sql("""update `tabCustom Field` set insert_after = 'address_display'
+		where fieldname in ('customer_gstin', 'supplier_gstin')
+	""")
+
+	frappe.db.sql("""update `tabCustom Field` set insert_after = 'company_address_display'
+		where fieldname = 'company_gstin'
+	""")
+
+	frappe.db.sql("""update `tabCustom Field` set insert_after = 'description'
+		where fieldname='gst_hsn_code' and dt in ('Sales Invoice Item', 'Purchase Invoice Item')
+	""")
+
+	# reload gst print format for Indian users
+	company = frappe.get_all('Company', filters = {'country': 'India'})
+	if company:
+		frappe.reload_doc("regional", "print_format", "gst_tax_invoice")
\ No newline at end of file
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index c4d8155..642ff1b 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -634,5 +634,91 @@
 		}
 		
 		this.calculate_outstanding_amount(false)
+	},
+	
+	show_item_wise_taxes: function() {
+		if(this.frm.fields_dict.other_charges_calculation) {
+			this.frm.toggle_display("other_charges_calculation", this.frm.doc.other_charges_calculation);
+		}
+	},
+	
+	set_item_wise_tax_breakup: function() {
+		if(this.frm.fields_dict.other_charges_calculation) {
+			var html = this.get_item_wise_taxes_html();
+			// console.log(html);
+			this.frm.set_value("other_charges_calculation", html);
+			this.show_item_wise_taxes();
+		}
+	},
+		
+	get_item_wise_taxes_html: function() {
+		var item_tax = {};
+		var tax_accounts = [];
+		var company_currency = this.get_company_currency();
+
+		$.each(this.frm.doc["taxes"] || [], function(i, tax) {
+			var tax_amount_precision = precision("tax_amount", tax);
+			var tax_rate_precision = precision("rate", tax);
+			$.each(JSON.parse(tax.item_wise_tax_detail || '{}'),
+				function(item_code, tax_data) {
+					if(!item_tax[item_code]) item_tax[item_code] = {};
+					if($.isArray(tax_data)) {
+						var tax_rate = "";
+						if(tax_data[0] != null) {
+							tax_rate = (tax.charge_type === "Actual") ?
+								format_currency(flt(tax_data[0], tax_amount_precision),
+									company_currency, tax_amount_precision) :
+								(flt(tax_data[0], tax_rate_precision) + "%");
+						}
+						var tax_amount = format_currency(flt(tax_data[1], tax_amount_precision),
+							company_currency, tax_amount_precision);
+
+						item_tax[item_code][tax.name] = [tax_rate, tax_amount];
+					} else {
+						item_tax[item_code][tax.name] = [flt(tax_data, tax_rate_precision) + "%", ""];
+					}
+				});
+			tax_accounts.push([tax.name, tax.account_head]);
+		});
+		
+		var headings = $.map([__("Item Name"), __("Taxable Amount")].concat($.map(tax_accounts, 
+			function(head) { return head[1]; })), function(head) {
+				if(head==__("Item Name")) {
+					return '<th style="min-width: 100px;" class="text-left">' + (head || "") + "</th>";
+				} else {
+					return '<th style="min-width: 80px;" class="text-right">' + (head || "") + "</th>";
+				}	
+			}
+		).join("\n");
+
+		var distinct_item_names = [];
+		var distinct_items = [];
+		$.each(this.frm.doc["items"] || [], function(i, item) {
+			if(distinct_item_names.indexOf(item.item_code || item.item_name)===-1) {
+				distinct_item_names.push(item.item_code || item.item_name);
+				distinct_items.push(item);
+			}
+		});
+
+		var rows = $.map(distinct_items, function(item) {
+			var item_tax_record = item_tax[item.item_code || item.item_name];
+			if(!item_tax_record) { return null; }
+			return repl("<tr><td>%(item_name)s</td><td class='text-right'>%(taxable_amount)s</td>%(taxes)s</tr>", {
+				item_name: item.item_name,
+				taxable_amount: item.net_amount,
+				taxes: $.map(tax_accounts, function(head) {
+					return item_tax_record[head[0]] ?
+						"<td class='text-right'>(" + item_tax_record[head[0]][0] + ") " + item_tax_record[head[0]][1] + "</td>" :
+						"<td></td>";
+				}).join("\n")
+			});
+		}).join("\n");
+
+		if(!rows) return "";
+		return '<div class="tax-break-up" style="overflow-x: auto;">\
+		<table class="table table-bordered table-hover">\
+			<thead><tr>' + headings + '</tr></thead> \
+			<tbody>' + rows + '</tbody> \
+		</table></div>';
 	}
 })
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index cd8e7bd..c4f9e8a 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -374,6 +374,7 @@
 
 	validate: function() {
 		this.calculate_taxes_and_totals(false);
+		this.set_item_wise_tax_breakup();
 	},
 
 	company: function() {
@@ -936,69 +937,6 @@
 		});
 	},
 
-	get_item_wise_taxes_html: function() {
-		var item_tax = {};
-		var tax_accounts = [];
-		var company_currency = this.get_company_currency();
-
-		$.each(this.frm.doc["taxes"] || [], function(i, tax) {
-			var tax_amount_precision = precision("tax_amount", tax);
-			var tax_rate_precision = precision("rate", tax);
-			$.each(JSON.parse(tax.item_wise_tax_detail || '{}'),
-				function(item_code, tax_data) {
-					if(!item_tax[item_code]) item_tax[item_code] = {};
-					if($.isArray(tax_data)) {
-						var tax_rate = "";
-						if(tax_data[0] != null) {
-							tax_rate = (tax.charge_type === "Actual") ?
-								format_currency(flt(tax_data[0], tax_amount_precision), company_currency, tax_amount_precision) :
-								(flt(tax_data[0], tax_rate_precision) + "%");
-						}
-						var tax_amount = format_currency(flt(tax_data[1], tax_amount_precision), company_currency,
-							tax_amount_precision);
-
-						item_tax[item_code][tax.name] = [tax_rate, tax_amount];
-					} else {
-						item_tax[item_code][tax.name] = [flt(tax_data, tax_rate_precision) + "%", ""];
-					}
-				});
-			tax_accounts.push([tax.name, tax.account_head]);
-		});
-
-		var headings = $.map([__("Item Name")].concat($.map(tax_accounts, function(head) { return head[1]; })),
-			function(head) { return '<th style="min-width: 100px;">' + (head || "") + "</th>" }).join("\n");
-
-		var distinct_item_names = [];
-		var distinct_items = [];
-		$.each(this.frm.doc["items"] || [], function(i, item) {
-			if(distinct_item_names.indexOf(item.item_code || item.item_name)===-1) {
-				distinct_item_names.push(item.item_code || item.item_name);
-				distinct_items.push(item);
-			}
-		});
-
-		var rows = $.map(distinct_items, function(item) {
-			var item_tax_record = item_tax[item.item_code || item.item_name];
-			if(!item_tax_record) { return null; }
-			return repl("<tr><td>%(item_name)s</td>%(taxes)s</tr>", {
-				item_name: item.item_name,
-				taxes: $.map(tax_accounts, function(head) {
-					return item_tax_record[head[0]] ?
-						"<td>(" + item_tax_record[head[0]][0] + ") " + item_tax_record[head[0]][1] + "</td>" :
-						"<td></td>";
-				}).join("\n")
-			});
-		}).join("\n");
-
-		if(!rows) return "";
-		return '<p><a class="h6 text-muted" href="#" onclick="$(\'.tax-break-up\').toggleClass(\'hide\'); return false;">'
-			+ __("Show tax break-up") + '</a></p>\
-		<div class="tax-break-up hide" style="overflow-x: auto;"><table class="table table-bordered table-hover">\
-			<thead><tr>' + headings + '</tr></thead> \
-			<tbody>' + rows + '</tbody> \
-		</table></div>';
-	},
-
 	validate_company_and_party: function() {
 		var me = this;
 		var valid = true;
@@ -1046,18 +984,6 @@
 		}
 	},
 
-	show_item_wise_taxes: function() {
-		if(this.frm.fields_dict.other_charges_calculation) {
-			var html = this.get_item_wise_taxes_html();
-			if (html) {
-				this.frm.toggle_display("other_charges_calculation", true);
-				$(this.frm.fields_dict.other_charges_calculation.wrapper).html(html);
-			} else {
-				this.frm.toggle_display("other_charges_calculation", false);
-			}
-		}
-	},
-
 	is_recurring: function() {
 		// set default values for recurring documents
 		if(this.frm.doc.is_recurring && this.frm.doc.__islocal) {
diff --git a/erpnext/regional/india/address_template.html b/erpnext/regional/india/address_template.html
index 706c7a4..46879ad 100644
--- a/erpnext/regional/india/address_template.html
+++ b/erpnext/regional/india/address_template.html
@@ -2,7 +2,7 @@
 {% if state %}{{ state }}<br>{% endif -%}
 {% if pincode %}{{ pincode }}<br>{% endif -%}
 {{ country }}<br>
-{% if gstin %}GSTIN: {{ gstin }}<br>{% endif -%}
 {% if phone %}Phone: {{ phone }}<br>{% endif -%}
 {% if fax %}Fax: {{ fax }}<br>{% endif -%}
-{% if email_id %}Email: {{ email_id }}<br>{% endif -%}
\ No newline at end of file
+{% if email_id %}Email: {{ email_id }}<br>{% endif -%}
+{% if gstin %}GSTIN: {{ gstin }}<br>{% endif -%}
\ No newline at end of file
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index a9f3a30..46cfdb8 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -14,6 +14,7 @@
 	add_custom_roles_for_reports()
 	add_hsn_codes()
 	update_address_template()
+	add_print_formats()
 	if not patch:
 		make_fixtures()
 
@@ -69,6 +70,9 @@
 		add_permission(doctype, 'Accounts Manager', 0)
 		add_permission(doctype, 'All', 0)
 
+def add_print_formats():
+	frappe.reload_doc("regional", "print_format", "gst_tax_invoice")
+
 def make_custom_fields():
 	custom_fields = {
 		'Address': [
@@ -80,39 +84,39 @@
 		'Purchase Invoice': [
 			dict(fieldname='supplier_gstin', label='Supplier GSTIN',
 				fieldtype='Data', insert_after='supplier_address',
-				options='supplier_address.gstin'),
+				options='supplier_address.gstin', print_hide=1),
 			dict(fieldname='company_gstin', label='Company GSTIN',
 				fieldtype='Data', insert_after='shipping_address',
-				options='shipping_address.gstin'),
+				options='shipping_address.gstin', print_hide=1),
 		],
 		'Sales Invoice': [
 			dict(fieldname='customer_gstin', label='Customer GSTIN',
 				fieldtype='Data', insert_after='shipping_address',
-				options='shipping_address_name.gstin'),
+				options='shipping_address_name.gstin', print_hide=1),
 			dict(fieldname='company_gstin', label='Company GSTIN',
 				fieldtype='Data', insert_after='company_address',
-				options='company_address.gstin'),
+				options='company_address.gstin', print_hide=1),
 		],
 		'Item': [
-			dict(fieldname='gst_hsn_code', label='GST HSN Code',
+			dict(fieldname='gst_hsn_code', label='HSN/SAC Code',
 				fieldtype='Link', options='GST HSN Code', insert_after='item_group'),
 		],
 		'Sales Invoice Item': [
-			dict(fieldname='gst_hsn_code', label='GST HSN Code',
+			dict(fieldname='gst_hsn_code', label='HSN/SAC Code',
 				fieldtype='Data', options='item_code.gst_hsn_code',
-				insert_after='income_account'),
+				insert_after='description'),
 		],
 		'Purchase Invoice Item': [
-			dict(fieldname='gst_hsn_code', label='GST HSN Code',
+			dict(fieldname='gst_hsn_code', label='HSN/SAC Code',
 				fieldtype='Data', options='item_code.gst_hsn_code',
-				insert_after='expense_account'),
+				insert_after='description'),
 		]
 	}
 
 	for doctype, fields in custom_fields.items():
 		for df in fields:
 			create_custom_field(doctype, df)
-
+			
 def make_fixtures():
 	docs = [
 		{'doctype': 'Salary Component', 'salary_component': 'Professional Tax', 'description': 'Professional Tax', 'type': 'Deduction'},
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index 4d37498..c4acafc 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -16,7 +16,7 @@
 			if doc.state in states:
 				doc.gst_state = doc.state
 
-			if doc.gst_state:
-				state_number = state_numbers[doc.gst_state]
-				if state_number != doc.gstin[:2]:
-					frappe.throw(_("First 2 digits of GSTIN should match with State number {0}").format(state_number))
+		if doc.gst_state:
+			state_number = state_numbers[doc.gst_state]
+			if state_number != doc.gstin[:2]:
+				frappe.throw(_("First 2 digits of GSTIN should match with State number {0}").format(state_number))
diff --git a/erpnext/regional/print_format/__init__.py b/erpnext/regional/print_format/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/regional/print_format/__init__.py
diff --git a/erpnext/regional/print_format/gst_tax_invoice/__init__.py b/erpnext/regional/print_format/gst_tax_invoice/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/regional/print_format/gst_tax_invoice/__init__.py
diff --git a/erpnext/regional/print_format/gst_tax_invoice/gst_tax_invoice.json b/erpnext/regional/print_format/gst_tax_invoice/gst_tax_invoice.json
new file mode 100644
index 0000000..b16aada
--- /dev/null
+++ b/erpnext/regional/print_format/gst_tax_invoice/gst_tax_invoice.json
@@ -0,0 +1,22 @@
+{
+ "align_labels_left": 0, 
+ "creation": "2017-07-04 16:26:21.120187", 
+ "custom_format": 0, 
+ "disabled": 0, 
+ "doc_type": "Sales Invoice", 
+ "docstatus": 0, 
+ "doctype": "Print Format", 
+ "font": "Default", 
+ "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"<div class=\\\"print-heading\\\">\\t\\t\\t\\t<h2>Sales Invoice<br><small>{{ doc.name }}</small>\\t\\t\\t\\t</h2></div>\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"company\", \"label\": \"Company\"}, {\"print_hide\": 0, \"fieldname\": \"company_address_display\", \"label\": \"Company Address\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"posting_date\", \"label\": \"Date\"}, {\"print_hide\": 0, \"fieldname\": \"due_date\", \"label\": \"Payment Due Date\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"options\": \"<hr>\", \"fieldname\": \"_custom_html\", \"fieldtype\": \"HTML\", \"label\": \"Custom HTML\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Address\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"customer_name\", \"label\": \"Customer Name\"}, {\"print_hide\": 0, \"fieldname\": \"address_display\", \"label\": \"Address\"}, {\"print_hide\": 0, \"fieldname\": \"contact_display\", \"label\": \"Contact\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"shipping_address\", \"label\": \"Shipping Address\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"item_code\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"200px\"}, {\"print_hide\": 0, \"fieldname\": \"gst_hsn_code\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"qty\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"uom\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"rate\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"items\", \"label\": \"Items\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"total\", \"label\": \"Total\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"description\", \"print_width\": \"300px\"}], \"print_hide\": 0, \"fieldname\": \"taxes\", \"label\": \"Sales Taxes and Charges\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"grand_total\", \"label\": \"Grand Total\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\", \"label\": \"Rounded Total\"}, {\"print_hide\": 0, \"fieldname\": \"in_words\", \"label\": \"In Words\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"other_charges_calculation\", \"align\": \"left\", \"label\": \"Item-wise Tax Breakup\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Terms\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"terms\", \"label\": \"Terms and Conditions Details\"}]", 
+ "idx": 0, 
+ "line_breaks": 0, 
+ "modified": "2017-07-04 17:13:44.911156", 
+ "modified_by": "Administrator", 
+ "module": "Regional", 
+ "name": "GST Tax Invoice", 
+ "owner": "Administrator", 
+ "print_format_builder": 1, 
+ "print_format_type": "Server", 
+ "show_section_headings": 0, 
+ "standard": "Yes"
+}
\ No newline at end of file