resolved merge conflicts
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/import_from_openerp.py b/erpnext/accounts/doctype/account/chart_of_accounts/import_from_openerp.py
index cb95bd1..9e3388b 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/import_from_openerp.py
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/import_from_openerp.py
@@ -4,7 +4,7 @@
 """
 Import chart of accounts from OpenERP sources
 """
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 
 import os, json
 import ast
@@ -229,7 +229,7 @@
 
 		filename = src["id"][5:] + "_" + chart_id
 
-		print "building " + filename
+		print("building " + filename)
 		chart = {}
 		chart["name"] = src["name"]
 		chart["country_code"] = src["id"][5:]
diff --git a/erpnext/accounts/doctype/bank_reconciliation/test_bank_reconciliation.js b/erpnext/accounts/doctype/bank_reconciliation/test_bank_reconciliation.js
new file mode 100644
index 0000000..f52f6fb
--- /dev/null
+++ b/erpnext/accounts/doctype/bank_reconciliation/test_bank_reconciliation.js
@@ -0,0 +1,22 @@
+QUnit.module('Account');
+
+QUnit.test("test Bank Reconciliation", function(assert) {
+	assert.expect(0);
+	let done = assert.async();
+	frappe.run_serially([
+		() => frappe.set_route('Form', 'Bank Reconciliation'),
+		() => cur_frm.set_value('bank_account','Cash - FT'),
+		() => frappe.click_button('Get Payment Entries'),
+		() => {
+			for(var i=0;i<=cur_frm.doc.payment_entries.length-1;i++){
+				cur_frm.doc.payment_entries[i].clearance_date = frappe.datetime.add_days(frappe.datetime.now_date(), 2);
+			}
+		},
+		() => {cur_frm.refresh_fields('payment_entries');},
+		() => frappe.click_button('Update Clearance Date'),
+		() => frappe.timeout(0.5),
+		() => frappe.click_button('Close'),
+		() => done()
+	]);
+});
+
diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.js b/erpnext/accounts/doctype/journal_entry/test_journal_entry.js
new file mode 100644
index 0000000..28ccd95
--- /dev/null
+++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.js
@@ -0,0 +1,39 @@
+QUnit.module('Journal Entry');
+
+QUnit.test("test journal entry", function(assert) {
+	assert.expect(2);
+	let done = assert.async();
+	frappe.run_serially([
+		() => {
+			return frappe.tests.make('Journal Entry', [
+				{posting_date:frappe.datetime.add_days(frappe.datetime.nowdate(), 0)},
+				{accounts: [
+					[
+						{'account':'Debtors - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+						{'party_type':'Customer'},
+						{'party':'Test Customer 1'},
+						{'credit_in_account_currency':1000},
+						{'is_advance':'Yes'},
+					],
+					[
+						{'account':'HDFC - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+						{'debit_in_account_currency':1000},
+					]
+				]},
+				{cheque_no:1234},
+				{cheque_date: frappe.datetime.add_days(frappe.datetime.nowdate(), -1)},
+				{user_remark: 'Test'},
+			]);
+		},
+		() => cur_frm.save(),
+		() => {
+			// get_item_details
+			assert.ok(cur_frm.doc.total_debit==1000, "total debit correct");
+			assert.ok(cur_frm.doc.total_credit==1000, "total credit correct");
+		},
+		() => frappe.tests.click_button('Submit'),
+		() => frappe.tests.click_button('Yes'),
+		() => frappe.timeout(0.3),
+		() => done()
+	]);
+});
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 7bb9a52..9832c05 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -393,7 +393,7 @@
 			if self.payment_type=="Receive":
 				against_account = self.paid_to
 			else:
-				 against_account = self.paid_from
+				against_account = self.paid_from
 
 
 			party_gl_dict = self.get_gl_dict({
diff --git a/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js
new file mode 100644
index 0000000..a4ef0ca
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js
@@ -0,0 +1,29 @@
+QUnit.module('Accounts');
+
+QUnit.test("test payment entry", function(assert) {
+	assert.expect(1);
+	let done = assert.async();
+	frappe.run_serially([
+		() => {
+			return frappe.tests.make('Payment Entry', [
+				{payment_type:'Receive'},
+				{mode_of_payment:'Cash'},
+				{party_type:'Customer'},
+				{party:'Test Customer 3'},
+				{paid_amount:675},
+				{reference_no:123},
+				{reference_date: frappe.datetime.add_days(frappe.datetime.nowdate(), 0)},
+			]);
+		},
+		() => cur_frm.save(),
+		() => {
+			// get_item_details
+			assert.ok(cur_frm.doc.total_allocated_amount==675, "Allocated AmountCorrect");
+		},
+		() => frappe.tests.click_button('Submit'),
+		() => frappe.tests.click_button('Yes'),
+		() => frappe.timeout(0.3),
+		() => done()
+	]);
+});
+
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 96d617e..780edd8 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -109,7 +109,7 @@
 
 		if not self.recurring_id:
 			frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
-			 	self.company, self.base_grand_total, self)
+				self.company, self.base_grand_total, self)
 
 		self.check_prev_docstatus()
 
diff --git a/erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment_request.js b/erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment_request.js
new file mode 100644
index 0000000..7abfb41
--- /dev/null
+++ b/erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment_request.js
@@ -0,0 +1,52 @@
+QUnit.module('Sales Invoice');
+
+QUnit.test("test sales Invoice with payment request", function(assert) {
+	assert.expect(4);
+	let done = assert.async();
+	frappe.run_serially([
+		() => {
+			return frappe.tests.make('Sales Invoice', [
+				{customer: 'Test Customer 1'},
+				{items: [
+					[
+						{'qty': 5},
+						{'item_code': 'Test Product 1'},
+					]
+				]},
+				{update_stock:1},
+				{customer_address: 'Test1-Billing'},
+				{shipping_address_name: 'Test1-Shipping'},
+				{contact_person: 'Contact 1-Test Customer 1'},
+				{taxes_and_charges: 'TEST In State GST'},
+				{tc_name: 'Test Term 1'},
+				{terms: 'This is Test'}
+			]);
+		},
+		() => cur_frm.save(),
+		() => {
+			// get_item_details
+			assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
+			// get tax details
+			assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
+			// grand_total Calculated
+			assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
+
+		},
+		() => frappe.tests.click_button('Submit'),
+		() => frappe.tests.click_button('Yes'),
+		() => frappe.timeout(2),
+		() => frappe.tests.click_button('Close'),
+		() => frappe.tests.click_button('Make'),
+		() => frappe.tests.click_link('Payment Request'),
+		() => frappe.timeout(0.2),
+		() => { cur_frm.set_value('print_format','GST Tax Invoice');},
+		() => { cur_frm.set_value('email_to','test@gmail.com');},
+		() => cur_frm.save(),
+		() => {
+			// get payment details
+			assert.ok(cur_frm.doc.grand_total==590, "grand total Correct");
+		},
+		() => done()
+	]);
+});
+
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
index 7faaf11..a47df2d 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
@@ -54,13 +54,15 @@
 			d.idx = i + 1
 
 	def validate_overlapping_shipping_rule_conditions(self):
-		def overlap_exists_between((x1, x2), (y1, y2)):
+		def overlap_exists_between(num_range1, num_range2):
 			"""
-				(x1, x2) and (y1, y2) are two ranges
-				if condition x = 100 to 300
-				then condition y can only be like 50 to 99 or 301 to 400
+				num_range1 and num_range2 are two ranges
+				ranges are represented as a tuple e.g. range 100 to 300 is represented as (100, 300)
+				if condition num_range1 = 100 to 300
+				then condition num_range2 can only be like 50 to 99 or 301 to 400
 				hence, non-overlapping condition = (x1 <= x2 < y1 <= y2) or (y1 <= y2 < x1 <= x2)
 			"""
+			(x1, x2), (y1, y2) = num_range1, num_range2
 			separate = (x1 <= x2 <= y1 <= y2) or (y1 <= y2 <= x1 <= x2)
 			return (not separate)
 
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
index 853b805..8fafce6 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
@@ -10,15 +10,15 @@
 	<thead>
 		<tr>
 			{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
-				<th style="width: 15%">{%= __("Date") %}</th>
-				<th style="width: 15%">{%= __("Ref") %}</th>
-				<th style="width: 40%">{%= __("Party") %}</th>
-				<th style="width: 15%">{%= __("Invoiced Amount") %}</th>
-				<th style="width: 15%">{%= __("Paid Amount") %}</th>
-				<th style="width: 15%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
-				<th style="width: 15%">{%= __("Outstanding Amount") %}</th>
+				<th style="width: 14%">{%= __("Date") %}</th>
+				<th style="width: 16%">{%= __("Ref") %}</th>
+				<th style="width: 30%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
+				<th style="width: 10%">{%= __("Invoiced Amount") %}</th>
+				<th style="width: 10%">{%= __("Paid Amount") %}</th>
+				<th style="width: 10%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
+				<th style="width: 10%">{%= __("Outstanding Amount") %}</th>
 			{% } else { %}
-				<th style="width: 40%">{%= __("Party") %}</th>
+				<th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
 				<th style="width: 15%">{%= __("Total Invoiced Amount") %}</th>
 				<th style="width: 15%">{%= __("Total Paid Amount") %}</th>
 				<th style="width: 15%">{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %}</th>
@@ -34,8 +34,12 @@
 					<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
 					<td>{%= data[i][__("Voucher Type")] %}
 						<br>{%= data[i][__("Voucher No")] %}</td>
-					<td>{%= data[i][__("Customer Name")] || data[i][__("Customer")] || data[i][__("Supplier Name")] || data[i][__("Supplier")] %}
-						<br>{%= __("Remarks") %}: {%= data[i][__("Remarks")] %}</td>
+					<td>
+						{% if(!(filters.customer || filters.supplier)) { %}
+							{%= data[i][__("Customer Name")] || data[i][__("Customer")] || data[i][__("Supplier Name")] || data[i][__("Supplier")] %}<br>{%= __("Remarks") %}: 
+						{% } %}
+						{%= data[i][__("Remarks")] %}
+					</td>
 					<td style="text-align: right">
 						{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"]) %}</td>
 					<td style="text-align: right">
@@ -59,8 +63,13 @@
 			{% } else { %}
 				{% if(data[i][__("Customer")] || data[i][__("Supplier")]|| "&nbsp;") { %}
 					{% if((data[i][__("Customer")] || data[i][__("Supplier")]) != __("'Total'")) { %}
-						<td>{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
-						<br>{%= __("Remarks") %}: {%= data[i][__("Remarks")] %}</td>
+						<td>
+							{% if(!(filters.customer || filters.supplier)) { %}
+								{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
+								<br>{%= __("Remarks") %}: 
+							{% } %}
+							{%= data[i][__("Remarks")] %}
+						</td>
 					{% } else { %}
 						<td><b>{%= __("Total") %}</b></td>
 					{% } %}
diff --git a/erpnext/controllers/website_list_for_contact.py b/erpnext/controllers/website_list_for_contact.py
index 73badc2..65360ec 100644
--- a/erpnext/controllers/website_list_for_contact.py
+++ b/erpnext/controllers/website_list_for_contact.py
@@ -68,8 +68,8 @@
 	if txt:
 		if meta.get_field('items'):
 			if meta.get_field('items').options:
-			   child_doctype = meta.get_field('items').options
-			   for item in frappe.get_all(child_doctype, {"item_name": ['like', "%" + txt + "%"]}):
+				child_doctype = meta.get_field('items').options
+				for item in frappe.get_all(child_doctype, {"item_name": ['like', "%" + txt + "%"]}):
 					child = frappe.get_doc(child_doctype, item.name)
 					or_filters.append([doctype, "name", "=", child.parent])
 
diff --git a/erpnext/crm/doctype/lead/lead.json b/erpnext/crm/doctype/lead/lead.json
index e7c2d33..c9d04ac 100644
--- a/erpnext/crm/doctype/lead/lead.json
+++ b/erpnext/crm/doctype/lead/lead.json
@@ -80,36 +80,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "salutation", 
-   "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": "Salutation", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Salutation", 
-   "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_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "fieldname": "lead_name", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -141,21 +111,21 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "gender", 
-   "fieldtype": "Link", 
+   "fieldname": "company_name", 
+   "fieldtype": "Data", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_global_search": 0, 
-   "in_list_view": 0, 
+   "in_list_view": 1, 
    "in_standard_filter": 0, 
-   "label": "Gender", 
+   "label": "Organization Name", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Gender", 
+   "oldfieldname": "company_name", 
+   "oldfieldtype": "Data", 
    "permlevel": 0, 
-   "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
    "read_only": 0, 
@@ -266,6 +236,37 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "gender", 
+   "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": "Gender", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Gender", 
+   "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": "", 
    "fieldname": "source", 
    "fieldtype": "Link", 
@@ -299,36 +300,6 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "company_name", 
-   "fieldtype": "Data", 
-   "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": "Organization Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "company_name", 
-   "oldfieldtype": "Data", 
-   "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_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
    "depends_on": "eval:doc.source == 'Existing Customer'", 
    "fieldname": "customer", 
    "fieldtype": "Link", 
@@ -435,6 +406,7 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
+   "label": "Follow Up", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -514,11 +486,12 @@
   {
    "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
-   "bold": 0, 
+   "bold": 1, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "contact_by", 
-   "fieldtype": "Link", 
+   "description": "", 
+   "fieldname": "contact_date", 
+   "fieldtype": "Datetime", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -526,12 +499,11 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Next Contact By", 
+   "label": "Next Contact Date", 
    "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "contact_by", 
-   "oldfieldtype": "Link", 
-   "options": "User", 
+   "no_copy": 1, 
+   "oldfieldname": "contact_date", 
+   "oldfieldtype": "Date", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
@@ -550,9 +522,8 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "description": "Add to calendar on this date", 
-   "fieldname": "contact_date", 
-   "fieldtype": "Datetime", 
+   "fieldname": "contact_by", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -560,11 +531,12 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Next Contact Date", 
+   "label": "Next Contact By", 
    "length": 0, 
-   "no_copy": 1, 
-   "oldfieldname": "contact_date", 
-   "oldfieldtype": "Date", 
+   "no_copy": 0, 
+   "oldfieldname": "contact_by", 
+   "oldfieldtype": "Link", 
+   "options": "User", 
    "permlevel": 0, 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
@@ -732,6 +704,37 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "salutation", 
+   "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": "Salutation", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Salutation", 
+   "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": "mobile_no", 
    "fieldtype": "Data", 
    "hidden": 0, 
@@ -1144,7 +1147,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-06-22 14:29:12.700000", 
+ "modified": "2017-08-21 02:28:21.581948", 
  "modified_by": "Administrator", 
  "module": "CRM", 
  "name": "Lead", 
diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json
index dc8b3e7..89eb191 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.json
+++ b/erpnext/crm/doctype/opportunity/opportunity.json
@@ -423,6 +423,164 @@
    "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
+   "collapsible": 1, 
+   "collapsible_depends_on": "contact_by", 
+   "columns": 0, 
+   "fieldname": "next_contact", 
+   "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": "Follow Up", 
+   "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, 
+   "description": "", 
+   "fieldname": "contact_by", 
+   "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": 1, 
+   "label": "Next Contact By", 
+   "length": 0, 
+   "no_copy": 0, 
+   "oldfieldname": "contact_by", 
+   "oldfieldtype": "Link", 
+   "options": "User", 
+   "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, 
+   "width": "75px"
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "description": "", 
+   "fieldname": "contact_date", 
+   "fieldtype": "Datetime", 
+   "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": "Next Contact Date", 
+   "length": 0, 
+   "no_copy": 0, 
+   "oldfieldname": "contact_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": "column_break2", 
+   "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, 
+   "oldfieldtype": "Column Break", 
+   "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, 
+   "width": "50%"
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "to_discuss", 
+   "fieldtype": "Small Text", 
+   "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": "To Discuss", 
+   "length": 0, 
+   "no_copy": 1, 
+   "oldfieldname": "to_discuss", 
+   "oldfieldtype": "Small Text", 
+   "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, 
    "depends_on": "with_items", 
@@ -435,7 +593,7 @@
    "in_global_search": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "", 
+   "label": "Items", 
    "length": 0, 
    "no_copy": 0, 
    "oldfieldtype": "Section Break", 
@@ -990,164 +1148,6 @@
    "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
-   "collapsible": 1, 
-   "collapsible_depends_on": "contact_by", 
-   "columns": 0, 
-   "fieldname": "next_contact", 
-   "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": "Next Contact", 
-   "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, 
-   "description": "Your sales person who will contact the customer in future", 
-   "fieldname": "contact_by", 
-   "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": 1, 
-   "label": "Next Contact By", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "contact_by", 
-   "oldfieldtype": "Link", 
-   "options": "User", 
-   "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, 
-   "width": "75px"
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "description": "Your sales person will get a reminder on this date to contact the customer", 
-   "fieldname": "contact_date", 
-   "fieldtype": "Datetime", 
-   "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": "Next Contact Date", 
-   "length": 0, 
-   "no_copy": 0, 
-   "oldfieldname": "contact_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": "column_break2", 
-   "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, 
-   "oldfieldtype": "Column Break", 
-   "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, 
-   "width": "50%"
-  }, 
-  {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "to_discuss", 
-   "fieldtype": "Small Text", 
-   "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": "To Discuss", 
-   "length": 0, 
-   "no_copy": 1, 
-   "oldfieldname": "to_discuss", 
-   "oldfieldtype": "Small Text", 
-   "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": "amended_from", 
@@ -1189,7 +1189,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-08-07 21:25:10.836517", 
+ "modified": "2017-08-21 02:07:46.486433", 
  "modified_by": "Administrator", 
  "module": "CRM", 
  "name": "Opportunity", 
diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py
index ae792ac..cec425c 100644
--- a/erpnext/demo/setup/setup_data.py
+++ b/erpnext/demo/setup/setup_data.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 
 import random, json
 import frappe, erpnext
@@ -42,7 +42,7 @@
 	frappe.clear_cache()
 
 def complete_setup(domain='Manufacturing'):
-	print "Complete Setup..."
+	print("Complete Setup...")
 	from frappe.desk.page.setup_wizard.setup_wizard import setup_complete
 
 	if not frappe.get_all('Company', limit=1):
diff --git a/erpnext/demo/user/stock.py b/erpnext/demo/user/stock.py
index 1b12db8..43668fe 100644
--- a/erpnext/demo/user/stock.py
+++ b/erpnext/demo/user/stock.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 
 import frappe, random
 from frappe.desk import query_report
@@ -36,7 +36,7 @@
 			try:
 				pr.submit()
 			except NegativeStockError:
-				print 'Negative stock for {0}'.format(po)
+				print('Negative stock for {0}'.format(po))
 				pass
 			frappe.db.commit()
 
diff --git a/erpnext/hr/doctype/appraisal/test_appraisal.js b/erpnext/hr/doctype/appraisal/test_appraisal.js
new file mode 100644
index 0000000..91da7d3
--- /dev/null
+++ b/erpnext/hr/doctype/appraisal/test_appraisal.js
@@ -0,0 +1,58 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Expense Claim [HR]", function (assert) {
+	assert.expect(3);
+	let done = assert.async();
+	let employee_name;
+
+	frappe.run_serially([
+		// Creating Appraisal
+		() => frappe.set_route('List','Appraisal','List'),
+		() => frappe.timeout(0.3),
+		() => frappe.click_button('Make a new Appraisal'),
+		() => {
+			cur_frm.set_value('kra_template','Test Appraisal 1'),
+			cur_frm.set_value('start_date','2017-08-21'),
+			cur_frm.set_value('end_date','2017-09-21');
+		},
+		() => frappe.timeout(1),
+		() => frappe.model.set_value('Appraisal Goal','New Appraisal Goal 1','score',4),
+		() => frappe.model.set_value('Appraisal Goal','New Appraisal Goal 1','score_earned',2),
+		() => frappe.model.set_value('Appraisal Goal','New Appraisal Goal 2','score',4),
+		() => frappe.model.set_value('Appraisal Goal','New Appraisal Goal 2','score_earned',2),
+		() => frappe.timeout(1),
+		() => frappe.db.get_value('Employee', {'employee_name': 'Test Employee 1'}, 'name'),
+		(r) => {
+			employee_name = r.message.name;
+		},
+
+		() => frappe.timeout(1),
+		() => cur_frm.set_value('employee',employee_name),
+		() => cur_frm.set_value('employee_name','Test Employee 1'),
+		() => cur_frm.set_value('company','Test Company'),
+		() => frappe.click_button('Calculate Total Score'),
+		() => frappe.timeout(1),
+		() => cur_frm.save(),
+		() => frappe.timeout(1),
+		() => cur_frm.save(),
+
+		// Submitting the Appraisal
+		() => frappe.click_button('Submit'),
+		() => frappe.click_button('Yes'),
+		() => frappe.timeout(3),
+
+		// Checking if the appraisal is correctly set for the employee
+		() => {
+			assert.equal('Submitted',cur_frm.get_field('status').value,
+				'Appraisal is submitted');
+
+			assert.equal('Test Employee 1',cur_frm.get_field('employee_name').value,
+				'Appraisal is created for correct employee');
+
+			assert.equal(4,cur_frm.get_field('total_score').value,
+				'Total score is correctly calculated');
+		},
+		() => done()
+	]);
+});
+
diff --git a/erpnext/hr/doctype/appraisal_template/test_appraisal_template.js b/erpnext/hr/doctype/appraisal_template/test_appraisal_template.js
new file mode 100644
index 0000000..4e245c7
--- /dev/null
+++ b/erpnext/hr/doctype/appraisal_template/test_appraisal_template.js
@@ -0,0 +1,30 @@
+QUnit.module('hr');
+QUnit.test("Test: Appraisal Template [HR]", function (assert) {
+	assert.expect(1);
+	let done = assert.async();
+	frappe.run_serially([
+		// Job Opening creation
+		() => {
+			frappe.tests.make('Appraisal Template', [
+				{ kra_title: 'Test Appraisal 1'},
+				{ description: 'This is just a test'},
+				{ goals: [
+					[
+						{ kra: 'Design'},
+						{ per_weightage: 50}
+					],
+					[
+						{ kra: 'Code creation'},
+						{ per_weightage: 50}
+					]
+				]},
+			]);
+		},
+		() => frappe.timeout(5),
+		() => {
+			assert.equal('Test Appraisal 1',cur_frm.doc.kra_title, 'Appraisal name correctly set');
+		},
+		() => done()
+	]);
+});
+
diff --git a/erpnext/hr/doctype/employee_loan/test_employee_loan.js b/erpnext/hr/doctype/employee_loan/test_employee_loan.js
new file mode 100644
index 0000000..9039339
--- /dev/null
+++ b/erpnext/hr/doctype/employee_loan/test_employee_loan.js
@@ -0,0 +1,79 @@
+
+QUnit.test("Test Loan [HR]", function(assert) {
+	assert.expect(8);
+	let done = assert.async();
+	let employee_name;
+
+	// To create a loan and check principal,interest and balance amount
+	let loan_creation = (ename,lname) => {
+		return frappe.run_serially([
+			() => frappe.db.get_value('Employee', {'employee_name': ename}, 'name'),
+			(r) => {
+				employee_name = r.message.name;
+			},
+			() => frappe.db.get_value('Employee Loan Application', {'loan_type': lname}, 'name'),
+			(r) => {
+				// Creating loan for an employee
+				return frappe.tests.make('Employee Loan', [
+					{ company: 'Test Company'},
+					{ posting_date: '2017-08-26'},
+					{ employee: employee_name},
+					{ employee_loan_application: r.message.name},
+					{ disbursement_date: '2018-08-26'},
+					{ mode_of_payment: 'Cash'},
+					{ employee_loan_account: 'Temporary Opening - TC'},
+					{ interest_income_account: 'Service - TC'}
+				]);
+			},
+			() => frappe.timeout(3),
+			() => frappe.click_button('Submit'),
+			() => frappe.timeout(1),
+			() => frappe.click_button('Yes'),
+			() => frappe.timeout(3),
+
+			// Checking if all the amounts are correctly calculated
+			() => {
+				assert.ok(cur_frm.get_field('employee_name').value=='Test Employee 1'&&
+					(cur_frm.get_field('status').value=='Sanctioned'),
+				'Loan Sanctioned for correct employee');
+
+				assert.equal(7270,
+					cur_frm.get_doc('repayment_schedule').repayment_schedule[0].principal_amount,
+					'Principal amount for first instalment is correctly calculated');
+
+				assert.equal(2333,
+					cur_frm.get_doc('repayment_schedule').repayment_schedule[0].interest_amount,
+					'Interest amount for first instalment is correctly calculated');
+
+				assert.equal(192730,
+					cur_frm.get_doc('repayment_schedule').repayment_schedule[0].balance_loan_amount,
+					'Balance amount after first instalment is correctly calculated');
+
+				assert.equal(9479,
+					cur_frm.get_doc('repayment_schedule').repayment_schedule[23].principal_amount,
+					'Principal amount for last instalment is correctly calculated');
+
+				assert.equal(111,
+					cur_frm.get_doc('repayment_schedule').repayment_schedule[23].interest_amount,
+					'Interest amount for last instalment is correctly calculated');
+
+				assert.equal(0,
+					cur_frm.get_doc('repayment_schedule').repayment_schedule[23].balance_loan_amount,
+					'Balance amount after last instalment is correctly calculated');
+
+			},
+			() => frappe.set_route('List','Employee Loan','List'),
+			() => frappe.timeout(2),
+
+			// Checking the submission of Loan
+			() => {
+				assert.ok(cur_list.data[0].docstatus==1,'Loan sanctioned and submitted successfully');
+			},
+		]);
+	};
+	frappe.run_serially([
+		// Creating loan
+		() => loan_creation('Test Employee 1','Test Loan'),
+		() => done()
+	]);
+});
diff --git a/erpnext/hr/doctype/employee_loan_application/test_employee_loan_application.js b/erpnext/hr/doctype/employee_loan_application/test_employee_loan_application.js
new file mode 100644
index 0000000..72ad915
--- /dev/null
+++ b/erpnext/hr/doctype/employee_loan_application/test_employee_loan_application.js
@@ -0,0 +1,68 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Employee Loan Application [HR]", function (assert) {
+	assert.expect(8);
+	let done = assert.async();
+	let employee_name;
+
+	frappe.run_serially([
+		//  Creation of Loan Application
+		() => frappe.db.get_value('Employee', {'employee_name': 'Test Employee 1'}, 'name'),
+		(r) => {
+			employee_name = r.message.name;
+		},
+		() => {
+			frappe.tests.make('Employee Loan Application', [
+				{ company: 'Test Company'},
+				{ employee: employee_name},
+				{ employee_name: 'Test Employee 1'},
+				{ status: 'Approved'},
+				{ loan_type: 'Test Loan '},
+				{ loan_amount: 200000},
+				{ description: 'This is just a test'},
+				{ repayment_method: 'Repay Over Number of Periods'},
+				{ repayment_periods: 24},
+				{ rate_of_interest: 14}
+			]);
+		},
+		() => frappe.timeout(6),
+		() => frappe.click_button('Submit'),
+		() => frappe.timeout(1),
+		() => frappe.click_button('Yes'),
+		() => frappe.timeout(2),
+		() => {
+			// To check if all the amounts are correctly calculated
+
+			assert.ok(cur_frm.get_field('employee_name').value == 'Test Employee 1',
+				'Application created successfully');
+
+			assert.ok(cur_frm.get_field('status').value=='Approved',
+				'Status of application is correctly set');
+
+			assert.ok(cur_frm.get_field('loan_type').value=='Test Loan',
+				'Application is created for correct Loan Type');
+
+			assert.ok(cur_frm.get_field('status').value=='Approved',
+				'Status of application is correctly set');
+
+			assert.ok(cur_frm.get_field('repayment_amount').value==9603,
+				'Repayment amount is correctly calculated');
+
+			assert.ok(cur_frm.get_field('total_payable_interest').value==30459,
+				'Interest amount is correctly calculated');
+
+			assert.ok(cur_frm.get_field('total_payable_amount').value==230459,
+				'Total payable amount is correctly calculated');
+		},
+
+		() => frappe.set_route('List','Employee Loan Application','List'),
+		() => frappe.timeout(2),
+
+		// Checking the submission of Loan Application
+		() => {
+			assert.ok(cur_list.data[0].docstatus==1,'Loan Application submitted successfully');
+		},
+		() => frappe.timeout(1),
+		() => done()
+	]);
+});
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.js b/erpnext/hr/doctype/expense_claim/test_expense_claim.js
new file mode 100644
index 0000000..c7c764c
--- /dev/null
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.js
@@ -0,0 +1,59 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Expense Claim [HR]", function (assert) {
+	assert.expect(3);
+	let done = assert.async();
+	let employee_name;
+	let d;
+	frappe.run_serially([
+		// Creating Expense Claim
+		() => frappe.set_route('List','Expense Claim','List'),
+		() => frappe.timeout(0.3),
+		() => frappe.click_button('Make a new Expense Claim'),
+		() => {
+			cur_frm.set_value('exp_approver','Administrator'),
+			cur_frm.set_value('is_paid',1),
+			cur_frm.set_value('expenses',[]),
+			d = frappe.model.add_child(cur_frm.doc,'Expense Claim Detail','expenses'),
+			d.expense_date = '2017-08-01',
+			d.expense_type = 'Test Expense Type 1',
+			d.description  = 'This is just to test Expense Claim',
+			d.claim_amount = 2000,
+			d.sanctioned_amount=2000,
+			refresh_field('expenses');
+		},
+		() => frappe.timeout(2),
+		() => frappe.db.get_value('Employee', {'employee_name': 'Test Employee 1'}, 'name'),
+		(r) => {
+			employee_name = r.message.name;
+		},
+		() => frappe.timeout(1),
+		() => cur_frm.set_value('employee',employee_name),
+		() => cur_frm.set_value('employee_name','Test Employee 1'),
+		() => cur_frm.set_value('company','Test Company'),
+		() => cur_frm.set_value('payable_account','Creditors - TC'),
+		() => cur_frm.set_value('cost_center','Main - TC'),
+		() => cur_frm.set_value('mode_of_payment','Cash'),
+		() => cur_frm.save(),
+		() => frappe.timeout(1),
+		() => cur_frm.set_value('approval_status','Approved'),
+		() => frappe.timeout(1),
+		() => cur_frm.save(),
+		// Submitting the Expense Claim
+		() => frappe.click_button('Submit'),
+		() => frappe.click_button('Yes'),
+		() => frappe.timeout(3),
+
+		// Checking if the amount is correctly reimbursed for the employee
+		() => {
+			assert.equal(employee_name,cur_frm.get_field('employee').value,
+				'Expense Claim is created for correct employee');
+			assert.equal(1,cur_frm.get_field('is_paid').value,
+				'Expense is paid as required');
+			assert.equal(2000,cur_frm.get_field('total_amount_reimbursed').value,
+				'Amount is reimbursed correctly');
+		},
+		() => done()
+	]);
+});
+
diff --git a/erpnext/hr/doctype/expense_claim_type/test_expense_claim_type.js b/erpnext/hr/doctype/expense_claim_type/test_expense_claim_type.js
new file mode 100644
index 0000000..595454f
--- /dev/null
+++ b/erpnext/hr/doctype/expense_claim_type/test_expense_claim_type.js
@@ -0,0 +1,30 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Expense Claim Type [HR]", function (assert) {
+	assert.expect(1);
+	let done = assert.async();
+	frappe.run_serially([
+		// Creating a Expense Claim Type
+		() => {
+			frappe.tests.make('Expense Claim Type', [
+				{ expense_type: 'Test Expense Type 1'},
+				{ description:'This is just a test'},
+				{ accounts: [
+					[
+						{ company: 'Test Company'},
+						{ default_account: 'Round Off - TC'}
+					]
+				]},
+			]);
+		},
+		() => frappe.timeout(5),
+
+		// Checking if the created type is present in the list
+		() => {
+			assert.equal('Test Expense Type 1', cur_frm.doc.expense_type,
+				'Expense Claim Type created successfully');
+		},
+		() => done()
+	]);
+});
+
diff --git a/erpnext/hr/doctype/leave_application/test_leave_application.js b/erpnext/hr/doctype/leave_application/test_leave_application.js
index 51e8ed6..6028405 100644
--- a/erpnext/hr/doctype/leave_application/test_leave_application.js
+++ b/erpnext/hr/doctype/leave_application/test_leave_application.js
@@ -1,7 +1,7 @@
 QUnit.module('hr');
 
 QUnit.test("Test: Leave application [HR]", function (assert) {
-	assert.expect(5);
+	assert.expect(4);
 	let done = assert.async();
 	let today_date = frappe.datetime.nowdate();
 	let leave_date = frappe.datetime.add_days(today_date, 1);	// leave for tomorrow
@@ -22,8 +22,6 @@
 		},
 		() => frappe.timeout(1),
 		// check calculated total leave days
-		() => assert.equal("0.5", cur_frm.doc.total_leave_days,
-			"leave application for half day"),
 		() => assert.ok(!cur_frm.doc.docstatus,
 			"leave application not submitted with status as open"),
 		() => cur_frm.set_value("status", "Approved"),	// approve the application [as administrator]
diff --git a/erpnext/hr/doctype/leave_block_list/test_leave_block_list.py b/erpnext/hr/doctype/leave_block_list/test_leave_block_list.py
index 42b26e3..210b8b7 100644
--- a/erpnext/hr/doctype/leave_block_list/test_leave_block_list.py
+++ b/erpnext/hr/doctype/leave_block_list/test_leave_block_list.py
@@ -10,7 +10,7 @@
 
 class TestLeaveBlockList(unittest.TestCase):
 	def tearDown(self):
-		 frappe.set_user("Administrator")
+		frappe.set_user("Administrator")
 
 	def test_get_applicable_block_dates(self):
 		frappe.set_user("test@example.com")
diff --git a/erpnext/hr/doctype/loan_type/test_loan_type.js b/erpnext/hr/doctype/loan_type/test_loan_type.js
new file mode 100644
index 0000000..8b5032b
--- /dev/null
+++ b/erpnext/hr/doctype/loan_type/test_loan_type.js
@@ -0,0 +1,31 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Loan Type [HR]", function (assert) {
+	assert.expect(3);
+	let done = assert.async();
+
+	frappe.run_serially([
+		// Loan Type creation
+		() => {
+			frappe.tests.make('Loan Type', [
+				{ loan_name: 'Test Loan'},
+				{ maximum_loan_amount: 400000},
+				{ rate_of_interest: 14},
+				{ description:
+					'This is just a test.'}
+			]);
+		},
+		() => frappe.timeout(3),
+		() => frappe.set_route('List','Loan Type','List'),
+		() => frappe.timeout(2),
+
+		// Checking if the fields are correctly set
+		() => {
+			assert.ok(cur_list.data.length==1, 'Loan Type created successfully');
+			assert.ok(cur_list.data[0].name=='Test Loan', 'Loan title Correctly set');
+			assert.ok(cur_list.data[0].disabled==0, 'Loan enabled');
+		},
+		() => done()
+	]);
+});
+
diff --git a/erpnext/hr/doctype/training_event/test_training_event.js b/erpnext/hr/doctype/training_event/test_training_event.js
new file mode 100644
index 0000000..a359af3
--- /dev/null
+++ b/erpnext/hr/doctype/training_event/test_training_event.js
@@ -0,0 +1,55 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Training Event [HR]", function (assert) {
+	assert.expect(4);
+	let done = assert.async();
+	let employee_name;
+
+	frappe.run_serially([
+		//  Creation of Training Event
+		() => frappe.db.get_value('Employee', {'employee_name': 'Test Employee 1'}, 'name'),
+		(r) => {
+			employee_name = r.message.name;
+		},
+		() => {
+			frappe.tests.make('Training Event', [
+				{ event_name: 'Test Training Event 1'},
+				{ location: 'Mumbai'},
+				{ start_time: '2017-09-01 11:00:0'},
+				{ end_time: '2017-09-01 17:00:0'},
+				{ introduction: 'This is just a test'},
+				{ employees: [
+					[
+						{employee: employee_name},
+						{employee_name: 'Test Employee 1'}
+					]
+				]},
+			]);
+		},
+		() => frappe.timeout(7),
+		() => frappe.click_button('Submit'),
+		() => frappe.timeout(1),
+		() => frappe.click_button('Yes'),
+		() => frappe.timeout(8),
+		() => {
+			// To check if the fields are correctly set
+			assert.ok(cur_frm.get_field('event_name').value == 'Test Training Event 1',
+				'Event created successfully');
+
+			assert.ok(cur_frm.get_field('event_status').value=='Scheduled',
+				'Status of event is correctly set');
+
+			assert.ok(cur_frm.doc.employees[0].employee_name=='Test Employee 1',
+				'Attendee Employee is correctly set');
+		},
+
+		() => frappe.set_route('List','Training Event','List'),
+		() => frappe.timeout(2),
+		// Checking the submission of Training Event
+		() => {
+			assert.ok(cur_list.data[0].docstatus==1,'Training Event Submitted successfully');
+		},
+		() => frappe.timeout(2),
+		() => done()
+	]);
+});
\ No newline at end of file
diff --git a/erpnext/hr/doctype/training_feedback/test_training_feedback.js b/erpnext/hr/doctype/training_feedback/test_training_feedback.js
new file mode 100644
index 0000000..9daa51f
--- /dev/null
+++ b/erpnext/hr/doctype/training_feedback/test_training_feedback.js
@@ -0,0 +1,52 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Training Feedback [HR]", function (assert) {
+	assert.expect(3);
+	let done = assert.async();
+	let employee_name;
+
+	frappe.run_serially([
+		// Creating Training Feedback
+		() => frappe.set_route('List','Training Feedback','List'),
+		() => frappe.timeout(0.3),
+		() => frappe.click_button('Make a new Training Feedback'),
+		() => frappe.timeout(1),
+		() => frappe.db.get_value('Employee', {'employee_name': 'Test Employee 1'}, 'name'),
+		(r) => {
+			employee_name = r.message.name;
+		},
+		() => cur_frm.set_value('employee',employee_name),
+		() => cur_frm.set_value('employee_name','Test Employee 1'),
+		() => cur_frm.set_value('training_event','Test Training Event 1'),
+		() => cur_frm.set_value('event_name','Test Training Event 1'),
+		() => cur_frm.set_value('feedback','Great Experience. This is just a test.'),
+		() => frappe.timeout(1),
+		() => cur_frm.save(),
+		() => frappe.timeout(1),
+		() => cur_frm.save(),
+
+		// Submitting the feedback
+		() => frappe.click_button('Submit'),
+		() => frappe.click_button('Yes'),
+		() => frappe.timeout(3),
+
+		// Checking if the feedback is given by correct employee
+		() => {
+			assert.equal('Test Employee 1',cur_frm.get_field('employee_name').value,
+				'Feedback is given by correct employee');
+
+			assert.equal('Test Training Event 1',cur_frm.get_field('training_event').value,
+				'Feedback is given for correct event');
+		},
+
+		() => frappe.set_route('List','Training Feedback','List'),
+		() => frappe.timeout(2),
+
+		// Checking the submission of Training Result
+		() => {
+			assert.ok(cur_list.data[0].docstatus==1,'Training Feedback Submitted successfully');
+		},
+		() => done()
+	]);
+});
+
diff --git a/erpnext/hr/doctype/training_result_employee/test_training_result.js b/erpnext/hr/doctype/training_result_employee/test_training_result.js
new file mode 100644
index 0000000..2ebf896
--- /dev/null
+++ b/erpnext/hr/doctype/training_result_employee/test_training_result.js
@@ -0,0 +1,53 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Training Result [HR]", function (assert) {
+	assert.expect(5);
+	let done = assert.async();
+	frappe.run_serially([
+		// Creating Training Result
+		() => frappe.set_route('List','Training Result','List'),
+		() => frappe.timeout(0.3),
+		() => frappe.click_button('Make a new Training Result'),
+		() => {
+			cur_frm.set_value('training_event','Test Training Event 1');
+		},
+		() => frappe.timeout(1),
+		() => frappe.model.set_value('Training Result Employee','New Training Result Employee 1','hours',4),
+		() => frappe.model.set_value('Training Result Employee','New Training Result Employee 1','grade','A'),
+		() => frappe.model.set_value('Training Result Employee','New Training Result Employee 1','comments','Nice Seminar'),
+		() => frappe.timeout(1),
+		() => cur_frm.save(),
+		() => frappe.timeout(1),
+		() => cur_frm.save(),
+
+		// Submitting the Training Result
+		() => frappe.click_button('Submit'),
+		() => frappe.click_button('Yes'),
+		() => frappe.timeout(4),
+
+		// Checking if the fields are correctly set
+		() => {
+			assert.equal('Test Training Event 1',cur_frm.get_field('training_event').value,
+				'Training Result is created');
+
+			assert.equal('Test Employee 1',cur_frm.doc.employees[0].employee_name,
+				'Training Result is created for correct employee');
+
+			assert.equal(4,cur_frm.doc.employees[0].hours,
+				'Hours field is correctly calculated');
+
+			assert.equal('A',cur_frm.doc.employees[0].grade,
+				'Grade field is correctly set');
+		},
+
+		() => frappe.set_route('List','Training Result','List'),
+		() => frappe.timeout(2),
+
+		// Checking the submission of Training Result
+		() => {
+			assert.ok(cur_list.data[0].docstatus==1,'Training Result Submitted successfully');
+		},
+		() => done()
+	]);
+});
+
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 71ff43f..e48a002 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -259,15 +259,15 @@
 
 			
 	def update_stock_qty(self):
- 		for m in self.get('items'):
+		for m in self.get('items'):
 		
 			if not m.conversion_factor:
 				m.conversion_factor = flt(get_conversion_factor(m.item_code, m.uom)['conversion_factor'])
- 			if m.uom and m.qty:
- 				m.stock_qty = flt(m.conversion_factor)*flt(m.qty)
- 			if not m.uom and m.stock_uom:
- 				m.uom = m.stock_uom
- 				m.qty = m.stock_qty
+			if m.uom and m.qty:
+				m.stock_qty = flt(m.conversion_factor)*flt(m.qty)
+			if not m.uom and m.stock_uom:
+				m.uom = m.stock_uom
+				m.qty = m.stock_qty
  
  
 	def set_conversion_rate(self):
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 35530fd..7ec2753 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -433,4 +433,5 @@
 erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
 erpnext.patches.v8_5.remove_project_type_property_setter
 erpnext.patches.v8_7.add_more_gst_fields
-erpnext.patches.v8_7.fix_purchase_receipt_status
\ No newline at end of file
+erpnext.patches.v8_7.fix_purchase_receipt_status
+erpnext.patches.v8_6.rename_bom_update_tool
\ No newline at end of file
diff --git a/erpnext/patches/v4_0/new_address_template.py b/erpnext/patches/v4_0/new_address_template.py
index f644a5a..fa66027 100644
--- a/erpnext/patches/v4_0/new_address_template.py
+++ b/erpnext/patches/v4_0/new_address_template.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 
 def execute():
@@ -10,5 +10,5 @@
 				frappe.db.get_value("Global Defaults", "Global Defaults", "country")})
 			d.insert()
 		except:
-			print frappe.get_traceback()
+			print(frappe.get_traceback())
 
diff --git a/erpnext/patches/v4_0/reset_permissions_for_masters.py b/erpnext/patches/v4_0/reset_permissions_for_masters.py
index b2f1fcd..bc1b438 100644
--- a/erpnext/patches/v4_0/reset_permissions_for_masters.py
+++ b/erpnext/patches/v4_0/reset_permissions_for_masters.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 from frappe.permissions import reset_perms
 
 def execute():
@@ -16,5 +16,5 @@
 		try:
 			reset_perms(doctype)
 		except:
-			print "Error resetting perms for", doctype
+			print("Error resetting perms for", doctype)
 			raise
diff --git a/erpnext/patches/v4_0/set_naming_series_property_setter.py b/erpnext/patches/v4_0/set_naming_series_property_setter.py
index 9d12f14..e61a596 100644
--- a/erpnext/patches/v4_0/set_naming_series_property_setter.py
+++ b/erpnext/patches/v4_0/set_naming_series_property_setter.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 
 import frappe
 from frappe.custom.doctype.property_setter.property_setter import make_property_setter
@@ -91,7 +91,7 @@
 		(new_series, new_series))
 
 	if not (default_series and default_series[0][0]):
-		print "[Skipping] Cannot guess which naming series to use for", doctype
+		print("[Skipping] Cannot guess which naming series to use for", doctype)
 		return
 
 	return default_series[0][0]
diff --git a/erpnext/patches/v4_0/split_email_settings.py b/erpnext/patches/v4_0/split_email_settings.py
index 21dc050..5d1dea6 100644
--- a/erpnext/patches/v4_0/split_email_settings.py
+++ b/erpnext/patches/v4_0/split_email_settings.py
@@ -1,11 +1,11 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 
 def execute():
-	print "WARNING!!!! Email Settings not migrated. Please setup your email again."
+	print("WARNING!!!! Email Settings not migrated. Please setup your email again.")
 
 	# this will happen if you are migrating very old accounts
 	# comment out this line below and remember to create new Email Accounts
diff --git a/erpnext/patches/v4_0/update_account_root_type.py b/erpnext/patches/v4_0/update_account_root_type.py
index e3edee9..15ddf03 100644
--- a/erpnext/patches/v4_0/update_account_root_type.py
+++ b/erpnext/patches/v4_0/update_account_root_type.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 
 def execute():
@@ -31,4 +31,4 @@
 				frappe.db.sql("""UPDATE tabAccount SET root_type=%s WHERE lft>%s and rgt<%s""",
 					(root.root_type, root.lft, root.rgt))
 			else:
-				print b"Root type not found for {0}".format(root.name.encode("utf-8"))
+				print(b"Root type not found for {0}".format(root.name.encode("utf-8")))
diff --git a/erpnext/patches/v4_2/fix_gl_entries_for_stock_transactions.py b/erpnext/patches/v4_2/fix_gl_entries_for_stock_transactions.py
index 0df5801..16932af 100644
--- a/erpnext/patches/v4_2/fix_gl_entries_for_stock_transactions.py
+++ b/erpnext/patches/v4_2/fix_gl_entries_for_stock_transactions.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 from frappe.utils import flt
 
@@ -37,7 +37,7 @@
 
 			if stock_bal and account_bal and abs(flt(stock_bal[0][0]) - flt(account_bal[0][0])) > 0.1:
 				try:
-					print voucher_type, voucher_no, stock_bal[0][0], account_bal[0][0]
+					print(voucher_type, voucher_no, stock_bal[0][0], account_bal[0][0])
 
 					frappe.db.sql("""delete from `tabGL Entry`
 						where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
@@ -45,10 +45,10 @@
 					voucher = frappe.get_doc(voucher_type, voucher_no)
 					voucher.make_gl_entries(repost_future_gle=False)
 					frappe.db.commit()
-				except Exception, e:
-					print frappe.get_traceback()
+				except Exception as e:
+					print(frappe.get_traceback())
 					rejected.append([voucher_type, voucher_no])
 					frappe.db.rollback()
 
-		print "Failed to repost: "
-		print rejected
+		print("Failed to repost: ")
+		print(rejected)
diff --git a/erpnext/patches/v4_2/party_model.py b/erpnext/patches/v4_2/party_model.py
index 8f4fc33..6f93352 100644
--- a/erpnext/patches/v4_2/party_model.py
+++ b/erpnext/patches/v4_2/party_model.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 
 def execute():
@@ -109,7 +109,7 @@
 		and exists(select gle.name from `tabGL Entry` gle where gle.account = tabAccount.name)""")
 		
 	if accounts_not_deleted:
-		print "Accounts not deleted: " + "\n".join(accounts_not_deleted)
+		print("Accounts not deleted: " + "\n".join(accounts_not_deleted))
 		
 
 def remove_customer_supplier_account_report():
diff --git a/erpnext/patches/v4_2/repost_sle_for_si_with_no_warehouse.py b/erpnext/patches/v4_2/repost_sle_for_si_with_no_warehouse.py
index 44bec00..1356129 100644
--- a/erpnext/patches/v4_2/repost_sle_for_si_with_no_warehouse.py
+++ b/erpnext/patches/v4_2/repost_sle_for_si_with_no_warehouse.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 from erpnext.stock.stock_ledger import NegativeStockError
 
@@ -28,7 +28,7 @@
 			frappe.local.stockledger_exceptions = None
 			frappe.db.rollback()
 
-	print "Failed to repost: ", failed_list
+	print("Failed to repost: ", failed_list)
 					
 		
 	
\ No newline at end of file
diff --git a/erpnext/patches/v4_2/set_company_country.py b/erpnext/patches/v4_2/set_company_country.py
index 929f6c5..89f07f2 100644
--- a/erpnext/patches/v4_2/set_company_country.py
+++ b/erpnext/patches/v4_2/set_company_country.py
@@ -1,13 +1,13 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 
 def execute():
 	country = frappe.db.get_single_value("Global Defaults", "country")
 	if not country:
-		print "Country not specified in Global Defaults"
+		print("Country not specified in Global Defaults")
 		return
 
 	for company in frappe.db.sql_list("""select name from `tabCompany`
diff --git a/erpnext/patches/v5_0/repost_gle_for_jv_with_multiple_party.py b/erpnext/patches/v5_0/repost_gle_for_jv_with_multiple_party.py
index da58ae2..76efdcc 100644
--- a/erpnext/patches/v5_0/repost_gle_for_jv_with_multiple_party.py
+++ b/erpnext/patches/v5_0/repost_gle_for_jv_with_multiple_party.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 
 def execute():
@@ -21,6 +21,6 @@
 		je.make_gl_entries()
 		
 	if je_list:
-		print je_list
+		print(je_list)
 		
 		
\ No newline at end of file
diff --git a/erpnext/patches/v5_4/fix_missing_item_images.py b/erpnext/patches/v5_4/fix_missing_item_images.py
index 1891d2d..c0a2513 100644
--- a/erpnext/patches/v5_4/fix_missing_item_images.py
+++ b/erpnext/patches/v5_4/fix_missing_item_images.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 import os
 from frappe.utils import get_files_path
@@ -45,7 +45,7 @@
 		try:
 			file_data.save()
 		except IOError:
-			print "File {0} does not exist".format(new_file_url)
+			print("File {0} does not exist".format(new_file_url))
 
 			# marking fix to prevent further errors
 			fixed_files.append(file_url)
diff --git a/erpnext/patches/v5_4/notify_system_managers_regarding_wrong_tax_calculation.py b/erpnext/patches/v5_4/notify_system_managers_regarding_wrong_tax_calculation.py
index 125b84f..ba31122 100644
--- a/erpnext/patches/v5_4/notify_system_managers_regarding_wrong_tax_calculation.py
+++ b/erpnext/patches/v5_4/notify_system_managers_regarding_wrong_tax_calculation.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 from frappe.email import sendmail_to_system_managers
 from frappe.utils import get_link_to_form
@@ -36,6 +36,6 @@
 		except:
 			pass
 		
-		print "="*50
-		print content
-		print "="*50
\ No newline at end of file
+		print("="*50)
+		print(content)
+		print("="*50)
\ No newline at end of file
diff --git a/erpnext/patches/v5_7/item_template_attributes.py b/erpnext/patches/v5_7/item_template_attributes.py
index 9f141b5..22b15d3 100644
--- a/erpnext/patches/v5_7/item_template_attributes.py
+++ b/erpnext/patches/v5_7/item_template_attributes.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 import MySQLdb
 
@@ -32,7 +32,7 @@
 			migrate_item_variants()
 
 		except MySQLdb.ProgrammingError:
-			print "`tabItem Variant` not found"
+			print("`tabItem Variant` not found")
 
 def rename_and_reload_doctypes():
 	if "tabVariant Attribute" in frappe.db.get_tables():
diff --git a/erpnext/patches/v6_12/repost_entries_with_target_warehouse.py b/erpnext/patches/v6_12/repost_entries_with_target_warehouse.py
index dc0df0f..fb5eab4 100644
--- a/erpnext/patches/v6_12/repost_entries_with_target_warehouse.py
+++ b/erpnext/patches/v6_12/repost_entries_with_target_warehouse.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 
 """
@@ -38,19 +38,19 @@
 	si_list = get_affected_sales_invoice()
 	
 	if so_list or dn_list or si_list:
-		print "Entries with Target Warehouse:"
+		print("Entries with Target Warehouse:")
 		
 		if so_list:
-			print "Sales Order"
-			print so_list
+			print("Sales Order")
+			print(so_list)
 
 		if dn_list:
-			print "Delivery Notes"
-			print [d.name for d in dn_list]
+			print("Delivery Notes")
+			print([d.name for d in dn_list])
 
 		if si_list:
-			print "Sales Invoice"
-			print [d.name for d in si_list]
+			print("Sales Invoice")
+			print([d.name for d in si_list])
 		
 		
 def repost():
@@ -61,34 +61,34 @@
 	frappe.db.commit()
 	
 	if dn_failed_list:
-		print "-"*40
-		print "Delivery Note Failed to Repost"
-		print dn_failed_list
+		print("-"*40)
+		print("Delivery Note Failed to Repost")
+		print(dn_failed_list)
 
 	if si_failed_list:
-		print "-"*40
-		print "Sales Invoice Failed to Repost"
-		print si_failed_list
-		print 
+		print("-"*40)
+		print("Sales Invoice Failed to Repost")
+		print(si_failed_list)
+		print()
 		
-		print """
+		print("""
 If above Delivery Notes / Sales Invoice failed due to negative stock, follow these steps:
 	- Ensure that stock is available for those items in the mentioned warehouse on the date mentioned in the error
 	- Run this patch again
-"""
+""")
 	
 def repost_dn(dn_failed_list):
 	dn_list = get_affected_delivery_notes()
 		
 	if dn_list:
-		print "-"*40
-		print "Reposting Delivery Notes"
+		print("-"*40)
+		print("Reposting Delivery Notes")
 
 	for dn in dn_list:
 		if dn.docstatus == 0:
 			continue
 			
-		print dn.name
+		print(dn.name)
 	
 		try:
 			dn_doc = frappe.get_doc("Delivery Note", dn.name)
@@ -107,7 +107,7 @@
 		except Exception:
 			dn_failed_list.append(dn.name)
 			frappe.local.stockledger_exceptions = None
-			print frappe.get_traceback()
+			print(frappe.get_traceback())
 			frappe.db.rollback()
 		
 	frappe.db.sql("update `tabDelivery Note Item` set target_warehouse='' where docstatus=0")
@@ -116,14 +116,14 @@
 	si_list = get_affected_sales_invoice()
 
 	if si_list:
-		print "-"*40
-		print "Reposting Sales Invoice"
+		print("-"*40)
+		print("Reposting Sales Invoice")
 	
 	for si in si_list:
 		if si.docstatus == 0:
 			continue
 		
-		print si.name
+		print(si.name)
 	
 		try:
 			si_doc = frappe.get_doc("Sales Invoice", si.name)
@@ -141,7 +141,7 @@
 		except Exception:
 			si_failed_list.append(si.name)
 			frappe.local.stockledger_exceptions = None
-			print frappe.get_traceback()
+			print(frappe.get_traceback())
 			frappe.db.rollback()
 		
 	frappe.db.sql("update `tabSales Invoice Item` set target_warehouse='' where docstatus=0")
@@ -152,8 +152,8 @@
 	frappe.db.sql("update `tabSales Order Item` set target_warehouse=''")
 	
 	if so_list:
-		print "-"*40
-		print "Sales Order reposted"
+		print("-"*40)
+		print("Sales Order reposted")
 	
 	
 def get_affected_delivery_notes():
diff --git a/erpnext/patches/v6_4/fix_expense_included_in_valuation.py b/erpnext/patches/v6_4/fix_expense_included_in_valuation.py
index 436dd02..7ed15ab 100644
--- a/erpnext/patches/v6_4/fix_expense_included_in_valuation.py
+++ b/erpnext/patches/v6_4/fix_expense_included_in_valuation.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 from frappe.utils import cstr
 
@@ -33,7 +33,7 @@
 				(pi.name, company.expenses_included_in_valuation))
 
 			if gle_for_expenses_included_in_valuation:
-				print pi.name
+				print(pi.name)
 
 				frappe.db.sql("""delete from `tabGL Entry`
 					where voucher_type='Purchase Invoice' and voucher_no=%s""", pi.name)
diff --git a/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py b/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py
index b1464d5..b53412d 100644
--- a/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py
+++ b/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 
 def execute():
@@ -44,7 +44,7 @@
 				where name=%s""", d.name)
 
 	for d in journal_entries:
-		print d
+		print(d)
 		# delete existing gle
 		frappe.db.sql("delete from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s", d)
 
diff --git a/erpnext/patches/v6_4/make_image_thumbnail.py b/erpnext/patches/v6_4/make_image_thumbnail.py
index 702148a..3315acc 100644
--- a/erpnext/patches/v6_4/make_image_thumbnail.py
+++ b/erpnext/patches/v6_4/make_image_thumbnail.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
 import frappe
 
 def execute():
@@ -11,4 +12,4 @@
 				if item_doc.thumbnail:
 					item_doc.db_set("thumbnail", item_doc.thumbnail, update_modified=False)
 			except Exception:
-				print "Unable to make thumbnail for {0}".format(item.website_image.encode("utf-8"))
+				print("Unable to make thumbnail for {0}".format(item.website_image.encode("utf-8")))
diff --git a/erpnext/patches/v6_4/repost_gle_for_journal_entries_where_reference_name_missing.py b/erpnext/patches/v6_4/repost_gle_for_journal_entries_where_reference_name_missing.py
index e0268c4..1319b53 100644
--- a/erpnext/patches/v6_4/repost_gle_for_journal_entries_where_reference_name_missing.py
+++ b/erpnext/patches/v6_4/repost_gle_for_journal_entries_where_reference_name_missing.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 
 def execute():
@@ -13,7 +13,7 @@
 				and against_voucher=je.reference_name)""")
 
 	for d in je_list:
-		print d
+		print(d)
 		
 		# delete existing gle
 		frappe.db.sql("delete from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s", d)
diff --git a/erpnext/patches/v6_6/fix_website_image.py b/erpnext/patches/v6_6/fix_website_image.py
index b3b4cab..cc3e2d8 100644
--- a/erpnext/patches/v6_6/fix_website_image.py
+++ b/erpnext/patches/v6_6/fix_website_image.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 from frappe.utils import encode
 
@@ -25,7 +25,7 @@
 		try:
 			file.validate_file()
 		except IOError:
-			print encode(item.website_image), "does not exist"
+			print(encode(item.website_image), "does not exist")
 			file.delete()
 			item.db_set("website_image", None, update_modified=False)
 
diff --git a/erpnext/patches/v7_0/fix_nonwarehouse_ledger_gl_entries_for_transactions.py b/erpnext/patches/v7_0/fix_nonwarehouse_ledger_gl_entries_for_transactions.py
index 58da059..2bc0971 100644
--- a/erpnext/patches/v7_0/fix_nonwarehouse_ledger_gl_entries_for_transactions.py
+++ b/erpnext/patches/v7_0/fix_nonwarehouse_ledger_gl_entries_for_transactions.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe, erpnext
 
 def execute():
@@ -35,11 +35,11 @@
 				voucher.make_gl_entries()
 				frappe.db.commit()
 			except Exception as e:
-				print frappe.get_traceback()
+				print(frappe.get_traceback())
 				rejected.append([voucher_type, voucher_no])
 				frappe.db.rollback()
 
-		print rejected
+		print(rejected)
 
 def set_warehouse_for_stock_account(warehouse_account):
 	for account in warehouse_account:
diff --git a/erpnext/patches/v7_0/rename_salary_components.py b/erpnext/patches/v7_0/rename_salary_components.py
index 4e9ceb2..8409ca8 100644
--- a/erpnext/patches/v7_0/rename_salary_components.py
+++ b/erpnext/patches/v7_0/rename_salary_components.py
@@ -81,7 +81,7 @@
 		try:
 			frappe.db.sql("""INSERT INTO `tabSalary Component` ({0}) SELECT {1} FROM `tab{2}`"""
 				.format(target_cols, source_cols, doctype))
-		except Exception, e:
+		except Exception as e:
 			if e.args[0]==1062:
 				pass
 			
diff --git a/erpnext/schools/api.py b/erpnext/schools/api.py
index c613c8c..ff2da07 100644
--- a/erpnext/schools/api.py
+++ b/erpnext/schools/api.py
@@ -63,7 +63,7 @@
 	:param student_group: Student Group.
 	:param date: Date.
 	"""
-	 
+
 	present = json.loads(students_present)
 	absent = json.loads(students_absent)
 	
diff --git a/erpnext/schools/doctype/course_schedule/test_course_schedule.py b/erpnext/schools/doctype/course_schedule/test_course_schedule.py
index 6a3456f..f131382 100644
--- a/erpnext/schools/doctype/course_schedule/test_course_schedule.py
+++ b/erpnext/schools/doctype/course_schedule/test_course_schedule.py
@@ -17,7 +17,7 @@
 		cs1 = make_course_schedule_test_record(simulate= True)
 
 		cs2 = make_course_schedule_test_record(schedule_date=cs1.schedule_date, from_time= cs1.from_time, 
-			to_time= cs1.to_time, instructor="_T-Instructor-00002", room="RM0002", do_not_save= 1)
+			to_time= cs1.to_time, instructor="_Test Instructor 2", room="RM0002", do_not_save= 1)
 		self.assertRaises(OverlapError, cs2.save)
 
 	def test_instructor_conflict(self):
@@ -31,14 +31,14 @@
 		cs1 = make_course_schedule_test_record(simulate= True)
 		
 		cs2 = make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time, 
-			student_group="Course-TC101-2014-2015 (_Test Academic Term)", instructor="_T-Instructor-00002", do_not_save= 1)
+			student_group="Course-TC101-2014-2015 (_Test Academic Term)", instructor="_Test Instructor 2", do_not_save= 1)
 		self.assertRaises(OverlapError, cs2.save)
 		
 	def test_no_conflict(self):
 		cs1 = make_course_schedule_test_record(simulate= True)
 		
 		make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time, 
-			student_group="Course-TC102-2014-2015 (_Test Academic Term)", instructor="_T-Instructor-00002", room="RM0002")
+			student_group="Course-TC102-2014-2015 (_Test Academic Term)", instructor="_Test Instructor 2", room="RM0002")
 
 def make_course_schedule_test_record(**args):
 	args = frappe._dict(args)
@@ -46,7 +46,7 @@
 	course_schedule = frappe.new_doc("Course Schedule")
 	course_schedule.student_group = args.student_group or "Course-TC101-2014-2015 (_Test Academic Term)"
 	course_schedule.course = args.course or "TC101"
-	course_schedule.instructor = args.instructor or "_T-Instructor-00001"
+	course_schedule.instructor = args.instructor or "_Test Instructor"
 	course_schedule.room = args.room or "RM0001"
 	
 	course_schedule.schedule_date = args.schedule_date or today()
diff --git a/erpnext/schools/doctype/instructor/instructor.json b/erpnext/schools/doctype/instructor/instructor.json
index a98fe69..cd0b4f1 100644
--- a/erpnext/schools/doctype/instructor/instructor.json
+++ b/erpnext/schools/doctype/instructor/instructor.json
@@ -208,7 +208,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2017-06-30 08:21:49.055531", 
+ "modified": "2017-08-25 01:03:14.602994", 
  "modified_by": "Administrator", 
  "module": "Schools", 
  "name": "Instructor", 
diff --git a/erpnext/schools/doctype/instructor/instructor.py b/erpnext/schools/doctype/instructor/instructor.py
index 4331b91..ba179f7 100644
--- a/erpnext/schools/doctype/instructor/instructor.py
+++ b/erpnext/schools/doctype/instructor/instructor.py
@@ -4,7 +4,21 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe import _
 from frappe.model.document import Document
+from frappe.model.naming import make_autoname
 
 class Instructor(Document):
-	pass
+	def autoname(self):
+		naming_method = frappe.db.get_value("School Settings", None, "instructor_created_by")
+		if not naming_method:
+			frappe.throw(_("Please setup Instructor Naming System in School > School Settings"))
+		else:
+			if naming_method == 'Naming Series':
+				self.name = make_autoname(self.naming_series + '.####')
+			elif naming_method == 'Employee Number':
+				if not self.employee:
+					frappe.throw("Please select Employee")
+				self.name = self.employee
+			elif naming_method == 'Full Name':
+				self.name = self.instructor_name
diff --git a/erpnext/schools/doctype/school_settings/school_settings.json b/erpnext/schools/doctype/school_settings/school_settings.json
index 3b5aae6..b6d9890 100644
--- a/erpnext/schools/doctype/school_settings/school_settings.json
+++ b/erpnext/schools/doctype/school_settings/school_settings.json
@@ -194,6 +194,67 @@
    "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_7", 
+   "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, 
+   "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": "Full Name", 
+   "fieldname": "instructor_created_by", 
+   "fieldtype": "Select", 
+   "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": "Instructor Records to be created by", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Full Name\nNaming Series\nEmployee Number", 
+   "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, 
@@ -206,7 +267,7 @@
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-06-30 08:21:50.339169", 
+ "modified": "2017-08-25 02:36:48.744456", 
  "modified_by": "Administrator", 
  "module": "Schools", 
  "name": "School Settings", 
diff --git a/erpnext/schools/doctype/school_settings/school_settings.py b/erpnext/schools/doctype/school_settings/school_settings.py
index 999014a..88235cf 100644
--- a/erpnext/schools/doctype/school_settings/school_settings.py
+++ b/erpnext/schools/doctype/school_settings/school_settings.py
@@ -26,3 +26,10 @@
 
 	def get_defaults(self):
 		return frappe.defaults.get_defaults()
+
+	def validate(self):
+		from frappe.custom.doctype.property_setter.property_setter import make_property_setter
+		if self.get('instructor_created_by')=='Naming Series':
+			make_property_setter('Instructor', "naming_series", "hidden", 0, "Check")
+		else:
+			make_property_setter('Instructor', "naming_series", "hidden", 1, "Check")
diff --git a/erpnext/schools/doctype/student/student.js b/erpnext/schools/doctype/student/student.js
index d3d248b..cadf272 100644
--- a/erpnext/schools/doctype/student/student.js
+++ b/erpnext/schools/doctype/student/student.js
@@ -3,6 +3,11 @@
 
 frappe.ui.form.on('Student', {
 	setup: function(frm) {
+		frm.add_fetch("guardian", "guardian_name", "guardian_name");
+		frm.add_fetch("student", "title", "full_name");
+		frm.add_fetch("student", "gender", "gender");
+		frm.add_fetch("student", "date_of_birth", "date_of_birth");
+
 		frm.set_query("student", "siblings", function(doc, cdt, cdn) {
 			return {
 				"filters": {
@@ -11,18 +16,4 @@
 			};
 		})
 	}
-});
-
-frappe.ui.form.on("Student Guardian", {
-	guardian: function(frm) {
-		frm.add_fetch("guardian", "guardian_name", "guardian_name");
-	}
-});
-
-frappe.ui.form.on('Student Sibling', {
-	student: function(frm) {
-		frm.add_fetch("student", "title", "full_name");
-		frm.add_fetch("student", "gender", "gender");
-		frm.add_fetch("student", "date_of_birth", "date_of_birth");
-	}
-});
+});
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.js b/erpnext/schools/doctype/student_applicant/student_applicant.js
index 9b08ee5..40a6ac3 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant.js
+++ b/erpnext/schools/doctype/student_applicant/student_applicant.js
@@ -39,15 +39,12 @@
 			method: "erpnext.schools.api.enroll_student",
 			frm: frm
 		})
-	}
-});
+	},
 
-
-frappe.ui.form.on('Student Sibling', {
-	student: function(frm) {
+	setup: function(frm) {
+		frm.add_fetch("guardian", "guardian_name", "guardian_name");
 		frm.add_fetch("student", "title", "full_name");
 		frm.add_fetch("student", "gender", "gender");
 		frm.add_fetch("student", "date_of_birth", "date_of_birth");
 	}
-});
-
+});
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.json b/erpnext/schools/doctype/student_applicant/student_applicant.json
index 271f873..578f84c 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant.json
+++ b/erpnext/schools/doctype/student_applicant/student_applicant.json
@@ -881,7 +881,7 @@
    "in_standard_filter": 0, 
    "label": "Guardians", 
    "length": 0, 
-   "no_copy": 1, 
+   "no_copy": 0, 
    "options": "Student Guardian", 
    "permlevel": 0, 
    "precision": "", 
@@ -1058,7 +1058,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2017-06-30 08:21:50.917086", 
+ "modified": "2017-08-23 06:12:36.996978", 
  "modified_by": "Administrator", 
  "module": "Schools", 
  "name": "Student Applicant", 
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.py b/erpnext/schools/doctype/student_applicant/student_applicant.py
index 047c702..081fa06 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant.py
+++ b/erpnext/schools/doctype/student_applicant/student_applicant.py
@@ -2,7 +2,7 @@
 # Copyright (c) 2015, Frappe Technologies and contributors
 # For license information, please see license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 from frappe import _
 from frappe.model.document import Document
@@ -13,7 +13,7 @@
 		if self.student_admission:
 			naming_series = frappe.db.get_value('Student Admission', self.student_admission,
 				'naming_series_for_student_applicant')
-			print naming_series
+			print(naming_series)
 
 			if naming_series:
 				self.naming_series = naming_series
diff --git a/erpnext/schools/doctype/student_group/test_student_group.py b/erpnext/schools/doctype/student_group/test_student_group.py
index 18a6b14..e358c27 100644
--- a/erpnext/schools/doctype/student_group/test_student_group.py
+++ b/erpnext/schools/doctype/student_group/test_student_group.py
@@ -8,20 +8,20 @@
 from frappe.utils.make_random import get_random
 
 class TestStudentGroup(unittest.TestCase):
-	 def test_student_roll_no(self):
-	 	doc = frappe.get_doc({
-	 		"doctype": "Student Group",
-	 		"student_group_name": "_Test Student Group R",
+	def test_student_roll_no(self):
+		doc = frappe.get_doc({
+			"doctype": "Student Group",
+			"student_group_name": "_Test Student Group R",
 			"group_based_on": "Activity"
-	 		}).insert()
+			}).insert()
 
-	 	student_list = []
-	 	while len(student_list) < 3:
-	 		s = get_random("Student")
-	 		if s not in student_list:
-	 			student_list.append(s)
+		student_list = []
+		while len(student_list) < 3:
+			s = get_random("Student")
+			if s not in student_list:
+				student_list.append(s)
 
-	 	doc.extend("students", [{"student":d} for d in student_list])
-	 	doc.save()
-	 	self.assertEquals(max([d.group_roll_number for d in doc.students]), 3)
+		doc.extend("students", [{"student":d} for d in student_list])
+		doc.save()
+		self.assertEquals(max([d.group_roll_number for d in doc.students]), 3)
 
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index d797632..c12cd44 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -67,7 +67,7 @@
 		'''If Customer created from Lead, update lead status to "Converted"
 		update Customer link in Quotation, Opportunity'''
 		if self.lead_name:
-		 	frappe.db.set_value('Lead', self.lead_name, 'status', 'Converted', update_modified=False)
+			frappe.db.set_value('Lead', self.lead_name, 'status', 'Converted', update_modified=False)
 
 			for doctype in ('Opportunity', 'Quotation'):
 				for d in frappe.get_all(doctype, {'lead': self.lead_name}):
diff --git a/erpnext/selling/doctype/quotation/tests/test_quotation_submit_cancel_amend.js b/erpnext/selling/doctype/quotation/tests/test_quotation_submit_cancel_amend.js
new file mode 100644
index 0000000..26a099e
--- /dev/null
+++ b/erpnext/selling/doctype/quotation/tests/test_quotation_submit_cancel_amend.js
@@ -0,0 +1,41 @@
+QUnit.module('Quotation');
+
+QUnit.test("test quotation submit cancel amend", function(assert) {
+	assert.expect(2);
+	let done = assert.async();
+	frappe.run_serially([
+		() => {
+			return frappe.tests.make('Quotation', [
+				{customer: 'Test Customer 1'},
+				{items: [
+					[
+						{'delivery_date': frappe.datetime.add_days(frappe.defaults.get_default("year_end_date"), 1)},
+						{'qty': 5},
+						{'item_code': 'Test Product 1'}
+					]
+				]},
+				{customer_address: 'Test1-Billing'},
+				{shipping_address_name: 'Test1-Shipping'},
+				{contact_person: 'Contact 1-Test Customer 1'}
+			]);
+		},
+		() => cur_frm.save(),
+		() => {
+			// get_item_details
+			assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
+			// get uom details
+			assert.ok(cur_frm.doc.grand_total== 500, "Grand total correct ");
+
+		},
+		() => frappe.tests.click_button('Submit'),
+		() => frappe.tests.click_button('Yes'),
+		() => frappe.timeout(1),
+		() => frappe.tests.click_button('Close'),
+		() => frappe.tests.click_button('Cancel'),
+		() => frappe.tests.click_button('Yes'),
+		() => frappe.timeout(0.5),
+		() => frappe.tests.click_button('Amend'),
+		() => cur_frm.save(),
+		() => done()
+	]);
+});
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 396b1c2..5f904c2 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -51,9 +51,9 @@
 		# validate p.o date v/s delivery date
 		if self.po_date:
 			for d in self.get("items"):
-				 if d.delivery_date and getdate(self.po_date) > getdate(d.delivery_date):
-					 frappe.throw(_("Row #{0}: Expected Delivery Date cannot be before Purchase Order Date")
-					 	.format(d.idx))
+				if d.delivery_date and getdate(self.po_date) > getdate(d.delivery_date):
+					frappe.throw(_("Row #{0}: Expected Delivery Date cannot be before Purchase Order Date")
+						.format(d.idx))
 
 		if self.po_no and self.customer:
 			so = frappe.db.sql("select name from `tabSales Order` \
diff --git a/erpnext/setup/doctype/item_group/test_item_group.py b/erpnext/setup/doctype/item_group/test_item_group.py
index bc88132..c487c72 100644
--- a/erpnext/setup/doctype/item_group/test_item_group.py
+++ b/erpnext/setup/doctype/item_group/test_item_group.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import unittest
 import frappe
 from frappe.utils.nestedset import NestedSetRecursionError, NestedSetMultipleRootsError, \
@@ -112,7 +112,7 @@
 
 	def print_tree(self):
 		import json
-		print json.dumps(frappe.db.sql("select name, lft, rgt from `tabItem Group` order by lft"), indent=1)
+		print(json.dumps(frappe.db.sql("select name, lft, rgt from `tabItem Group` order by lft"), indent=1))
 
 	def test_move_leaf_into_another_group(self):
 		# before move
diff --git a/erpnext/setup/doctype/naming_series/naming_series.js b/erpnext/setup/doctype/naming_series/naming_series.js
index e2584bf..7c76d9c 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.js
+++ b/erpnext/setup/doctype/naming_series/naming_series.js
@@ -1,47 +1,55 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
 
 
-cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
-	cur_frm.disable_save();
-	cur_frm.toolbar.print_icon.addClass("hide");
-	return cur_frm.call({
-		doc: cur_frm.doc,
-		method: 'get_transactions',
-		callback: function(r) {
-			cur_frm.cscript.update_selects(r);
-			cur_frm.cscript.select_doc_for_series(doc, cdt, cdn);
-		}
-	});
-}
+frappe.ui.form.on("Naming Series", {
+	onload: function(frm) {
+		frm.disable_save();
+		frm.events.get_doc_and_prefix(frm);
+	},
 
-cur_frm.cscript.update_selects = function(r) {
-	set_field_options('select_doc_for_series', r.message.transactions);
-	set_field_options('prefix', r.message.prefixes);
-}
+	get_doc_and_prefix: function(frm) {
+		frappe.call({
+			method: "get_transactions",
+			doc: frm.doc,
+			callback: function(r) {
+				frm.set_df_property("select_doc_for_series", "options", r.message.transactions);
+				frm.set_df_property("prefix", "options", r.message.prefixes);
+			}
+		});
+	},
 
-cur_frm.cscript.select_doc_for_series = function(doc, cdt, cdn) {
-	cur_frm.set_value('user_must_always_select', 0);
-	cur_frm.toggle_display(['help_html','set_options', 'user_must_always_select', 'update'],
-		doc.select_doc_for_series);
+	select_doc_for_series: function(frm) {
+		frm.set_value("user_must_always_select", 0);
+		frappe.call({
+			method: "get_options",
+			doc: frm.doc,
+			callback: function(r) {
+				frm.set_value("set_options", r.message);
+				if(r.message && r.message.split('\n')[0]=='')
+					frm.set_value('user_must_always_select', 1);
+				frm.refresh();
+			}
+		});
+	},
 
-	var callback = function(r, rt){
-		locals[cdt][cdn].set_options = r.message;
-		refresh_field('set_options');
-		if(r.message && r.message.split('\n')[0]=='')
-			cur_frm.set_value('user_must_always_select', 1);
+	prefix: function(frm) {
+		frappe.call({
+			method: "get_current",
+			doc: frm.doc,
+			callback: function(r) {
+				frm.refresh_field("current_value");
+			}
+		});
+	},
+
+	update: function(frm) {
+		frappe.call({
+			method: "update_series",
+			doc: frm.doc,
+			callback: function(r) {
+				frm.events.get_doc_and_prefix(frm);
+			}
+		});
 	}
-
-	if(doc.select_doc_for_series)
-		return $c_obj(doc,'get_options','',callback);
-}
-
-cur_frm.cscript.update = function() {
-	return cur_frm.call_server('update_series', '', cur_frm.cscript.update_selects);
-}
-
-cur_frm.cscript.prefix = function(doc, dt, dn) {
-	return cur_frm.call_server('get_current', '', function(r) {
-		refresh_field('current_value');
-	});
-}
+});
diff --git a/erpnext/setup/doctype/naming_series/naming_series.json b/erpnext/setup/doctype/naming_series/naming_series.json
index 0daf1a1..f936dcf 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.json
+++ b/erpnext/setup/doctype/naming_series/naming_series.json
@@ -1,29 +1,40 @@
 {
  "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
+ "beta": 0, 
  "creation": "2013-01-25 11:35:08", 
  "custom": 0, 
  "description": "Set prefix for numbering series on your transactions", 
  "docstatus": 0, 
  "doctype": "DocType", 
+ "editable_grid": 0, 
  "fields": [
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "description": "Set prefix for numbering series on your transactions", 
    "fieldname": "setup_series", 
    "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": "Setup Series", 
+   "length": 0, 
    "no_copy": 0, 
    "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, 
@@ -31,20 +42,28 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "select_doc_for_series", 
    "fieldtype": "Select", 
    "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": "Select Transaction", 
+   "length": 0, 
    "no_copy": 0, 
    "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, 
@@ -52,21 +71,30 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "select_doc_for_series", 
    "fieldname": "help_html", 
    "fieldtype": "HTML", 
    "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": "Help HTML", 
+   "length": 0, 
    "no_copy": 0, 
    "options": "<div class=\"well\">\nEdit list of Series in the box below. Rules:\n<ul>\n<li>Each Series Prefix on a new line.</li>\n<li>Allowed special characters are \"/\" and \"-\"</li>\n<li>Optionally, set the number of digits in the series using dot (.) followed by hashes (#). For example, \".####\" means that the series will have four digits. Default is five digits.</li>\n</ul>\nExamples:<br>\nINV-<br>\nINV-10-<br>\nINVK-<br>\nINV-.####<br>\n</div>", 
    "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, 
@@ -74,20 +102,29 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "select_doc_for_series", 
    "fieldname": "set_options", 
    "fieldtype": "Text", 
    "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": "Series List for this Transaction", 
+   "length": 0, 
    "no_copy": 0, 
    "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, 
@@ -95,21 +132,30 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "select_doc_for_series", 
    "description": "Check this if you want to force the user to select a series before saving. There will be no default if you check this.", 
    "fieldname": "user_must_always_select", 
    "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": "User must always select", 
+   "length": 0, 
    "no_copy": 0, 
    "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, 
@@ -117,20 +163,30 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "select_doc_for_series", 
    "fieldname": "update", 
    "fieldtype": "Button", 
    "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": "Update", 
+   "length": 0, 
    "no_copy": 0, 
+   "options": "", 
    "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, 
@@ -138,21 +194,29 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "description": "Change the starting / current sequence number of an existing series.", 
    "fieldname": "update_series", 
    "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": "Update Series", 
+   "length": 0, 
    "no_copy": 0, 
    "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, 
@@ -160,20 +224,28 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "prefix", 
    "fieldtype": "Select", 
    "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": "Prefix", 
+   "length": 0, 
    "no_copy": 0, 
    "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, 
@@ -181,21 +253,29 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "description": "This is the number of the last created transaction with this prefix", 
    "fieldname": "current_value", 
    "fieldtype": "Int", 
    "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": "Current Value", 
+   "length": 0, 
    "no_copy": 0, 
    "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, 
@@ -203,21 +283,29 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "update_series_start", 
    "fieldtype": "Button", 
    "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": "Update Series Number", 
+   "length": 0, 
    "no_copy": 0, 
    "options": "update_series_start", 
    "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, 
@@ -225,16 +313,18 @@
    "unique": 0
   }
  ], 
+ "has_web_view": 0, 
  "hide_heading": 0, 
  "hide_toolbar": 1, 
  "icon": "fa fa-sort-by-order", 
  "idx": 1, 
+ "image_view": 0, 
  "in_create": 0, 
- "in_dialog": 0, 
  "is_submittable": 0, 
  "issingle": 1, 
  "istable": 0, 
- "modified": "2015-02-05 05:11:41.473793", 
+ "max_attachments": 0, 
+ "modified": "2017-08-17 03:41:37.685910", 
  "modified_by": "Administrator", 
  "module": "Setup", 
  "name": "Naming Series", 
@@ -261,6 +351,10 @@
    "write": 1
   }
  ], 
+ "quick_entry": 0, 
  "read_only": 1, 
- "read_only_onload": 0
+ "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
+ "track_changes": 0, 
+ "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py
index 536b72f..4534584 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.py
+++ b/erpnext/setup/doctype/naming_series/naming_series.py
@@ -21,7 +21,6 @@
 				where fieldname='naming_series'""")))
 
 		doctypes = list(set(get_doctypes_with_read()) | set(doctypes))
-
 		prefixes = ""
 		for d in doctypes:
 			options = ""
@@ -34,9 +33,8 @@
 
 			if options:
 				prefixes = prefixes + "\n" + options
-
 		prefixes.replace("\n\n", "\n")
-		prefixes = "\n".join(sorted(prefixes.split()))
+		prefixes = "\n".join(sorted(prefixes.split("\n")))
 
 		return {
 			"transactions": "\n".join([''] + sorted(doctypes)),
@@ -112,9 +110,7 @@
 				where dt.name = df.dt and df.fieldname='naming_series' and dt.name != %s""",
 				self.select_doc_for_series)
 			))
-		sr = [[frappe.get_meta(p).get_field("naming_series").options, p]
-			for p in parent]
-
+		sr = [[frappe.get_meta(p).get_field("naming_series").options, p] for p in parent]
 		dt = frappe.get_doc("DocType", self.select_doc_for_series)
 		options = self.scrub_options_list(self.set_options.split("\n"))
 		for series in options:
diff --git a/erpnext/setup/doctype/naming_series/test_naming_series.js b/erpnext/setup/doctype/naming_series/test_naming_series.js
new file mode 100644
index 0000000..22b664b
--- /dev/null
+++ b/erpnext/setup/doctype/naming_series/test_naming_series.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: Naming Series", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially([
+		// insert a new Naming Series
+		() => frappe.tests.make('Naming Series', [
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index 7b71675..9bf15ce 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 
 import frappe
 from frappe import _
@@ -19,10 +19,10 @@
 
 def check_setup_wizard_not_completed():
 	if frappe.db.get_default('desktop:home_page') == 'desktop':
-		print
-		print "ERPNext can only be installed on a fresh site where the setup wizard is not completed"
-		print "You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall"
-		print
+		print()
+		print("ERPNext can only be installed on a fresh site where the setup wizard is not completed")
+		print("You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall")
+		print()
 		return False
 
 def set_single_defaults():
diff --git a/erpnext/stock/doctype/batch/test_batch.js b/erpnext/stock/doctype/batch/test_batch.js
new file mode 100644
index 0000000..af7f50f
--- /dev/null
+++ b/erpnext/stock/doctype/batch/test_batch.js
@@ -0,0 +1,23 @@
+QUnit.module('Stock');
+
+QUnit.test("test Batch", function(assert) {
+	assert.expect(1);
+	let done = assert.async();
+	frappe.run_serially([
+		() => {
+			return frappe.tests.make('Batch', [
+				{batch_id:'TEST-BATCH-001'},
+				{item:'Test Product 4'},
+				{expiry_date:frappe.datetime.add_days(frappe.datetime.now_date(), 2)},
+			]);
+		},
+		() => cur_frm.save(),
+		() => {
+			// get_item_details
+			assert.ok(cur_frm.doc.batch_id=='TEST-BATCH-001', "Batch Id correct");
+		},
+		() => frappe.timeout(0.3),
+		() => done()
+	]);
+});
+
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index 4477c1d..41f8b84 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -3113,7 +3113,7 @@
    "in_filter": 0, 
    "in_global_search": 0, 
    "in_list_view": 0, 
-   "in_standard_filter": 1, 
+   "in_standard_filter": 0, 
    "label": "Installation Status", 
    "length": 0, 
    "no_copy": 0, 
@@ -3487,7 +3487,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2017-08-09 15:44:14.253457", 
+ "modified": "2017-08-23 13:25:34.182268", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Delivery Note", 
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 82beff8..f5a99af 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -92,9 +92,9 @@
 	def so_required(self):
 		"""check in manage account if sales order required or not"""
 		if frappe.db.get_value("Selling Settings", None, 'so_required') == 'Yes':
-			 for d in self.get('items'):
-				 if not d.against_sales_order:
-					 frappe.throw(_("Sales Order required for Item {0}").format(d.item_code))
+			for d in self.get('items'):
+				if not d.against_sales_order:
+					frappe.throw(_("Sales Order required for Item {0}").format(d.item_code))
 
 	def validate(self):
 		self.validate_posting_time()
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index d12c288..2d089c4 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -84,9 +84,9 @@
 
 	def po_required(self):
 		if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes':
-			 for d in self.get('items'):
-				 if not d.purchase_order:
-					 frappe.throw(_("Purchase Order number required for Item {0}").format(d.item_code))
+			for d in self.get('items'):
+				if not d.purchase_order:
+					frappe.throw(_("Purchase Order number required for Item {0}").format(d.item_code))
 
 	def get_already_received_qty(self, po, po_detail):
 		qty = frappe.db.sql("""select sum(qty) from `tabPurchase Receipt Item`
diff --git a/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt_for_serialize_item.js b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt_for_serialize_item.js
new file mode 100644
index 0000000..ffd0664
--- /dev/null
+++ b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt_for_serialize_item.js
@@ -0,0 +1,35 @@
+QUnit.module('Stock');
+
+QUnit.test("test material receipt", function(assert) {
+	assert.expect(2);
+	let done = assert.async();
+	frappe.run_serially([
+		() => {
+			return frappe.tests.make('Stock Entry', [
+				{purpose:'Material Receipt'},
+				{to_warehouse:'Stores - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+				{items: [
+					[
+						{'item_code': 'Test Product 4'},
+						{'qty': 5},
+						{'batch_no':'TEST-BATCH-001'},
+						{'serial_no':'Test-Product-001\nTest-Product-002\nTest-Product-003\nTest-Product-004\nTest-Product-005'},
+						{'basic_rate':100},
+					]
+				]},
+			]);
+		},
+		() => cur_frm.save(),
+		() => frappe.click_button('Update Rate and Availability'),
+		() => {
+			// get_item_details
+			assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
+			assert.ok(cur_frm.doc.total_incoming_value==500, " Incoming Value correct");
+		},
+		() => frappe.tests.click_button('Submit'),
+		() => frappe.tests.click_button('Yes'),
+		() => frappe.timeout(0.3),
+		() => done()
+	]);
+});
+
diff --git a/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer_for_manufacture.js b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer_for_manufacture.js
new file mode 100644
index 0000000..e8b2973
--- /dev/null
+++ b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer_for_manufacture.js
@@ -0,0 +1,34 @@
+QUnit.module('Stock');
+
+QUnit.test("test material Transfer to manufacture", function(assert) {
+	assert.expect(3);
+	let done = assert.async();
+	frappe.run_serially([
+		() => {
+			return frappe.tests.make('Stock Entry', [
+				{purpose:'Material Transfer for Manufacture'},
+				{from_warehouse:'Stores - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+				{to_warehouse:'Work In Progress - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+				{items: [
+					[
+						{'item_code': 'Test Product 1'},
+						{'qty': 1},
+					]
+				]},
+			]);
+		},
+		() => cur_frm.save(),
+		() => frappe.click_button('Update Rate and Availability'),
+		() => {
+			// get_item_details
+			assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
+			assert.ok(cur_frm.doc.total_outgoing_value==100, " Outgoing Value correct");
+			assert.ok(cur_frm.doc.total_incoming_value==100, " Incoming Value correct");
+		},
+		() => frappe.tests.click_button('Submit'),
+		() => frappe.tests.click_button('Yes'),
+		() => frappe.timeout(0.3),
+		() => done()
+	]);
+});
+
diff --git a/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_subcontract.js b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_subcontract.js
new file mode 100644
index 0000000..131d3ca
--- /dev/null
+++ b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_subcontract.js
@@ -0,0 +1,34 @@
+QUnit.module('Stock');
+
+QUnit.test("test material Transfer to manufacture", function(assert) {
+	assert.expect(3);
+	let done = assert.async();
+	frappe.run_serially([
+		() => {
+			return frappe.tests.make('Stock Entry', [
+				{purpose:'Subcontract'},
+				{from_warehouse:'Work In Progress - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+				{to_warehouse:'Finished Goods - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+				{items: [
+					[
+						{'item_code': 'Test Product 1'},
+						{'qty': 1},
+					]
+				]},
+			]);
+		},
+		() => cur_frm.save(),
+		() => frappe.click_button('Update Rate and Availability'),
+		() => {
+			// get_item_details
+			assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
+			assert.ok(cur_frm.doc.total_outgoing_value==100, " Outgoing Value correct");
+			assert.ok(cur_frm.doc.total_incoming_value==100, " Incoming Value correct");
+		},
+		() => frappe.tests.click_button('Submit'),
+		() => frappe.tests.click_button('Yes'),
+		() => frappe.timeout(0.3),
+		() => done()
+	]);
+});
+
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.py b/erpnext/stock/doctype/stock_settings/stock_settings.py
index d9d9568..186eaee 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.py
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.py
@@ -18,7 +18,7 @@
 			self.get("item_naming_by")=="Naming Series", hide_name_field=True)
 
 		stock_frozen_limit = 356
-		submitted_stock_frozen = self.stock_frozen_upto_days
+		submitted_stock_frozen = self.stock_frozen_upto_days or 0
 		if submitted_stock_frozen > stock_frozen_limit:
 			self.stock_frozen_upto_days = stock_frozen_limit
 			frappe.msgprint (_("`Freeze Stocks Older Than` should be smaller than %d days.") %stock_frozen_limit)
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 403d5cb..6a4ac43 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -1,7 +1,7 @@
 # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
 # License: GNU General Public License v3. See license.txt
 
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
 import frappe
 
 from frappe.utils import flt, cstr, nowdate, nowtime
@@ -170,7 +170,7 @@
 			where item_code=%s and warehouse=%s and docstatus < 2""", (d[0], d[1]))
 
 		if serial_nos and flt(serial_nos[0][0]) != flt(d[2]):
-			print d[0], d[1], d[2], serial_nos[0][0]
+			print(d[0], d[1], d[2], serial_nos[0][0])
 
 		sle = frappe.db.sql("""select valuation_rate, company from `tabStock Ledger Entry`
 			where item_code = %s and warehouse = %s and ifnull(is_cancelled, 'No') = 'No'
@@ -244,7 +244,7 @@
 	i = 0
 	for voucher_type, voucher_no in vouchers:
 		i+=1
-		print i, "/", len(vouchers), voucher_type, voucher_no
+		print(i, "/", len(vouchers), voucher_type, voucher_no)
 		try:
 			for dt in ["Stock Ledger Entry", "GL Entry"]:
 				frappe.db.sql("""delete from `tab%s` where voucher_type=%s and voucher_no=%s"""%
@@ -259,9 +259,9 @@
 			doc.update_stock_ledger()
 			doc.make_gl_entries(repost_future_gle=False)
 			frappe.db.commit()
-		except Exception, e:
-			print frappe.get_traceback()
+		except Exception as e:
+			print(frappe.get_traceback())
 			rejected.append([voucher_type, voucher_no])
 			frappe.db.rollback()
 
-	print rejected
+	print(rejected)
diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js
index c1b76e5..306736f 100644
--- a/erpnext/support/doctype/issue/issue.js
+++ b/erpnext/support/doctype/issue/issue.js
@@ -24,7 +24,7 @@
 			frm.timeline.wrapper.find('.comment-header .asset-details .btn-add-to-kb').remove();
 			$('<button class="btn btn-xs btn-link btn-add-to-kb text-muted hidden-xs pull-right">'+
 				__('Help Article') + '</button>')
-				.appendTo(frm.timeline.wrapper.find('.comment-header .asset-details'))
+				.appendTo(frm.timeline.wrapper.find('.comment-header .asset-details:not([data-communication-type="Comment"])'))
 				.on('click', function() {
 					var content = $(this).parents('.timeline-item:first').find('.timeline-item-content').html();
 					var doc = frappe.model.get_new_doc('Help Article');
diff --git a/erpnext/templates/includes/product_page.js b/erpnext/templates/includes/product_page.js
index 3905959..b2d5ad9 100644
--- a/erpnext/templates/includes/product_page.js
+++ b/erpnext/templates/includes/product_page.js
@@ -73,7 +73,7 @@
 			}
 		}
 
-		if (window.location.search.indexOf(item_code)!==-1) {
+		if (window.location.search == ("?variant=" + item_code) || window.location.search.includes(item_code)) {
 			return;
 		}
 
diff --git a/erpnext/templates/utils.py b/erpnext/templates/utils.py
index e46fed6..6ebe411 100644
--- a/erpnext/templates/utils.py
+++ b/erpnext/templates/utils.py
@@ -36,11 +36,11 @@
     ))
 
     if customer:
-    	opportunity.customer = customer[0][0]
+        opportunity.customer = customer[0][0]
     elif lead:
-    	opportunity.lead = lead
+        opportunity.lead = lead
     else:
-    	opportunity.lead = new_lead.name
+        opportunity.lead = new_lead.name
 
     opportunity.insert(ignore_permissions=True)
 
diff --git a/erpnext/tests/ui/tests.txt b/erpnext/tests/ui/tests.txt
index cb33c90..653aeec 100644
--- a/erpnext/tests/ui/tests.txt
+++ b/erpnext/tests/ui/tests.txt
@@ -66,12 +66,23 @@
 erpnext/hr/doctype/job_opening/test_job_opening.js
 erpnext/hr/doctype/job_applicant/test_job_applicant.js
 erpnext/hr/doctype/offer_letter/test_offer_letter.js
+erpnext/hr/doctype/appraisal_template/test_appraisal_template.js
+erpnext/hr/doctype/appraisal/test_appraisal.js
+erpnext/hr/doctype/expense_claim_type/test_expense_claim_type.js
+erpnext/hr/doctype/expense_claim/test_expense_claim.js
+erpnext/hr/doctype/training_event/test_training_event.js
+erpnext/hr/doctype/training_result_employee/test_training_result.js
+erpnext/hr/doctype/training_feedback/test_training_feedback.js
+erpnext/hr/doctype/loan_type/test_loan_type.js
+erpnext/hr/doctype/employee_loan_application/test_employee_loan_application.js
+erpnext/hr/doctype/employee_loan/test_employee_loan.js
 erpnext/buying/doctype/supplier/test_supplier.js
 erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation.js
 erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation.js
 erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_taxes_and_charges.js
 erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice.js
 erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment.js
+erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment_request.js
 erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.js
 erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_item_wise_discount.js
 erpnext/buying/doctype/purchase_order/tests/test_purchase_order.js
@@ -102,4 +113,12 @@
 erpnext/schools/doctype/assessment_plan/test_assessment_plan.js
 erpnext/schools/doctype/assessment_result/test_assessment_result.js
 erpnext/schools/doctype/assessment_result_tool/test_assessment_result_tool.js
+erpnext/accounts/doctype/journal_entry/test_journal_entry.js
 erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.js
+erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js
+erpnext/selling/doctype/quotation/tests/test_quotation_submit_cancel_amend.js
+erpnext/stock/doctype/batch/test_batch.js
+erpnext/accounts/doctype/bank_reconciliation/test_bank_reconciliation.js
+erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt_for_serialize_item.js
+erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer_for_manufacture.js
+erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_subcontract.js
diff --git a/erpnext/utilities/__init__.py b/erpnext/utilities/__init__.py
index 944f978..0f641b2 100644
--- a/erpnext/utilities/__init__.py
+++ b/erpnext/utilities/__init__.py
@@ -1,5 +1,5 @@
 ## temp utility
-
+from __future__ import print_function
 import frappe
 from erpnext.utilities.activation import get_level
 from frappe.utils import cstr
@@ -12,7 +12,7 @@
 
 		for f in dt.fields:
 			if f.fieldname == d.fieldname and f.fieldtype in ("Text", "Small Text"):
-				print f.parent, f.fieldname
+				print(f.parent, f.fieldname)
 				f.fieldtype = "Text Editor"
 				dt.save()
 				break