Fixed merge conflict
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 416aaf4..a2dc172 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
 from erpnext.hooks import regional_overrides
 from frappe.utils import getdate
 
-__version__ = '10.1.13'
+__version__ = '10.1.14'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index 2692f3c..fd48faa 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -88,6 +88,9 @@
 		controller = get_payment_gateway_controller(self.payment_gateway)
 		controller.validate_transaction_currency(self.currency)
 
+		if hasattr(controller, 'validate_minimum_transaction_amount'):
+			controller.validate_minimum_transaction_amount(self.currency, self.grand_total)
+
 		return controller.get_payment_url(**{
 			"amount": flt(self.grand_total, self.precision("grand_total")),
 			"title": data.company.encode("utf-8"),
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 0479cd8..e047b6d 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -132,7 +132,7 @@
 		"name": args.name,
 		"serial_no": args.serial_no
 	})
-	if args.get("parenttype") in ("Sales Invoice", "Delivery Note") and args.stock_qty > 0:
+	if args.get("parenttype") in ("Sales Invoice", "Delivery Note") and flt(args.stock_qty) > 0:
 		item_details.serial_no = get_serial_no(args)
 	return item_details
 
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index 15b8cfc..cfcc341 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -751,7 +751,7 @@
    "precision": "",
    "print_hide": 0,
    "print_hide_if_no_value": 0,
-   "read_only": 1,
+   "read_only": 0,
    "remember_last_selected_value": 0,
    "report_hide": 0,
    "reqd": 0,
@@ -4713,7 +4713,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2018-03-13 15:19:54.711885",
+ "modified": "2018-03-16 15:19:54.711885",
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Sales Invoice", 
diff --git a/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json b/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json
index 0377ff9..33af313 100644
--- a/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json
+++ b/erpnext/accounts/print_format/gst_pos_invoice/gst_pos_invoice.json
@@ -7,10 +7,10 @@
  "docstatus": 0, 
  "doctype": "Print Format", 
  "font": "Default", 
- "html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t{% if doc.docstatus == 0 %}\n\t\t<b>{{ doc.status + \" \"+ (doc.select_print_heading or _(\"Invoice\")) }}</b><br>\n\t{% else %}\n\t\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n\t{% endif %}\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t  {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t  {%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.rounded_total -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Rounded Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>", 
+ "html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t{% if doc.docstatus == 0 %}\n\t\t<b>{{ doc.status + \" \"+ (doc.select_print_heading or _(\"Invoice\")) }}</b><br>\n\t{% else %}\n\t\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n\t{% endif %}\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t  {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t  {%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.rounded_total -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Rounded Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Paid Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t{%- if doc.change_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Change Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t{%- endif -%}\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>", 
  "idx": 0, 
  "line_breaks": 0, 
- "modified": "2018-02-07 12:38:36.011318", 
+ "modified": "2018-03-20 14:24:08.167930", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "GST POS Invoice", 
diff --git a/erpnext/accounts/print_format/pos_invoice/pos_invoice.json b/erpnext/accounts/print_format/pos_invoice/pos_invoice.json
index bef6a02..c3450d6 100644
--- a/erpnext/accounts/print_format/pos_invoice/pos_invoice.json
+++ b/erpnext/accounts/print_format/pos_invoice/pos_invoice.json
@@ -6,10 +6,10 @@
  "doc_type": "Sales Invoice", 
  "docstatus": 0, 
  "doctype": "Print Format", 
- "html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.docstatus == 0 %}\n\t\t{{ doc.status + \" \" + (doc.select_print_heading or _(\"Invoice\")) }}<br>\n\t{% else %}\n\t\t{{ doc.select_print_heading or _(\"Invoice\") }}<br>\n\t{% endif %}\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t<b>{{ _(\"Customer\") }}:</b> {{ doc.customer_name }}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.get_formatted(\"rate\") }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t  {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t  {%- endif -%}\n\t\t{%- endfor -%}\n\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.rounded_total -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Rounded Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t{%- if doc.pos_total_qty -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Total Qty\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"pos_total_qty\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t</tbody>\n</table>\n<hr>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>", 
+ "html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.docstatus == 0 %}\n\t\t{{ doc.status + \" \" + (doc.select_print_heading or _(\"Invoice\")) }}<br>\n\t{% else %}\n\t\t{{ doc.select_print_heading or _(\"Invoice\") }}<br>\n\t{% endif %}\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t<b>{{ _(\"Customer\") }}:</b> {{ doc.customer_name }}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.get_formatted(\"rate\") }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t  {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t  {%- endif -%}\n\t\t{%- endfor -%}\n\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.rounded_total -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Rounded Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"rounded_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Paid Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"paid_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- if doc.change_amount -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t\t<b>{{ _(\"Change Amount\") }}</b>\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"change_amount\") }}\n\t\t\t\t</td>\n\t\t\t</tr>\n\t\t{%- endif -%}\n\t\t{%- if doc.pos_total_qty -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Total Qty\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"pos_total_qty\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t</tbody>\n</table>\n<hr>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>", 
  "idx": 1, 
  "line_breaks": 0, 
- "modified": "2018-02-08 05:39:47.280705", 
+ "modified": "2018-03-20 14:24:12.394354", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "POS Invoice", 
diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.js b/erpnext/accounts/report/accounts_payable/accounts_payable.js
index 0c24feb..63ef832 100644
--- a/erpnext/accounts/report/accounts_payable/accounts_payable.js
+++ b/erpnext/accounts/report/accounts_payable/accounts_payable.js
@@ -14,7 +14,13 @@
 			"fieldname":"supplier",
 			"label": __("Supplier"),
 			"fieldtype": "Link",
-			"options": "Supplier"
+			"options": "Supplier",
+			on_change: () => {
+				var supplier = frappe.query_report_filters_by_name.supplier.get_value();
+				frappe.db.get_value('Supplier', supplier, "tax_id", function(value) {
+					frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]);
+				});
+			}
 		},
 		{
 			"fieldname":"report_date",
@@ -52,6 +58,12 @@
 			"fieldtype": "Int",
 			"default": "90",
 			"reqd": 1
+		},
+		{
+			"fieldname":"tax_id",
+			"label": __("Tax Id"),
+			"fieldtype": "Data",
+			"hidden": 1
 		}
 	],
 	onload: function(report) {
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
index d96fc99..10f3262 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
@@ -13,6 +13,11 @@
 
 <h2 class="text-center">{%= __(report.report_name) %}</h2>
 <h4 class="text-center">{%= filters.customer || filters.supplier %} </h4>
+<h6 class="text-center">
+		{% if (filters.tax_id) { %}
+		{%= __("Tax Id: ")%}	{%= filters.tax_id %}
+		{% } %}
+</h6>
 <h5 class="text-center">
 	{%= __(filters.ageing_based_on) %}
 	{%= __("Until") %}
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
index 82f3507..ec1e9f9 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.js
@@ -14,7 +14,13 @@
 			"fieldname":"customer",
 			"label": __("Customer"),
 			"fieldtype": "Link",
-			"options": "Customer"
+			"options": "Customer",
+			on_change: () => {
+				var customer = frappe.query_report_filters_by_name.customer.get_value();
+				frappe.db.get_value('Customer', customer, "tax_id", function(value) {
+					frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]);
+				});
+			}
 		},
 		{
 			"fieldname":"customer_group",
@@ -87,6 +93,12 @@
 			"fieldname":"show_pdc_in_print",
 			"label": __("Show PDC in Print"),
 			"fieldtype": "Check",
+		},
+		{
+			"fieldname":"tax_id",
+			"label": __("Tax Id"),
+			"fieldtype": "Data",
+			"hidden": 1
 		}
 	],
 
diff --git a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
index 845a2c5..08b24fb 100644
--- a/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
+++ b/erpnext/accounts/report/accounts_receivable_summary/accounts_receivable_summary.py
@@ -4,6 +4,7 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _
+from frappe.utils import flt
 from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport
 
 class AccountsReceivableSummary(ReceivablePayableReport):
@@ -88,7 +89,8 @@
 				})
 			)
 			for k in party_total[d.party].keys():
-				party_total[d.party][k] += d.get(k, 0)
+				if k != "currency":
+					party_total[d.party][k] += flt(d.get(k, 0))
 				
 			party_total[d.party].currency = d.currency
 
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.html b/erpnext/accounts/report/general_ledger/general_ledger.html
index 7f50599..9a2205a 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.html
+++ b/erpnext/accounts/report/general_ledger/general_ledger.html
@@ -8,6 +8,13 @@
 		{%= filters.account %}
 	{% } %}
 </h4>
+
+<h6 class="text-center">
+	{% if (filters.tax_id) { %}
+	{%= __("Tax Id: ")%}	{%= filters.tax_id %}
+	{% } %}
+</h6>
+
 <h5 class="text-center">
 	{%= frappe.datetime.str_to_user(filters.from_date) %}
 	{%= __("to") %}
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js
index d6a2aec..b7f96c6 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.js
+++ b/erpnext/accounts/report/general_ledger/general_ledger.js
@@ -87,6 +87,12 @@
 				frappe.db.get_value(party_type, party, fieldname, function(value) {
 					frappe.query_report_filters_by_name.party_name.set_value(value[fieldname]);
 				});
+
+				if (party_type === "Customer" || party_type === "Supplier") {
+					frappe.db.get_value(party_type, party, "tax_id", function(value) {
+						frappe.query_report_filters_by_name.tax_id.set_value(value["tax_id"]);
+					});
+				}
 			}
 		},
 		{
@@ -96,6 +102,12 @@
 			"hidden": 1
 		},
 		{
+			"fieldname":"tax_id",
+			"label": __("Tax Id"),
+			"fieldtype": "Data",
+			"hidden": 1
+		},
+		{
 			"fieldname":"group_by_voucher",
 			"label": __("Group by Voucher"),
 			"fieldtype": "Check",
diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py
index 73bb4dc..cf599a0 100644
--- a/erpnext/accounts/report/purchase_register/purchase_register.py
+++ b/erpnext/accounts/report/purchase_register/purchase_register.py
@@ -43,7 +43,7 @@
 
 		row += [
 			supplier_details.get(inv.supplier), # supplier_type
-			inv.credit_to, inv.mode_of_payment, ", ".join(project),
+			inv.tax_id, inv.credit_to, inv.mode_of_payment, ", ".join(project),
 			inv.bill_no, inv.bill_date, inv.remarks,
 			", ".join(purchase_order), ", ".join(purchase_receipt), company_currency
 		]
@@ -83,7 +83,7 @@
 		columns += additional_table_columns
 
 	columns += [
-		_("Supplier Type") + ":Link/Supplier Type:120", _("Payable Account") + ":Link/Account:120",
+		_("Supplier Type") + ":Link/Supplier Type:120", _("Tax Id") + "::80", _("Payable Account") + ":Link/Account:120",
 		_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
 		_("Bill No") + "::120", _("Bill Date") + ":Date:80", _("Remarks") + "::150",
 		_("Purchase Order") + ":Link/Purchase Order:100",
@@ -143,7 +143,7 @@
 	conditions = get_conditions(filters)
 	return frappe.db.sql("""
 		select
-			name, posting_date, credit_to, supplier, supplier_name, bill_no, bill_date,
+			name, posting_date, credit_to, supplier, supplier_name, tax_id, bill_no, bill_date,
 			remarks, base_net_total, base_grand_total, outstanding_amount,
 			mode_of_payment {0}
 		from `tabPurchase Invoice`
diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py
index 757b760..a318751 100644
--- a/erpnext/accounts/report/sales_register/sales_register.py
+++ b/erpnext/accounts/report/sales_register/sales_register.py
@@ -47,6 +47,7 @@
 		row +=[
 			inv.get("customer_group"),
 			inv.get("territory"),
+			inv.get("tax_id"),
 			inv.debit_to, ", ".join(mode_of_payments.get(inv.name, [])),
 			inv.project, inv.owner, inv.remarks,
 			", ".join(sales_order), ", ".join(delivery_note),", ".join(cost_center),
@@ -89,7 +90,7 @@
 
 	columns +=[
 		_("Customer Group") + ":Link/Customer Group:120", _("Territory") + ":Link/Territory:80",
-		_("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + "::120",
+		_("Tax Id") + "::80", _("Receivable Account") + ":Link/Account:120", _("Mode of Payment") + "::120",
 		_("Project") +":Link/Project:80", _("Owner") + "::150", _("Remarks") + "::150",
 		_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
 		_("Cost Center") + ":Link/Cost Center:100", _("Warehouse") + ":Link/Warehouse:100",
@@ -161,7 +162,7 @@
 	conditions = get_conditions(filters)
 	return frappe.db.sql("""
 		select name, posting_date, debit_to, project, customer, 
-		customer_name, owner, remarks, territory, customer_group,
+		customer_name, owner, remarks, territory, tax_id, customer_group,
 		base_net_total, base_grand_total, base_rounded_total, outstanding_amount {0}
 		from `tabSales Invoice`
 		where docstatus = 1 %s order by posting_date desc, name desc""".format(additional_query_columns or '') %
diff --git a/erpnext/config/education.py b/erpnext/config/education.py
index e4e77f3..5a05a25 100644
--- a/erpnext/config/education.py
+++ b/erpnext/config/education.py
@@ -135,6 +135,10 @@
 					"name": "Assessment Plan Status",
 					"doctype": "Assessment Plan"
 				},
+				{
+					"type": "doctype",
+					"name": "Student Report Generation Tool"
+				}
 			]
 		},
 		{
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index df0fec8..e8e851d 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -285,7 +285,7 @@
 					ifnull((select
 						ifnull(sum(if(%(target_ref_field)s > %(target_field)s, abs(%(target_field)s), abs(%(target_ref_field)s))), 0)
 						/ sum(abs(%(target_ref_field)s)) * 100
-					from `tab%(target_dt)s` where parent="%(name)s"), 0), 2)
+					from `tab%(target_dt)s` where parent="%(name)s" having sum(abs(%(target_ref_field)s)) > 0), 0), 2)
 					%(update_modified)s
 				where name='%(name)s'""" % args)
 
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index b40b986..8b0ea3e 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -252,7 +252,7 @@
 			"company": self.company,
 			"batch_no": cstr(d.get("batch_no")).strip(),
 			"serial_no": d.get("serial_no"),
-			"project": d.get("project"),
+			"project": d.get("project") or self.get('project'),
 			"is_cancelled": self.docstatus==2 and "Yes" or "No"
 		})
 
diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py
index a830e5b..841c2e8 100644
--- a/erpnext/education/doctype/student/student.py
+++ b/erpnext/education/doctype/student/student.py
@@ -22,14 +22,16 @@
 	def update_student_name_in_linked_doctype(self):
 		linked_doctypes = get_linked_doctypes("Student")
 		for d in linked_doctypes:
-			if "student_name" in [f.fieldname for f in frappe.get_meta(d).fields]:
-				frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
-					.format(d, linked_doctypes[d]["fieldname"]),(self.title, self.name))
+			meta = frappe.get_meta(d)
+			if not meta.issingle:
+				if "student_name" in [f.fieldname for f in meta.fields]:
+					frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
+						.format(d, linked_doctypes[d]["fieldname"]),(self.title, self.name))
 
-			if "child_doctype" in linked_doctypes[d].keys() and "student_name" in \
-				[f.fieldname for f in frappe.get_meta(linked_doctypes[d]["child_doctype"]).fields]:
-				frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
-					.format(linked_doctypes[d]["child_doctype"], linked_doctypes[d]["fieldname"]),(self.title, self.name))
+				if "child_doctype" in linked_doctypes[d].keys() and "student_name" in \
+					[f.fieldname for f in frappe.get_meta(linked_doctypes[d]["child_doctype"]).fields]:
+					frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
+						.format(linked_doctypes[d]["child_doctype"], linked_doctypes[d]["fieldname"]),(self.title, self.name))
 
 	def check_unique(self):
 		"""Validates if the Student Applicant is Unique"""
diff --git a/erpnext/education/doctype/student_report_generation_tool/__init__.py b/erpnext/education/doctype/student_report_generation_tool/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/education/doctype/student_report_generation_tool/__init__.py
diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html
new file mode 100644
index 0000000..72772b7
--- /dev/null
+++ b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html
@@ -0,0 +1,371 @@
+<style>
+		@media screen {
+		.print-format-gutter {
+			background-color: #ddd;
+			padding: 15px 0px;
+		}
+		.print-format {
+			background-color: white;
+			box-shadow: 0px 0px 9px rgba(0,0,0,0.5);
+			max-width: 8.3in;
+			min-height: 11.69in;
+			padding: 0.75in;
+			margin: auto;
+		}
+	
+		.print-format.landscape {
+			max-width: 11.69in;
+			padding: 0.2in;
+		}
+	
+		.page-break {
+			padding: 30px 0px;
+			border-bottom: 1px dashed #888;
+		}
+	
+		.page-break:first-child {
+			padding-top: 0px;
+		}
+	
+		.page-break:last-child {
+			border-bottom: 0px;
+		}
+	
+		/* mozilla hack for images in table */
+		body:last-child .print-format td img {
+			width: 100% !important;
+		}
+	
+		@media(max-width: 767px) {
+			.print-format {
+				padding: 0.2in;
+			}
+		}
+	}
+	
+	@media print {
+		.print-format p {
+			margin-left: 1px;
+			margin-right: 1px;
+		}
+	}
+	
+	.data-field {
+		margin-top: 5px;
+		margin-bottom: 5px;
+	}
+	
+	.data-field .value {
+		word-wrap: break-word;
+	}
+	
+	.important .value {
+		font-size: 120%;
+		font-weight: bold;
+	}
+	
+	.important label {
+		line-height: 1.8;
+		margin: 0px;
+	}
+	
+	.table {
+		margin: 20px 0px;
+	}
+	
+	.square-image {
+		width: 100%;
+		height: 0;
+		padding: 50% 0;
+		background-size: contain;
+		/*background-size: cover;*/
+		background-repeat: no-repeat !important;
+		background-position: center center;
+		border-radius: 4px;
+	}
+	
+	.print-item-image {
+		object-fit: contain;
+	}
+	
+	.pdf-variables,
+	.pdf-variable,
+	.visible-pdf {
+		display: none !important;
+	}
+	
+	.print-format {
+		font-size: 9pt;
+		font-family: "Helvetica Neue", Helvetica, Arial, "Open Sans", sans-serif;
+		-webkit-print-color-adjust:exact;
+	}
+	
+	.page-break {
+		page-break-after: always;
+	}
+	
+	.print-heading {
+		border-bottom: 1px solid #aaa;
+		margin-bottom: 10px;
+	}
+	
+	.print-heading h2 {
+		margin: 0px;
+	}
+	.print-heading h4 {
+		margin-top: 5px;
+	}
+	
+	table.no-border, table.no-border td {
+		border: 0px;
+	}
+	
+	.print-format label {
+		/* wkhtmltopdf breaks label into multiple lines when it is inline-block */
+		display: block;
+	}
+	
+	.print-format img {
+		max-width: 100%;
+	}
+	
+	.print-format table td > .primary:first-child {
+		font-weight: bold;
+	}
+	
+	.print-format td, .print-format th {
+		vertical-align: top !important;
+		padding: 6px !important;
+	}
+	
+	.print-format p {
+		margin: 3px 0px 3px;
+	}
+	
+	table td div {
+		
+		/* needed to avoid partial cutting of text between page break in wkhtmltopdf */
+		page-break-inside: avoid !important;
+		
+	}
+	
+	/* hack for webkit specific browser */
+	@media (-webkit-min-device-pixel-ratio:0) {
+		thead, tfoot { display: table-row-group; }
+	}
+	
+	[document-status] {
+		margin-bottom: 5mm;
+	}
+	
+	.signature-img {
+		background: #fff;
+		border-radius: 3px;
+		margin-top: 5px;
+		max-height: 150px;
+	}
+	
+	.print-heading {
+		text-align: right;
+		text-transform: uppercase;
+		color: #666;
+		padding-bottom: 20px;
+		margin-bottom: 20px;
+		border-bottom: 1px solid #d1d8dd;
+	}
+	
+	.print-heading h2 {
+		font-size: 24px;
+	}
+	
+	.print-format th {
+		background-color: #eee !important;
+		border-bottom: 0px !important;
+	}
+	
+	/* modern format: for-test */
+
+	.pbi_avoid {
+		page-break-inside: avoid !important;
+	}
+	.pb_before {
+		page-break-before: always !important;
+	}
+</style>
+
+
+
+<div class="page-break">
+
+	<div id="header-html" class="hidden-pdf">
+
+		{% if letterhead and add_letterhead %}
+			<div class="">{{ letterhead }}</div>
+		{% endif %}
+		<div class="print-heading">
+			<h2>{{ _("Student Report Card") }}<br>
+				<small>{{ doc.student_name }}</small>
+			</h2>
+		</div>
+	</div>
+
+	<div class="row section-break">
+		<div class="col-xs-6 column-break">
+			<div class="row data-field">
+				<div class="col-xs-5">
+					<label>{{ _("Student ID: ") }}</label>
+				</div>
+				<div class="col-xs-7">
+					{{ doc.students[0] }}
+				</div>
+			</div>
+
+			<div class="row data-field">
+				<div class="col-xs-5">
+					<label>{{ _("Student Name: ") }}</label>
+				</div>
+				<div class="col-xs-7">
+					{{ doc.student_name }}
+				</div>
+			</div>
+
+			<div class="row data-field">
+				<div class="col-xs-5">
+					<label>{{ _("Program: ") }}</label>
+				</div>
+				<div class="col-xs-7">
+					{{ doc.program }}
+				</div>
+			</div>
+
+			<div class="row data-field">
+				<div class="col-xs-5">
+					<label>{{ _("Batch: ") }}</label>
+				</div>
+				<div class="col-xs-7">
+					{{ doc.student_batch }}
+				</div>
+			</div>
+		</div>
+
+		<div class="col-xs-6 column-break">
+			<div class="row data-field">
+				<div class="col-xs-5">
+					<label>{{ _("Academic Year: ") }}</label>
+				</div>
+				<div class="col-xs-7">
+					{{ doc.academic_year }}
+				</div>
+			</div>
+
+			{% if doc.academic_term %}
+			<div class="row data-field">
+				<div class="col-xs-5">
+					<label>{{ _("Academic Term: ") }}</label>
+				</div>
+				<div class="col-xs-7">
+					{{ doc.academic_term }}
+				</div>
+			</div>
+			{% endif %}
+
+			<div class="row data-field">
+				<div class="col-xs-5">
+					<label>{{ _("Assessment Group: ") }}</label>
+				</div>
+				<div class="col-xs-7">
+					{{ doc.assessment_group }}
+				</div>
+			</div>
+		</div>
+	</div>
+
+
+{% if doc.show_marks | int %}
+	{% set result_data = 'score' %}
+{% else %}
+	{% set result_data = 'grade' %}
+{% endif %}
+
+
+{% for course in courses %}
+
+<div class="row section-break pbi_avoid">
+	<div class="col-xs-12 column-break">
+
+		<div>
+		<table class="table table-bordered table-condensed">
+			<caption>
+				<div class="row">
+					<div class="col-xs-1">
+						<label>{{ _("Course: ") }}</label>
+					</div>
+					<div class="col-xs-11">
+						{{ course }} ({{ frappe.db.get_value("Course", course, "course_name") }})
+					</div>
+				</div>
+			</caption>
+			<thead>
+				<tr>
+					<th style="width: {{ 650//(assessment_groups|length + 1) }}px">{{ _("Assessment Criteria") }}</th>
+					{% for assessment_group in assessment_groups %}
+					<th> {{ assessment_group }}</th>
+					{% endfor %}
+				</tr>
+			</thead>
+
+			<tbody>
+				{% for criteria in course_criteria[course] %}
+				<tr>
+					<td>{{ criteria }}</td>
+					{% for assessment_group in assessment_groups %}
+						{% if (assessment_result.get(course) and assessment_result.get(course).get(assessment_group) and assessment_result.get(course).get(assessment_group).get(criteria)) %}
+							<td>
+								{{ assessment_result.get(course).get(assessment_group).get(criteria).get(result_data) }}
+								{% if result_data == 'score' %}
+								({{ assessment_result.get(course).get(assessment_group).get(criteria).get('maximum_score') }})
+								{% endif %}
+							</td>
+						{% else %}
+							<td></td>
+						{% endif %}
+					{% endfor %}
+				</tr>
+				{% endfor %}
+			</tbody>
+
+		</table>
+		</div>
+	</div>
+</div>
+
+{% endfor %}
+
+<br>
+
+<div class="row section-break pbi_avoid">
+	<div class="col-xs-6 column-break">	
+		<h4>{{ _("Student Attendance")}}</h4> <br>
+		<div>
+			Present {{ doc.attendance.get("Present") if doc.attendance.get("Present") != None else '0' }} days
+			out of {{ doc.attendance.get("Present") + doc.attendance.get("Absent") }}
+		</div>
+	</div>
+
+	<div class="col-xs-6 column-break">	
+		<h4>{{ _("Parents Teacher Meeting Attendance")}}</h4> <br>
+		<div>
+			Present {{ doc.parents_attendance if doc.parents_attendance != None else '0' }}
+			out of {{ doc.parents_meeting if doc.parents_meeting != None else '0' }}
+		</div>
+	</div>
+</div>
+
+{% if doc.assessment_terms %}
+<div class="row section-break pb_before">
+	<div class="col-xs-12">
+		<p> {{ doc.assessment_terms }} </p>
+	</div>
+</div>
+{% endif %}
+</div>
diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.js b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.js
new file mode 100644
index 0000000..d5103ca
--- /dev/null
+++ b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.js
@@ -0,0 +1,66 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Student Report Generation Tool', {
+	onload: function(frm) {
+		frm.set_query("academic_term",function(){
+			return{
+				"filters":{
+					"academic_year": frm.doc.academic_year
+				}
+			};
+		});
+		frm.set_query("assessment_group", function() {
+			return{
+				filters: {
+					"is_group": 1
+				}
+			};
+		});
+	},
+
+	refresh: function(frm) {
+		frm.disable_save();
+		frm.page.clear_indicator();
+		frm.page.set_primary_action(__('Print Report Card'), () => {
+			let url = "/api/method/erpnext.education.doctype.student_report_generation_tool.student_report_generation_tool.preview_report_card";
+			open_url_post(url, frm.doc, true);
+		});
+	},
+
+	student: function(frm) {
+		if (frm.doc.student) {
+			frappe.call({
+				method:"erpnext.education.api.get_current_enrollment",
+				args: {
+					"student": frm.doc.student,
+					"academic_year": frm.doc.academic_year
+				},
+				callback: function(r) {
+					if(r){
+						$.each(r.message, function(i, d) {
+							if (frm.fields_dict.hasOwnProperty(i)) {
+								frm.set_value(i, d);
+							}
+						});
+					}
+				}
+			});
+		}
+	},
+
+	terms: function(frm) {
+		if(frm.doc.terms) {
+			return frappe.call({
+				method: 'erpnext.setup.doctype.terms_and_conditions.terms_and_conditions.get_terms_and_conditions',
+				args: {
+					template_name: frm.doc.terms,
+					doc: frm.doc
+				},
+				callback: function(r) {
+					frm.set_value("assessment_terms", r.message);
+				}
+			});
+		}
+	}
+});
diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.json b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.json
new file mode 100644
index 0000000..88c59c2
--- /dev/null
+++ b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.json
@@ -0,0 +1,582 @@
+{
+ "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2018-01-15 15:36:32.830069", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "student", 
+   "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": "Student", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Student", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "student_name", 
+   "fieldtype": "Read Only", 
+   "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": "Student Name", 
+   "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": "program", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Program", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Program", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "student_batch", 
+   "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": "Batch", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Student Batch Name", 
+   "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": "include_all_assessment", 
+   "fieldtype": "Check", 
+   "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": "Include All Assessment Group", 
+   "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": "show_marks", 
+   "fieldtype": "Check", 
+   "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": "Show Marks", 
+   "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, 
+   "default": "1", 
+   "fieldname": "add_letterhead", 
+   "fieldtype": "Check", 
+   "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": "Add letterhead", 
+   "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": "column_break_3", 
+   "fieldtype": "Column 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, 
+   "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": "assessment_group", 
+   "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": "Assessment Group", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Assessment Group", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "academic_year", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Academic Year", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Academic Year", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "academic_term", 
+   "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": "Academic Term", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Academic Term", 
+   "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, 
+   "depends_on": "add_letterhead", 
+   "fieldname": "letter_head", 
+   "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": "Letter Head", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Letter Head", 
+   "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": "section_break_5", 
+   "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": "Print Section", 
+   "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": "parents_meeting", 
+   "fieldtype": "Data", 
+   "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": "Total Parents Teacher Meeting", 
+   "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": "parents_attendance", 
+   "fieldtype": "Data", 
+   "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": "Attended by Parents", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "", 
+   "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": "terms", 
+   "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": "Terms", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Terms and Conditions", 
+   "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": "assessment_terms", 
+   "fieldtype": "Text Editor", 
+   "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": "Assessment Terms", 
+   "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
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 0, 
+ "hide_toolbar": 1, 
+ "idx": 0, 
+ "image_view": 0, 
+ "in_create": 0, 
+ "is_submittable": 0, 
+ "issingle": 1, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "modified": "2018-03-20 17:57:53.936119", 
+ "modified_by": "Administrator", 
+ "module": "Education", 
+ "name": "Student Report Generation Tool", 
+ "name_case": "", 
+ "owner": "Administrator", 
+ "permissions": [
+  {
+   "amend": 0, 
+   "apply_user_permissions": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 0, 
+   "email": 0, 
+   "export": 0, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 0, 
+   "read": 1, 
+   "report": 0, 
+   "role": "System Manager", 
+   "set_user_permissions": 0, 
+   "share": 0, 
+   "submit": 0, 
+   "write": 1
+  }
+ ], 
+ "quick_entry": 1, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_changes": 1, 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.py b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.py
new file mode 100644
index 0000000..7b2e007
--- /dev/null
+++ b/erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+from erpnext.education.api import get_grade
+from frappe.utils.pdf import get_pdf
+from erpnext.education.report.course_wise_assessment_report.course_wise_assessment_report import get_formatted_result
+from erpnext.education.report.course_wise_assessment_report.course_wise_assessment_report import get_child_assessment_groups
+
+
+class StudentReportGenerationTool(Document):
+	pass
+
+
+@frappe.whitelist()
+def preview_report_card(**kwargs):
+	doc = frappe._dict(**kwargs)
+	doc.students = [doc.student]
+	if not (doc.student_name and doc.student_batch):
+		program_enrollment = frappe.get_all("Program Enrollment", fields=["student_batch_name", "student_name"],
+			filters={"student": doc.student, "docstatus": ('!=', 2), "academic_year": doc.academic_year})
+		if program_enrollment:
+			doc.batch = program_enrollment[0].student_batch_name
+			doc.student_name = program_enrollment[0].student_name
+
+	# get the assessment result of the selected student
+	values = get_formatted_result(doc, get_course=True, get_all_assessment_groups=doc.include_all_assessment)
+	assessment_result = values.get("assessment_result").get(doc.student)
+	courses = values.get("course_dict")
+	course_criteria = get_courses_criteria(courses)
+
+	# get the assessment group as per the user selection
+	if int(doc.include_all_assessment):
+		assessment_groups = get_child_assessment_groups(doc.assessment_group)
+	else:
+		assessment_groups = [doc.assessment_group]
+
+	# get the attendance of the student for that peroid of time.
+	doc.attendance = get_attendance_count(doc.students[0], doc.academic_year, doc.academic_term)
+
+	template = "erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html"
+	base_template_path = "frappe/www/printview.html"
+
+	from frappe.www.printview import get_letter_head
+	letterhead = get_letter_head(frappe._dict({"letter_head": doc.letterhead}), not doc.add_letterhead)
+
+	html = frappe.render_template(template,
+		{
+			"doc": doc,
+			"assessment_result": assessment_result,
+			"courses": courses,
+			"assessment_groups": assessment_groups,
+			"course_criteria": course_criteria,
+			"letterhead": letterhead.content,
+			"add_letterhead": int(doc.add_letterhead) if int(doc.add_letterhead) else 0
+		})
+	final_template = frappe.render_template(base_template_path, {"body": html, "title": "Report Card"})
+
+	frappe.response.filename = "Report Card " + doc.students[0] + ".pdf"
+	frappe.response.filecontent = get_pdf(final_template)
+	frappe.response.type = "download"
+
+
+def get_courses_criteria(courses):
+	course_criteria = frappe._dict()
+	for course in courses:
+		course_criteria[course] = [d.assessment_criteria for d in frappe.get_all("Course Assessment Criteria",
+			fields=["assessment_criteria"], filters={"parent": course})]
+	return course_criteria
+
+
+def get_attendance_count(student, academic_year, academic_term=None):
+	if academic_year:
+		from_date, to_date = frappe.db.get_value("Academic Year", academic_year, ["year_start_date", "year_end_date"])
+	elif academic_term:
+		from_date, to_date = frappe.db.get_value("Academic Term", academic_term, ["term_start_date", "term_end_date"])
+	if from_date and to_date:
+		attendance = dict(frappe.db.sql('''select status, count(student) as no_of_days
+			from `tabStudent Attendance` where student = %s 
+			and date between %s and %s group by status''',
+			(student, from_date, to_date)))
+		if "Absent" not in attendance.keys():
+			attendance["Absent"] = 0
+		if "Present" not in attendance.keys():
+			attendance["Present"] = 0
+		return attendance
+	else:
+		frappe.throw("Provide the academic year and set the starting and ending date.") 
\ No newline at end of file
diff --git a/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.js b/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.js
new file mode 100644
index 0000000..10be092
--- /dev/null
+++ b/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Student Report Generation Tool", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Student Report Generation Tool
+		() => frappe.tests.make('Student Report Generation Tool', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.py b/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.py
new file mode 100644
index 0000000..4178166
--- /dev/null
+++ b/erpnext/education/doctype/student_report_generation_tool/test_student_report_generation_tool.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestStudentReportGenerationTool(unittest.TestCase):
+	pass
diff --git a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py
index a50ad7b..ce58148 100644
--- a/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py
+++ b/erpnext/education/report/course_wise_assessment_report/course_wise_assessment_report.py
@@ -60,7 +60,7 @@
 	return columns, data, None, chart
 
 
-def get_formatted_result(args, get_assessment_criteria=False, get_course=False):
+def get_formatted_result(args, get_assessment_criteria=False, get_course=False, get_all_assessment_groups=False):
 	cond, cond1, cond2, cond3, cond4 = " ", " ", " ", " ", " "
 	args_list = [args.academic_year]
 
@@ -77,15 +77,9 @@
 		args_list.append(args.student_group)
 
 	create_total_dict = False
-	group_type = frappe.get_value("Assessment Group", args.assessment_group, "is_group")
-	if group_type:
-		from frappe.desk.treeview import get_children
-		assessment_groups = [d.get("value") for d in get_children("Assessment Group",
-			args.assessment_group) if d.get("value") and not d.get("expandable")]
-		cond3 = " and ar.assessment_group in (%s)"%(', '.join(['%s']*len(assessment_groups)))
-	else:
-		assessment_groups = [args.assessment_group]
-		cond3 = " and ar.assessment_group=%s"
+
+	assessment_groups = get_child_assessment_groups(args.assessment_group)
+	cond3 = " and ar.assessment_group in (%s)"%(', '.join(['%s']*len(assessment_groups)))
 	args_list += assessment_groups
 
 	if args.students:
@@ -156,6 +150,9 @@
 
 		# create the total of all the assessment groups criteria-wise
 		elif create_total_dict:
+			if get_all_assessment_groups:
+				formatted_assessment_result[result.student][result.course][result.assessment_group]\
+					[result.assessment_criteria] = assessment_criteria_details				
 			if not formatted_assessment_result[result.student][result.course][args.assessment_group]:
 				formatted_assessment_result[result.student][result.course][args.assessment_group] = defaultdict(dict)
 				formatted_assessment_result[result.student][result.course][args.assessment_group]\
@@ -238,3 +235,15 @@
 		},
 		"type": 'bar',
 	}
+
+
+def get_child_assessment_groups(assessment_group):
+	assessment_groups = []
+	group_type = frappe.get_value("Assessment Group", assessment_group, "is_group")
+	if group_type:
+		from frappe.desk.treeview import get_children
+		assessment_groups = [d.get("value") for d in get_children("Assessment Group",
+			assessment_group) if d.get("value") and not d.get("expandable")]
+	else:
+		assessment_groups = [assessment_group]
+	return assessment_groups
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 328a7e4..fca4134 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -510,3 +510,7 @@
 erpnext.patches.v10_0.set_auto_created_serial_no_in_stock_entry
 erpnext.patches.v10_0.update_territory_and_customer_group
 erpnext.patches.v10_0.update_warehouse_address_details
+erpnext.patches.v10_0.update_reserved_qty_for_purchase_order
+erpnext.patches.v10_0.update_hub_connector_domain
+erpnext.patches.v10_0.set_student_party_type
+erpnext.patches.v10_0.update_project_in_sle
diff --git a/erpnext/patches/v10_0/set_student_party_type.py b/erpnext/patches/v10_0/set_student_party_type.py
new file mode 100644
index 0000000..6ac1451
--- /dev/null
+++ b/erpnext/patches/v10_0/set_student_party_type.py
@@ -0,0 +1,7 @@
+import frappe
+
+def execute():
+	if not frappe.db.exists("Party Type", "Student"):
+		party = frappe.new_doc("Party Type")
+		party.party_type = "Student"
+		party.save()
diff --git a/erpnext/patches/v10_0/update_hub_connector_domain.py b/erpnext/patches/v10_0/update_hub_connector_domain.py
new file mode 100644
index 0000000..808ae77
--- /dev/null
+++ b/erpnext/patches/v10_0/update_hub_connector_domain.py
@@ -0,0 +1,9 @@
+import frappe
+
+def execute():
+	if frappe.db.table_exists("Data Migration Connector"):
+		frappe.db.sql("""
+			UPDATE `tabData Migration Connector`
+			SET hostname = 'https://hubmarket.org'
+			WHERE connector_name = 'Hub Connector'
+		""")
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/update_project_in_sle.py b/erpnext/patches/v10_0/update_project_in_sle.py
new file mode 100644
index 0000000..08c64f1
--- /dev/null
+++ b/erpnext/patches/v10_0/update_project_in_sle.py
@@ -0,0 +1,15 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	for doctype in ['Sales Invoice', 'Delivery Note', 'Stock Entry']:
+		frappe.db.sql(""" update
+				`tabStock Ledger Entry` sle, `tab{0}` parent_doc
+			set
+				sle.project = parent_doc.project
+			where
+				sle.voucher_no = parent_doc.name and sle.voucher_type = %s and sle.project is null
+				and parent_doc.project is not null and parent_doc.project != ''""".format(doctype), doctype)
diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json
index 7b4d718..8b41adc 100644
--- a/erpnext/projects/doctype/project/project.json
+++ b/erpnext/projects/doctype/project/project.json
@@ -1125,6 +1125,36 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "total_consumed_material_cost", 
+   "fieldtype": "Currency", 
+   "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": "Total Consumed Material Cost  (via Stock Entry)", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 1, 
+   "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": "cost_center", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -1626,7 +1656,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 4, 
- "modified": "2018-01-29 11:48:21.156697", 
+ "modified": "2018-03-22 11:44:38.723507", 
  "modified_by": "Administrator", 
  "module": "Projects", 
  "name": "Project", 
diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py
index 6455be0..2d2a18b 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.py
+++ b/erpnext/setup/doctype/naming_series/naming_series.py
@@ -20,7 +20,7 @@
 			+ frappe.db.sql_list("""select dt from `tabCustom Field`
 				where fieldname='naming_series'""")))
 
-		doctypes = list(set(get_doctypes_with_read()) | set(doctypes))
+		doctypes = list(set(get_doctypes_with_read()).intersection(set(doctypes)))
 		prefixes = ""
 		for d in doctypes:
 			options = ""
@@ -47,6 +47,7 @@
 
 	def update_series(self, arg=None):
 		"""update series list"""
+		self.validate_series_set()
 		self.check_duplicate()
 		series_list = self.set_options.split("\n")
 
@@ -60,6 +61,10 @@
 
 		return self.get_transactions()
 
+	def validate_series_set(self):
+		if self.select_doc_for_series and not self.set_options:
+			frappe.throw(_("Please set the series to be used."))
+
 	def set_series_for(self, doctype, ol):
 		options = self.scrub_options_list(ol)
 
diff --git a/erpnext/setup/setup_wizard/operations/install_fixtures.py b/erpnext/setup/setup_wizard/operations/install_fixtures.py
index 2aa4d5e..045dca0 100644
--- a/erpnext/setup/setup_wizard/operations/install_fixtures.py
+++ b/erpnext/setup/setup_wizard/operations/install_fixtures.py
@@ -217,6 +217,7 @@
 		{'doctype': "Party Type", "party_type": "Employee"},
 		{'doctype': "Party Type", "party_type": "Member"},
 		{'doctype': "Party Type", "party_type": "Shareholder"},
+		{'doctype': "Party Type", "party_type": "Student"},
 
 		{'doctype': "Opportunity Type", "name": "Hub"},
 		{'doctype': "Opportunity Type", "name": _("Sales")},
diff --git a/erpnext/stock/dashboard/item_dashboard.js b/erpnext/stock/dashboard/item_dashboard.js
index 2748436..dff65af 100644
--- a/erpnext/stock/dashboard/item_dashboard.js
+++ b/erpnext/stock/dashboard/item_dashboard.js
@@ -18,12 +18,12 @@
 
 		// move
 		this.content.on('click', '.btn-move', function() {
-			erpnext.stock.move_item($(this).attr('data-item'), $(this).attr('data-warehouse'),
+			erpnext.stock.move_item(unescape($(this).attr('data-item')), $(this).attr('data-warehouse'),
 				null, $(this).attr('data-actual_qty'), null, function() { me.refresh(); });
 		});
 
 		this.content.on('click', '.btn-add', function() {
-			erpnext.stock.move_item($(this).attr('data-item'), null, $(this).attr('data-warehouse'),
+			erpnext.stock.move_item(unescape($(this).attr('data-item')), null, $(this).attr('data-warehouse'),
 				$(this).attr('data-actual_qty'), $(this).attr('data-rate'),
 				function() { me.refresh(); });
 		});
diff --git a/erpnext/stock/dashboard/item_dashboard_list.html b/erpnext/stock/dashboard/item_dashboard_list.html
index e0b3431..5a3fa2e 100644
--- a/erpnext/stock/dashboard/item_dashboard_list.html
+++ b/erpnext/stock/dashboard/item_dashboard_list.html
@@ -45,12 +45,12 @@
 				<button class="btn btn-default btn-xs btn-move"
 					data-warehouse="{{ d.warehouse }}"
 					data-actual_qty="{{ d.actual_qty }}"
-					data-item="{{ d.item_code }}">{{ __("Move") }}</a>
+					data-item="{{ escape(d.item_code) }}">{{ __("Move") }}</a>
 				{% endif %}
 				<button style="margin-left: 7px;" class="btn btn-default btn-xs btn-add"
 					data-warehouse="{{ d.warehouse }}"
 					data-actual_qty="{{ d.actual_qty }}"
-					data-item="{{ d.item_code }}"
+					data-item="{{ escape(d.item_code) }}"
 					data-rate="{{ d.valuation_rate }}">{{ __("Add") }}</a>
 			</div>
 			{% endif %}
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 5f16d8b..8886f33 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -309,7 +309,8 @@
 
 		for dn in set(updated_delivery_notes):
 			dn_doc = self if (dn == self.name) else frappe.get_doc("Delivery Note", dn)
-			dn_doc.update_billing_percentage(update_modified=update_modified)
+			if dn_doc.net_total > 0:
+				dn_doc.update_billing_percentage(update_modified=update_modified)
 
 		self.load_from_db()
 
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 9da35aa..4f9cefe 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -77,6 +77,7 @@
 		if self.purchase_order and self.purpose == "Subcontract":
 			self.update_purchase_order_supplied_items()
 		self.make_gl_entries()
+		self.update_cost_in_project()
 
 	def on_cancel(self):
 		self.update_stock_ledger()
@@ -100,6 +101,18 @@
 			item.transfer_qty = flt(flt(item.qty) * flt(item.conversion_factor),
 				self.precision("transfer_qty", item))
 
+	def update_cost_in_project(self):
+		if self.project:
+			amount = frappe.db.sql(""" select ifnull(sum(sed.amount), 0)
+				from
+					`tabStock Entry` se, `tabStock Entry Detail` sed
+				where
+					se.docstatus = 1 and se.project = %s and sed.parent = se.name
+					and (sed.t_warehouse is null or sed.t_warehouse = '')""", self.project, as_list=1)
+
+			if amount:
+				frappe.db.set_value('Project', self.project, 'total_consumed_material_cost', amount[0][0])
+
 	def validate_item(self):
 		stock_items = self.get_stock_items()
 		serialized_items = self.get_serialized_items()
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.js b/erpnext/stock/report/stock_ledger/stock_ledger.js
index e95f5ca..d4f5ab5 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.js
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.js
@@ -59,6 +59,12 @@
 			"fieldname":"voucher_no",
 			"label": __("Voucher #"),
 			"fieldtype": "Data"
+		},
+		{
+			"fieldname":"project",
+			"label": __("Project"),
+			"fieldtype": "Link",
+			"options": "Project"
 		}
 	]
 }
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index e436132..305702e 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -24,7 +24,7 @@
 			item_detail.stock_uom, sle.actual_qty, sle.qty_after_transaction,
 			(sle.incoming_rate if sle.actual_qty > 0 else 0.0),
 			sle.valuation_rate, sle.stock_value, sle.voucher_type, sle.voucher_no,
-			sle.batch_no, sle.serial_no, sle.company])
+			sle.batch_no, sle.serial_no, sle.project, sle.company])
 
 	return columns, data
 
@@ -45,6 +45,7 @@
 		_("Voucher #") + ":Dynamic Link/" + _("Voucher Type") + ":100",
 		_("Batch") + ":Link/Batch:100",
 		_("Serial #") + ":Link/Serial No:100",
+		_("Project") + ":Link/Project:100",
 		{"label": _("Company"), "fieldtype": "Link", "width": 110,
 			"options": "company", "fieldname": "company"}
 	]
@@ -54,7 +55,7 @@
 def get_stock_ledger_entries(filters):
 	return frappe.db.sql("""select concat_ws(" ", posting_date, posting_time) as date,
 			item_code, warehouse, actual_qty, qty_after_transaction, incoming_rate, valuation_rate,
-			stock_value, voucher_type, voucher_no, batch_no, serial_no, company
+			stock_value, voucher_type, voucher_no, batch_no, serial_no, company, project
 		from `tabStock Ledger Entry` sle
 		where company = %(company)s and
 			posting_date between %(from_date)s and %(to_date)s
@@ -96,6 +97,8 @@
 		conditions.append("voucher_no=%(voucher_no)s")
 	if filters.get("batch_no"):
 		conditions.append("batch_no=%(batch_no)s")
+	if filters.get("project"):
+		conditions.append("project=%(project)s")
 
 	return "and {}".format(" and ".join(conditions)) if conditions else ""