Merge branch 'develop' of https://github.com/frappe/erpnext into payment-terms
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index ecf0d35..48296e7 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -4,7 +4,7 @@
 import frappe
 from erpnext.hooks import regional_overrides
 
-__version__ = '8.8.6'
+__version__ = '8.9.2'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
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/account/chart_of_accounts/verified/tw_chart_of_accounts.json b/erpnext/accounts/doctype/account/chart_of_accounts/verified/tw_chart_of_accounts.json
new file mode 100644
index 0000000..a79283a
--- /dev/null
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/tw_chart_of_accounts.json
@@ -0,0 +1,722 @@
+{
+    "country_code": "tw", 
+    "name": "Taiwan - Chart of Accounts", 
+    "tree": {
+        "1-\u8cc7\u7522": {
+            "11~12-\u6d41\u52d5\u8cc7\u7522": {
+                "111-\u73fe\u91d1\u53ca\u7d04\u7576\u73fe\u91d1": {
+                    "1111-\u5eab\u5b58\u73fe\u91d1": {
+                        "account_type": "Cash"
+                    },
+                    "1112-\u96f6\u7528\u91d1/\u9031\u8f49\u91d1": {
+                        "account_type": "Cash"
+                    },
+                    "1113-\u9280\u884c\u5b58\u6b3e": {
+                        "account_type": "Bank", 
+                        "\u4e2d\u570b\u4fe1\u8a17": {
+                            "account_type": "Bank"
+                        },
+                        "\u53f0\u5317\u5bcc\u90a6": {
+                            "account_type": "Bank"
+                        }
+                    },
+                    "1116-\u5728\u9014\u73fe\u91d1": {
+                        "account_type": "Cash"
+                    },
+                    "1117-\u7d04\u7576\u73fe\u91d1": {
+                        "account_type": "Cash"
+                    },
+                    "1118-\u5176\u4ed6\u73fe\u91d1\u53ca\u7d04\u7576\u73fe\u91d1": {
+                        "account_type": "Cash"
+                    },
+                    "account_type": "Cash"
+                },
+                "112-\u77ed\u671f\u6295\u8cc7": {
+                    "1121-\u77ed\u671f\u6295\u8cc7 \u2014\u80a1\u7968": {}
+                },
+                "113-\u61c9\u6536\u7968\u64da": {
+                    "1131-\u61c9\u6536\u7968\u64da": {
+                        "account_type": "Receivable"
+                    },
+                    "1132-\u61c9\u6536\u7968\u64da\u8cbc\u73fe ": {
+                        "account_type": "Receivable"
+                    },
+                    "1138-\u5176\u4ed6\u61c9\u6536\u7968\u64da ": {
+                        "account_type": "Receivable"
+                    },
+                    "1139-\u5099\u62b5\u5446\u5e33 \uff0d\u61c9\u6536\u7968\u64da ": {
+                        "account_type": "Receivable"
+                    },
+                    "account_type": "Receivable"
+                },
+                "114-\u61c9\u6536\u5e33\u6b3e": {
+                    "1141-\u61c9\u6536\u5e33\u6b3e ": {
+                        "account_type": "Receivable"
+                    },
+                    "1142-\u61c9\u6536\u5206\u671f\u5e33\u6b3e ": {
+                        "account_type": "Receivable"
+                    },
+                    "1149-\u5099\u62b5\u5446\u5e33 \uff0d\u61c9\u6536\u5e33\u6b3e ": {
+                        "account_type": "Receivable"
+                    },
+                    "account_type": "Receivable"
+                },
+                "118-\u5176\u4ed6\u61c9\u6536\u6b3e": {
+                    "1184-\u61c9\u6536\u6536\u76ca": {
+                        "account_type": "Receivable"
+                    },
+                    "1185-\u61c9\u6536\u9000\u7a05\u6b3e": {
+                        "account_type": "Receivable"
+                    },
+                    "1189-\u5099\u62b5\u5446\u5e33 \u2014 \u5176\u4ed6\u61c9\u6536\u6b3e ": {
+                        "account_type": "Receivable"
+                    },
+                    "account_type": "Receivable"
+                },
+                "121~122-\u5b58\u8ca8": {
+                    "1219-\u5099\u62b5\u5b58\u8ca8\u8dcc\u50f9\u640d\u5931": {},
+                    "1229-\u5099\u62b5\u5b58\u8ca8\u8dcc\u50f9\u640d\u5931": {},
+                    "account_type": "Stock", 
+                    "is_group": 1
+                },
+                "125-\u9810\u4ed8\u8cbb\u7528": {
+                    "1251-\u9810\u4ed8\u85aa\u8cc7": {},
+                    "1252-\u9810\u4ed8\u79df\u91d1": {},
+                    "1253-\u9810\u4ed8\u4fdd\u96aa\u8cbb": {},
+                    "1254-\u7528\u54c1\u76e4\u5b58": {},
+                    "1255-\u9810\u4ed8\u6240\u5f97\u7a05": {},
+                    "1258-\u5176\u4ed6\u9810\u4ed8\u8cbb\u7528": {}
+                },
+                "126-\u9810\u4ed8\u6b3e\u9805": {
+                    "1261-\u9810\u4ed8\u8ca8\u6b3e": {},
+                    "1268-\u5176\u4ed6\u9810\u4ed8\u6b3e\u9805": {}
+                },
+                "128~129-\u5176\u4ed6\u6d41\u52d5\u8cc7\u7522": {
+                    "1281-\u9032\u9805\u7a05\u984d": {},
+                    "1282-\u7559\u62b5\u7a05\u984d": {},
+                    "1283-\u66ab\u4ed8\u6b3e": {},
+                    "1284-\u4ee3\u4ed8\u6b3e": {},
+                    "1285-\u54e1\u5de5\u501f\u652f": {}
+                }
+            },
+            "13-\u57fa\u91d1\u53ca\u9577\u671f\u6295\u8cc7": {
+                "131-\u57fa\u91d1": {
+                    "1311-\u511f\u50b5\u57fa\u91d1": {},
+                    "1313-\u610f\u5916\u640d\u5931\u6e96\u5099\u57fa\u91d1": {},
+                    "1314-\u9000\u4f11\u57fa\u91d1": {},
+                    "1318-\u5176\u4ed6\u57fa\u91d1": {}
+                },
+                "132-\u9577\u671f\u6295\u8cc7": {
+                    "1321-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7": {},
+                    "1322-\u9577\u671f\u50b5\u5238\u6295\u8cc7": {},
+                    "1323-\u9577\u671f\u4e0d\u52d5\u7522\u6295\u8cc7": {},
+                    "1328-\u5176\u4ed6\u9577\u671f\u6295\u8cc7": {}
+                }
+            },
+            "14~15-\u56fa\u5b9a\u8cc7\u7522": {
+                "141-\u571f\u5730": {
+                    "1411-\u571f\u5730": {
+                        "account_type": "Fixed Asset"
+                    },
+                    "account_type": "Fixed Asset"
+                },
+                "142-\u571f\u5730\u6539\u826f\u7269": {
+                    "1421-\u571f\u5730\u6539\u826f\u7269": {
+                        "account_type": "Fixed Asset"
+                    },
+                    "account_type": "Fixed Asset"
+                },
+                "143-\u623f\u5c4b\u53ca\u5efa\u7269": {
+                    "1431-\u623f\u5c4b\u53ca\u5efa\u7269": {
+                        "account_type": "Fixed Asset"
+                    },
+                    "account_type": "Fixed Asset"
+                },
+                "144~146-\u6a5f(\u5668)\u5177\u53ca\u8a2d\u5099": {
+                    "1441-\u6a5f(\u5668)\u5177": {
+                        "account_type": "Fixed Asset"
+                    },
+                    "account_type": "Fixed Asset"
+                },
+                "151-\u79df\u8cc3\u8cc7\u7522": {
+                    "1511-\u79df\u8cc3\u8cc7\u7522": {
+                        "account_type": "Fixed Asset"
+                    },
+                    "account_type": "Fixed Asset"
+                },
+                "152-\u79df\u8cc3\u6b0a\u76ca\u6539\u826f": {
+                    "1521-\u79df\u8cc3\u6b0a\u76ca\u6539\u826f": {
+                        "account_type": "Fixed Asset"
+                    },
+                    "account_type": "Fixed Asset"
+                },
+                "156-\u672a\u5b8c\u5de5\u7a0b\u53ca\u9810\u4ed8\u8cfc\u7f6e\u8a2d\u5099\u6b3e": {
+                    "1561-\u672a\u5b8c\u5de5\u7a0b": {
+                        "account_type": "Fixed Asset"
+                    },
+                    "account_type": "Fixed Asset"
+                },
+                "158-\u96dc\u9805\u56fa\u5b9a\u8cc7\u7522": {
+                    "1581-\u96dc\u9805\u56fa\u5b9a\u8cc7\u7522": {
+                        "account_type": "Fixed Asset"
+                    },
+                    "account_type": "Fixed Asset"
+                },
+                "account_type": "Fixed Asset"
+            },
+            "16-\u905e\u8017\u8cc7\u7522": {
+                "161-\u905e\u8017\u8cc7\u7522": {
+                    "is_group": 1
+                }
+            },
+            "17-\u7121\u5f62\u8cc7\u7522": {
+                "171-\u5546\u6a19\u6b0a": {
+                    "1711-\u5546\u6a19\u6b0a": {}
+                },
+                "172-\u5c08\u5229\u6b0a": {
+                    "1721-\u5c08\u5229\u6b0a": {}
+                },
+                "176-\u5546\u8b7d": {
+                    "1761-\u5546\u8b7d": {}
+                },
+                "177-\u958b\u8fa6\u8cbb": {
+                    "1771-\u958b\u8fa6\u8cbb": {}
+                },
+                "178-\u5176\u4ed6\u7121\u5f62\u8cc7\u7522": {
+                    "1781-\u905e\u5ef6\u9000\u4f11\u91d1\u6210\u672c": {}
+                }
+            },
+            "18-\u5176\u4ed6\u8cc7\u7522": {
+                "181-\u905e\u5ef6\u8cc7\u7522": {
+                    "1811-\u50b5\u5238\u767c\u884c\u6210\u672c": {},
+                    "1812-\u9577\u671f\u9810\u4ed8\u79df\u91d1": {},
+                    "1813-\u9577\u671f\u9810\u4ed8\u4fdd\u96aa\u8cbb": {},
+                    "1814-\u905e\u5ef6\u6240\u5f97\u7a05\u8cc7\u7522": {},
+                    "1815-\u9810\u4ed8\u9000\u4f11\u91d1": {},
+                    "1818-\u5176\u4ed6\u905e\u5ef6\u8cc7\u7522": {}
+                },
+                "182-\u9592\u7f6e\u8cc7\u7522": {
+                    "1821-\u9592\u7f6e\u8cc7\u7522": {}
+                },
+                "184-\u9577\u671f\u61c9\u6536\u7968\u64da\u53ca\u6b3e\u9805\u8207\u50ac\u6536\u5e33\u6b3e": {
+                    "1841-\u9577\u671f\u61c9\u6536\u7968\u64da": {
+                        "account_type": "Receivable"
+                    },
+                    "1842-\u9577\u671f\u61c9\u6536\u5e33\u6b3e": {
+                        "account_type": "Receivable"
+                    },
+                    "1843-\u50ac\u6536\u5e33\u6b3e": {
+                        "account_type": "Receivable"
+                    },
+                    "1848-\u5176\u4ed6\u9577\u671f\u61c9\u6536\u6b3e\u9805": {
+                        "account_type": "Receivable"
+                    },
+                    "1849-\u5099\u62b5\u5446\u5e33\u2014\u9577\u671f\u61c9\u6536\u7968\u64da\u53ca\u6b3e\u9805\u8207\u50ac\u6536\u5e33\u6b3e": {
+                        "account_type": "Receivable"
+                    },
+                    "account_type": "Receivable"
+                },
+                "185-\u51fa\u79df\u8cc7\u7522": {
+                    "1851-\u51fa\u79df\u8cc7\u7522": {},
+                    "1858-\u51fa\u79df\u8cc7\u7522 \u2014\u91cd\u4f30\u589e\u503c": {},
+                    "1859-\u7d2f\u7a4d\u6298\u820a \u2014\u51fa\u79df\u8cc7\u7522": {
+                        "account_type": "Accumulated Depreciation"
+                    }
+                },
+                "186-\u5b58\u51fa\u4fdd\u8b49\u91d1": {
+                    "1861-\u5b58\u51fa\u4fdd\u8b49\u91d1": {}
+                },
+                "188-\u96dc\u9805\u8cc7\u7522": {
+                    "1881-\u53d7\u9650\u5236\u5b58\u6b3e": {},
+                    "1888-\u96dc\u9805\u8cc7\u7522 \u2014\u5176\u4ed6": {}
+                }
+            },
+            "Temporary Accounts": {
+                "Temporary Opening": {
+                    "account_type": "Temporary"
+                },
+                "account_type": "Temporary"
+            },
+            "root_type": "Asset"
+        },
+        "2-\u8ca0\u50b5": {
+            "21~22-\u6d41\u52d5\u8ca0\u50b5": {
+                "211-\u77ed\u671f\u501f\u6b3e": {
+                    "2111-\u9280\u884c\u900f\u652f": {},
+                    "2112-\u9280\u884c\u501f\u6b3e": {}
+                },
+                "212-\u61c9\u4ed8\u77ed\u671f\u7968\u5238": {
+                    "2121-\u61c9\u4ed8\u5546\u696d\u672c\u7968": {
+                        "account_type": "Payable"
+                    },
+                    "2122-\u9280\u884c\u627f\u514c\u532f\u7968": {
+                        "account_type": "Payable"
+                    },
+                    "account_type": "Payable"
+                },
+                "213-\u61c9\u4ed8\u7968\u64da": {
+                    "2131-\u61c9\u4ed8\u7968\u64da": {
+                        "account_type": "Payable"
+                    },
+                    "account_type": "Payable"
+                },
+                "214-\u61c9\u4ed8\u5e33\u6b3e": {
+                    "2141-\u61c9\u4ed8\u5e33\u6b3e": {
+                        "account_type": "Payable"
+                    },
+                    "account_type": "Payable"
+                },
+                "216-\u61c9\u4ed8\u6240\u5f97\u7a05": {
+                    "2161-\u61c9\u4ed8\u6240\u5f97\u7a05": {
+                        "account_type": "Tax", 
+                        "tax_rate": 5.0
+                    },
+                    "account_type": "Tax", 
+                    "tax_rate": 5.0
+                },
+                "217-\u61c9\u4ed8\u8cbb\u7528": {
+                    "2171-\u61c9\u4ed8\u85aa\u5de5": {},
+                    "2172-\u61c9\u4ed8\u79df\u91d1": {},
+                    "2173-\u61c9\u4ed8\u5229\u606f": {},
+                    "2174-\u61c9\u4ed8\u71df\u696d\u7a05": {},
+                    "2175-\u61c9\u4ed8\u7a05\u6350 \u2014\u5176\u4ed6": {
+                        "account_type": "Tax", 
+                        "tax_rate": 5.0
+                    },
+                    "2178-\u5176\u4ed6\u61c9\u4ed8\u8cbb\u7528": {}
+                },
+                "218~219-\u5176\u4ed6\u61c9\u4ed8\u6b3e": {
+                    "2184-\u61c9\u4ed8\u571f\u5730\u623f\u5c4b\u6b3e": {},
+                    "2185-\u61c9\u4ed8\u8a2d\u5099\u6b3e": {},
+                    "2192-\u61c9\u4ed8\u80a1\u5229": {}
+                },
+                "226-\u9810\u6536\u6b3e\u9805": {
+                    "2261-\u9810\u6536\u8ca8\u6b3e": {},
+                    "2262-\u9810\u6536\u6536\u5165": {},
+                    "2268-\u5176\u4ed6\u9810\u6536\u6b3e": {}
+                },
+                "227-\u4e00\u5e74\u6216\u4e00\u71df\u696d\u9031\u671f\u5167\u5230\u671f\u9577\u671f\u8ca0\u50b5": {
+                    "is_group": 1
+                },
+                "228~229-\u5176\u4ed6\u6d41\u52d5\u8ca0\u50b5": {
+                    "2281-\u92b7\u9805\u7a05\u984d": {},
+                    "2283-\u66ab\u6536\u6b3e ": {},
+                    "2284-\u4ee3\u6536\u6b3e": {},
+                    "2285-\u4f30\u8a08\u552e\u5f8c\u670d\u52d9/\u4fdd\u56fa\u8ca0\u50b5": {},
+                    "2291-\u905e\u5ef6\u6240\u5f97\u7a05\u8ca0\u50b5": {},
+                    "2292-\u905e\u5ef6\u514c\u63db\u5229\u76ca": {}
+                }
+            },
+            "23-\u9577\u671f\u8ca0\u50b5": {
+                "231-\u61c9\u4ed8\u516c\u53f8\u50b5": {
+                    "2311-\u61c9\u4ed8\u516c\u53f8\u50b5": {},
+                    "2319-\u61c9\u4ed8\u516c\u53f8\u50b5\u6ea2(\u6298)\u50f9": {}
+                },
+                "232-\u9577\u671f\u501f\u6b3e": {
+                    "2321-\u9577\u671f\u9280\u884c\u501f\u6b3e": {},
+                    "2324-\u9577\u671f\u501f\u6b3e \u2014\u696d\u4e3b": {},
+                    "2325-\u9577\u671f\u501f\u6b3e \u2014\u54e1\u5de5": {},
+                    "2327-\u9577\u671f\u501f\u6b3e \u2014\u95dc\u4fc2\u4eba": {},
+                    "2328-\u9577\u671f\u501f\u6b3e \u2014\u5176\u4ed6": {}
+                },
+                "233-\u9577\u671f\u61c9\u4ed8\u7968\u64da\u53ca\u6b3e\u9805": {
+                    "2331-\u9577\u671f\u61c9\u4ed8\u7968\u64da": {
+                        "account_type": "Payable"
+                    },
+                    "2332-\u9577\u671f\u61c9\u4ed8\u5e33\u6b3e": {
+                        "account_type": "Payable"
+                    },
+                    "2333-\u9577\u671f\u61c9\u4ed8\u79df\u8cc3\u8ca0\u50b5": {
+                        "account_type": "Payable"
+                    },
+                    "account_type": "Payable"
+                },
+                "234-\u4f30\u8a08\u61c9\u4ed8\u571f\u5730\u589e\u503c\u7a05": {
+                    "2341-\u4f30\u8a08\u61c9\u4ed8\u571f\u5730\u589e\u503c\u7a05": {}
+                },
+                "235-\u61c9\u8a08\u9000\u4f11\u91d1\u8ca0\u50b5": {
+                    "2351-\u61c9\u8a08\u9000\u4f11\u91d1\u8ca0\u50b5": {}
+                },
+                "238-\u5176\u4ed6\u9577\u671f\u8ca0\u50b5": {
+                    "2388-\u5176\u4ed6\u9577\u671f\u8ca0\u50b5\u2014\u5176\u4ed6": {}
+                }
+            },
+            "28-\u5176\u4ed6\u8ca0\u50b5": {
+                "281-\u905e\u5ef6\u8ca0\u50b5": {
+                    "2811-\u905e\u5ef6\u6536\u5165": {},
+                    "2814-\u905e\u5ef6\u6240\u5f97\u7a05\u8ca0\u50b5": {},
+                    "2818-\u5176\u4ed6\u905e\u5ef6\u8ca0\u50b5": {}
+                },
+                "286-\u5b58\u5165\u4fdd\u8b49\u91d1": {
+                    "2861-\u5b58\u5165\u4fdd\u8b49\u91d1": {}
+                },
+                "288-\u96dc\u9805\u8ca0\u50b5": {
+                    "2888-\u96dc\u9805\u8ca0\u50b5 \u2014\u5176\u4ed6": {}
+                }
+            },
+            "Stock Received But Not Billed": {
+                "account_type": "Stock Received But Not Billed"
+            },
+            "root_type": "Liability"
+        },
+        "3-\u696d\u4e3b\u6b0a\u76ca": {
+            "31-\u8cc7\u672c": {
+                "311-\u8cc7\u672c\uff08\u80a1\u672c\uff09 ": {
+                    "3111-\u666e\u901a\u80a1\u80a1\u672c": {},
+                    "3112-\u7279\u5225\u80a1\u80a1\u672c": {},
+                    "3113-\u9810\u6536\u80a1\u672c": {},
+                    "3114-\u5f85\u5206\u914d\u80a1\u7968\u80a1\u5229": {},
+                    "3115-\u8cc7\u672c": {}
+                }
+            },
+            "32-\u8cc7\u672c\u516c\u7a4d": {
+                "321-\u80a1\u7968\u6ea2\u50f9": {
+                    "3211-\u666e\u901a\u80a1\u80a1\u7968\u6ea2\u50f9": {},
+                    "3212-\u7279\u5225\u80a1\u80a1\u7968\u6ea2\u50f9": {}
+                },
+                "323-\u8cc7\u7522\u91cd\u4f30\u589e\u503c\u6e96\u5099": {
+                    "3231-\u8cc7\u7522\u91cd\u4f30\u589e\u503c\u6e96\u5099": {}
+                },
+                "324-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u516c\u7a4d": {
+                    "3241-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u516c\u7a4d": {}
+                },
+                "325-\u5408\u4f75\u516c\u7a4d": {
+                    "3251-\u5408\u4f75\u516c\u7a4d": {}
+                },
+                "326-\u53d7\u8d08\u516c\u7a4d": {
+                    "3261-\u53d7\u8d08\u516c\u7a4d": {}
+                },
+                "328-\u5176\u4ed6\u8cc7\u672c\u516c\u7a4d": {
+                    "3281-\u6b0a\u76ca\u6cd5\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u8cc7\u672c\u516c\u7a4d": {},
+                    "3282-\u8cc7\u672c\u516c\u7a4d\u2014 \u5eab\u85cf\u80a1\u7968\u4ea4\u6613": {}
+                }
+            },
+            "33-\u4fdd\u7559\u76c8\u9918(\u7d2f\u7a4d\u8667\u640d)": {
+                "331-\u6cd5\u5b9a\u76c8\u9918\u516c\u7a4d": {
+                    "3311-\u6cd5\u5b9a\u76c8\u9918\u516c\u7a4d": {}
+                },
+                "332-\u7279\u5225\u76c8\u9918\u516c\u7a4d": {
+                    "3321-\u610f\u5916\u640d\u5931\u6e96\u5099": {},
+                    "3322-\u6539\u826f\u64f4\u5145\u6e96\u5099": {},
+                    "3323-\u511f\u50b5\u6e96\u5099": {},
+                    "3328-\u5176\u4ed6\u7279\u5225\u76c8\u9918\u516c\u7a4d": {}
+                },
+                "335-\u672a\u5206\u914d\u76c8\u9918(\u7d2f\u7a4d\u8667\u640d) ": {
+                    "is_group": 1
+                }
+            },
+            "34-\u6b0a\u76ca\u8abf\u6574": {
+                "341-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {
+                    "3411-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {}
+                },
+                "342-\u7d2f\u7a4d\u63db\u7b97\u8abf\u6574\u6578": {
+                    "3421-\u7d2f\u7a4d\u63db\u7b97\u8abf\u6574\u6578": {}
+                },
+                "343-\u672a\u8a8d\u5217\u70ba\u9000\u4f11\u91d1\u6210\u672c\u4e4b\u6de8\u640d\u5931": {
+                    "3431-\u672a\u8a8d\u5217\u70ba\u9000\u4f11\u91d1\u6210\u672c\u4e4b\u6de8\u640d\u5931": {}
+                }
+            },
+            "35-\u5eab\u85cf\u80a1": {
+                "351-\u5eab\u85cf\u80a1": {
+                    "3511-\u5eab\u85cf\u80a1": {}
+                }
+            },
+            "36-\u5c11\u6578\u80a1\u6b0a": {
+                "361-\u5c11\u6578\u80a1\u6b0a": {
+                    "3611-\u5c11\u6578\u80a1\u6b0a": {}
+                }
+            },
+            "root_type": "Equity"
+        },
+        "4-\u71df\u696d\u6536\u5165": {
+            "41-\u92b7\u8ca8\u6536\u5165": {
+                "411-\u92b7\u8ca8\u6536\u5165": {
+                    "4111-\u92b7\u8ca8\u6536\u5165": {},
+                    "4112-\u5206\u671f\u4ed8\u6b3e\u92b7\u8ca8\u6536\u5165": {}
+                },
+                "417-\u92b7\u8ca8\u9000\u56de": {
+                    "4171-\u92b7\u8ca8\u9000\u56de": {}
+                },
+                "419-\u92b7\u8ca8\u6298\u8b93": {
+                    "4191-\u92b7\u8ca8\u6298\u8b93": {}
+                }
+            },
+            "46-\u52de\u52d9\u6536\u5165": {
+                "461-\u52de\u52d9\u6536\u5165": {
+                    "4611-\u52de\u52d9\u6536\u5165": {}
+                }
+            },
+            "47-\u696d\u52d9\u6536\u5165": {
+                "471-\u696d\u52d9\u6536\u5165": {
+                    "4711-\u696d\u52d9\u6536\u5165": {}
+                }
+            },
+            "48-\u5176\u4ed6\u71df\u696d\u6536\u5165": {
+                "488-\u5176\u4ed6\u71df\u696d\u6536\u5165\u2014\u5176\u4ed6": {
+                    "4888-\u5176\u4ed6\u71df\u696d\u6536\u5165\u2014\u5176\u4ed6": {}
+                }
+            },
+            "root_type": "Income"
+        },
+        "5-\u71df\u696d\u6210\u672c": {
+            "51-\u92b7\u8ca8\u6210\u672c": {
+                "511-\u92b7\u8ca8\u6210\u672c": {
+                    "5111-\u92b7\u8ca8\u6210\u672c": {
+                        "account_type": "Cost of Goods Sold"
+                    },
+                    "5112-\u5206\u671f\u4ed8\u6b3e\u92b7\u8ca8\u6210\u672c": {
+                        "account_type": "Cost of Goods Sold"
+                    },
+                    "account_type": "Cost of Goods Sold"
+                },
+                "512-\u9032\u8ca8": {
+                    "5121-\u9032\u8ca8": {},
+                    "5122-\u9032\u8ca8\u8cbb\u7528": {},
+                    "5123-\u9032\u8ca8\u9000\u51fa": {},
+                    "5124-\u9032\u8ca8\u6298\u8b93": {}
+                },
+                "513-\u9032\u6599": {
+                    "5131-\u9032\u6599": {},
+                    "5132-\u9032\u6599\u8cbb\u7528": {},
+                    "5133-\u9032\u6599\u9000\u51fa": {},
+                    "5134-\u9032\u6599\u6298\u8b93": {}
+                },
+                "514-\u76f4\u63a5\u4eba\u5de5": {
+                    "5141-\u76f4\u63a5\u4eba\u5de5": {}
+                },
+                "515~518-\u88fd\u9020\u8cbb\u7528": {
+                    "5151-\u9593\u63a5\u4eba\u5de5": {},
+                    "5152-\u79df\u91d1\u652f\u51fa": {},
+                    "5153-\u6587\u5177\u7528\u54c1": {},
+                    "5154-\u65c5\u8cbb": {},
+                    "5155-\u904b\u8cbb": {},
+                    "5156-\u90f5\u96fb\u8cbb": {},
+                    "5157-\u4fee\u7e55\u8cbb": {},
+                    "5158-\u5305\u88dd\u8cbb": {},
+                    "5161-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
+                    "5162-\u4fdd\u96aa\u8cbb": {},
+                    "5163-\u52a0\u5de5\u8cbb": {},
+                    "5166-\u7a05\u6350": {
+                        "account_type": "Tax", 
+                        "tax_rate": 5.0
+                    },
+                    "5168-\u6298\u820a ": {
+                        "account_type": "Depreciation"
+                    },
+                    "5169-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
+                    "5172-\u4f19\u98df\u8cbb": {},
+                    "5173-\u8077\u5de5\u798f\u5229": {},
+                    "5176-\u8a13\u7df4\u8cbb": {},
+                    "5177-\u9593\u63a5\u6750\u6599": {},
+                    "5188-\u5176\u4ed6\u88fd\u9020\u8cbb\u7528": {}
+                },
+                "Expenses Included In Valuation": {
+                    "account_type": "Expenses Included In Valuation"
+                },
+                "account_type": "Cost of Goods Sold"
+            },
+            "56-\u52de\u52d9\u6210\u672c\u88fd": {
+                "561-\u52de\u52d9\u6210\u672c": {
+                    "5611-\u52de\u52d9\u6210\u672c": {}
+                }
+            },
+            "57-\u696d\u52d9\u6210\u672c": {
+                "571-\u696d\u52d9\u6210\u672c": {
+                    "5711-\u696d\u52d9\u6210\u672c": {}
+                }
+            },
+            "58-\u5176\u4ed6\u71df\u696d\u6210\u672c": {
+                "588-\u5176\u4ed6\u71df\u696d\u6210\u672c\u2014\u5176\u4ed6 ": {
+                    "5888-\u5176\u4ed6\u71df\u696d\u6210\u672c\u2014\u5176\u4ed6": {}
+                }
+            },
+            "Stock Adjustment": {
+                "account_type": "Stock Adjustment"
+            },
+            "root_type": "Expense"
+        },
+        "6-\u71df\u696d\u8cbb\u7528": {
+            "61-\u63a8\u92b7\u8cbb\u7528": {
+                "615~618-\u63a8\u92b7\u8cbb\u7528": {
+                    "6151-\u85aa\u8cc7\u652f\u51fa": {},
+                    "6152-\u79df\u91d1\u652f\u51fa": {},
+                    "6153-\u6587\u5177\u7528\u54c1": {},
+                    "6154-\u65c5\u8cbb": {},
+                    "6155-\u904b\u8cbb": {},
+                    "6156-\u90f5\u96fb\u8cbb": {},
+                    "6157-\u4fee\u7e55\u8cbb": {},
+                    "6159-\u5ee3\u544a\u8cbb": {},
+                    "6161-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
+                    "6162-\u4fdd\u96aa\u8cbb": {},
+                    "6164-\u4ea4\u969b\u8cbb": {},
+                    "6165-\u6350\u8d08": {},
+                    "6166-\u7a05\u6350": {
+                        "account_type": "Tax", 
+                        "tax_rate": 5.0
+                    },
+                    "6167-\u5446\u5e33\u640d\u5931": {},
+                    "6168-\u6298\u820a ": {
+                        "account_type": "Depreciation"
+                    },
+                    "6169-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
+                    "6172-\u4f19\u98df\u8cbb": {},
+                    "6173-\u8077\u5de5\u798f\u5229": {},
+                    "6175-\u4f63\u91d1\u652f\u51fa": {},
+                    "6176-\u8a13\u7df4\u8cbb": {},
+                    "6188-\u5176\u4ed6\u63a8\u92b7\u8cbb\u7528": {}
+                }
+            },
+            "62-\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {
+                "625~628-\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {
+                    "6251-\u85aa\u8cc7\u652f\u51fa": {},
+                    "6252-\u79df\u91d1\u652f\u51fa": {},
+                    "6253-\u6587\u5177\u7528\u54c1": {},
+                    "6254-\u65c5\u8cbb": {},
+                    "6255-\u904b\u8cbb": {},
+                    "6256-\u90f5\u96fb\u8cbb": {},
+                    "6257-\u4fee\u7e55\u8cbb": {},
+                    "6259-\u5ee3\u544a\u8cbb": {},
+                    "6261-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
+                    "6262-\u4fdd\u96aa\u8cbb": {},
+                    "6264-\u4ea4\u969b\u8cbb": {},
+                    "6265-\u6350\u8d08": {},
+                    "6266-\u7a05\u6350": {
+                        "account_type": "Tax", 
+                        "tax_rate": 5.0
+                    },
+                    "6267-\u5446\u5e33\u640d\u5931": {},
+                    "6268-\u6298\u820a": {
+                        "account_type": "Depreciation"
+                    },
+                    "6269-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
+                    "6271-\u5916\u92b7\u640d\u5931": {},
+                    "6272-\u4f19\u98df\u8cbb": {},
+                    "6273-\u8077\u5de5\u798f\u5229": {},
+                    "6274-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {},
+                    "6275-\u4f63\u91d1\u652f\u51fa": {},
+                    "6276-\u8a13\u7df4\u8cbb": {},
+                    "6278-\u52de\u52d9\u8cbb": {},
+                    "6288-\u5176\u4ed6\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {}
+                }
+            },
+            "63-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {
+                "635~638-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {
+                    "6351-\u85aa\u8cc7\u652f\u51fa": {},
+                    "6352-\u79df\u91d1\u652f\u51fa": {},
+                    "6353-\u6587\u5177\u7528\u54c1": {},
+                    "6354-\u65c5\u8cbb": {},
+                    "6355-\u904b\u8cbb": {},
+                    "6356-\u90f5\u96fb\u8cbb": {},
+                    "6357-\u4fee\u7e55\u8cbb": {},
+                    "6361-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
+                    "6362-\u4fdd\u96aa\u8cbb": {},
+                    "6364-\u4ea4\u969b\u8cbb": {},
+                    "6366-\u7a05\u6350": {
+                        "account_type": "Tax", 
+                        "tax_rate": 5.0
+                    },
+                    "6368-\u6298\u820a": {
+                        "account_type": "Depreciation"
+                    },
+                    "6369-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
+                    "6372-\u4f19\u98df\u8cbb": {},
+                    "6373-\u8077\u5de5\u798f\u5229": {},
+                    "6376-\u8a13\u7df4\u8cbb": {},
+                    "6378-\u5176\u4ed6\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {}
+                }
+            },
+            "root_type": "Expense"
+        },
+        "7-\u71df\u696d\u5916\u6536\u5165\u53ca\u8cbb\u7528": {
+            "71~74-\u71df\u696d\u5916\u6536\u5165": {
+                "711-\u5229\u606f\u6536\u5165": {
+                    "7111-\u5229\u606f\u6536\u5165": {}
+                },
+                "712-\u6295\u8cc7\u6536\u76ca": {
+                    "7121-\u6b0a\u76ca\u6cd5\u8a8d\u5217\u4e4b\u6295\u8cc7\u6536\u76ca": {},
+                    "7122-\u80a1\u5229\u6536\u5165": {},
+                    "7123-\u77ed\u671f\u6295\u8cc7\u5e02\u50f9\u56de\u5347\u5229\u76ca": {}
+                },
+                "713-\u514c\u63db\u5229\u76ca": {
+                    "7131-\u514c\u63db\u5229\u76ca": {}
+                },
+                "714-\u8655\u5206\u6295\u8cc7\u6536\u76ca": {
+                    "7141-\u8655\u5206\u6295\u8cc7\u6536\u76ca": {}
+                },
+                "715-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u6536\u5165": {
+                    "7151-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u6536\u5165": {}
+                },
+                "748-\u5176\u4ed6\u71df\u696d\u5916\u6536\u5165": {
+                    "7481-\u6350\u8d08\u6536\u5165": {},
+                    "7482-\u79df\u91d1\u6536\u5165": {},
+                    "7483-\u4f63\u91d1\u6536\u5165": {},
+                    "7484-\u51fa\u552e\u4e0b\u8173\u53ca\u5ee2\u6599\u6536\u5165": {},
+                    "7485-\u5b58\u8ca8\u76e4\u76c8": {},
+                    "7486-\u5b58\u8ca8\u8dcc\u50f9\u56de\u5347\u5229\u76ca": {},
+                    "7487-\u58de\u5e33\u8f49\u56de\u5229\u76ca": {},
+                    "7488-\u5176\u4ed6\u71df\u696d\u5916\u6536\u5165\u2014\u5176\u4ed6": {}
+                }
+            },
+            "75~78-\u71df\u696d\u5916\u8cbb\u7528": {
+                "751-\u5229\u606f\u8cbb\u7528": {
+                    "7511-\u5229\u606f\u8cbb\u7528": {}
+                },
+                "752-\u6295\u8cc7\u640d\u5931": {
+                    "7521-\u6b0a\u76ca\u6cd5\u8a8d\u5217\u4e4b\u6295\u8cc7\u640d\u5931": {},
+                    "7523-\u77ed\u671f\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {}
+                },
+                "753-\u514c\u63db\u640d\u5931": {
+                    "7531-\u514c\u63db\u640d\u5931": {}
+                },
+                "754-\u8655\u5206\u6295\u8cc7\u640d\u5931": {
+                    "7541-\u8655\u5206\u6295\u8cc7\u640d\u5931": {}
+                },
+                "755-\u8655\u5206\u8cc7\u7522\u640d\u5931": {
+                    "7551-\u8655\u5206\u8cc7\u7522\u640d\u5931 ": {}
+                },
+                "788-\u5176\u4ed6\u71df\u696d\u5916\u8cbb\u7528": {
+                    "7881-\u505c\u5de5\u640d\u5931": {},
+                    "7882-\u707d\u5bb3\u640d\u5931": {},
+                    "7885-\u5b58\u8ca8\u76e4\u640d": {},
+                    "7886-\u5b58\u8ca8\u8dcc\u50f9\u53ca\u5446\u6eef\u640d\u5931": {},
+                    "7888-\u5176\u4ed6\u71df\u696d\u5916\u8cbb\u7528\u2014\u5176\u4ed6": {}
+                }
+            },
+            "root_type": "Income"
+        },
+        "8-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca)": {
+            "81-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca)": {
+                "811-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca) ": {
+                    "8111-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca) ": {}
+                }
+            },
+            "root_type": "Expense"
+        },
+        "9-\u975e\u7d93\u5e38\u71df\u696d\u640d\u76ca": {
+            "91-\u505c\u696d\u90e8\u9580\u640d\u76ca": {
+                "911-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u505c\u696d\u524d\u71df\u696d\u640d\u76ca": {
+                    "9111-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u505c\u696d\u524d\u71df\u696d\u640d\u76ca": {}
+                },
+                "912-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u8655\u5206\u640d\u76ca": {
+                    "9121-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u8655\u5206\u640d\u76ca": {}
+                }
+            },
+            "92-\u975e\u5e38\u640d\u76ca": {
+                "921-\u975e\u5e38\u640d\u76ca": {
+                    "9211-\u975e\u5e38\u640d\u76ca": {}
+                }
+            },
+            "93-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {
+                "931-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {
+                    "9311-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {}
+                }
+            },
+            "94-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {
+                "941-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {
+                    "9411-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {}
+                }
+            },
+            "root_type": "Expense"
+        }
+    }
+}
\ No newline at end of file
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.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 92a805f..12e46c4 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -569,7 +569,7 @@
 		})
 
 		var allocated_negative_outstanding = 0;
-		if((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
+		if ((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
 				(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
 				(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee")) {
 			if(total_positive_outstanding_including_order > paid_amount) {
@@ -579,7 +579,7 @@
 			}
 
 			var allocated_positive_outstanding =  paid_amount + allocated_negative_outstanding;
-		} else {
+		} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
 			if(paid_amount > total_negative_outstanding) {
 				if(total_negative_outstanding == 0) {
 					frappe.msgprint(__("Cannot {0} {1} {2} without any negative outstanding invoice",
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 762fa99..c6353d5 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 6002590..a5bf4ff 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/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js
index 8d33524..46ed9da 100644
--- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js
+++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js
@@ -7,7 +7,7 @@
 			"fieldname":"from_date",
 			"label": __("From Date"),
 			"fieldtype": "Date",
-			"default": frappe.defaults.get_user_default("year_start_date"),
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
 			"width": "80"
 		},
 		{
diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
index 0e5d128..fa458df 100644
--- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
+++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
@@ -2,7 +2,7 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe
+import frappe, erpnext
 from frappe import _
 from frappe.utils import flt
 from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import get_tax_accounts
@@ -14,10 +14,12 @@
 	if not filters: filters = {}
 	columns = get_columns(additional_table_columns)
 
+	company_currency = erpnext.get_company_currency(filters.company)
+
 	item_list = get_items(filters, additional_query_columns)
 	aii_account_map = get_aii_accounts()
 	if item_list:
-		itemised_tax, tax_columns = get_tax_accounts(item_list, columns,
+		itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency,
 			doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges")
 
 	columns.append({
@@ -26,7 +28,7 @@
 		"fieldtype": "Data",
 		"width": 80
 	})
-	company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
+
 	po_pr_map = get_purchase_receipts_against_purchase_order(item_list)
 
 	data = []
@@ -125,14 +127,15 @@
 	po_pr_map = frappe._dict()
 	po_item_rows = list(set([d.po_detail for d in item_list]))
 
-	purchase_receipts = frappe.db.sql("""
-		select parent, purchase_order_item
-		from `tabPurchase Receipt Item`
-		where docstatus=1 and purchase_order_item in (%s)
-		group by purchase_order_item, parent
-	""" % (', '.join(['%s']*len(po_item_rows))), tuple(po_item_rows), as_dict=1)
+	if po_item_rows:
+		purchase_receipts = frappe.db.sql("""
+			select parent, purchase_order_item
+			from `tabPurchase Receipt Item`
+			where docstatus=1 and purchase_order_item in (%s)
+			group by purchase_order_item, parent
+		""" % (', '.join(['%s']*len(po_item_rows))), tuple(po_item_rows), as_dict=1)
 
-	for pr in purchase_receipts:
-		po_pr_map.setdefault(pr.po_detail, []).append(pr.parent)
+		for pr in purchase_receipts:
+			po_pr_map.setdefault(pr.po_detail, []).append(pr.parent)
 
 	return po_pr_map
\ No newline at end of file
diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js
index 65cec51..b57a7fc 100644
--- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js
+++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js
@@ -7,7 +7,7 @@
 			"fieldname":"from_date",
 			"label": __("From Date"),
 			"fieldtype": "Date",
-			"default": frappe.defaults.get_default("year_start_date"),
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
 			"width": "80"
 		},
 		{
diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
index dfcade2..0fc5831 100644
--- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
+++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
@@ -2,9 +2,10 @@
 # License: GNU General Public License v3. See license.txt
 
 from __future__ import unicode_literals
-import frappe
+import frappe, erpnext
 from frappe import _
 from frappe.utils import flt
+from frappe.model.meta import get_field_precision
 from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
 
 def execute(filters=None):
@@ -14,16 +15,17 @@
 	if not filters: filters = {}
 	columns = get_columns(additional_table_columns)
 
+	company_currency = erpnext.get_company_currency(filters.company)
+
 	item_list = get_items(filters, additional_query_columns)
 	if item_list:
-		itemised_tax, tax_columns = get_tax_accounts(item_list, columns)
+		itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
 	columns.append({
 		"fieldname": "currency",
 		"label": _("Currency"),
 		"fieldtype": "Data",
 		"width": 80
 	})
-	company_currency = frappe.db.get_value("Company", filters.get("company"), "default_currency")
 	mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list]))
 	so_dn_map = get_delivery_notes_against_sales_order(item_list)
 
@@ -127,28 +129,38 @@
 	so_dn_map = frappe._dict()
 	so_item_rows = list(set([d.so_detail for d in item_list]))
 
-	delivery_notes = frappe.db.sql("""
-		select parent, so_detail
-		from `tabDelivery Note Item`
-		where docstatus=1 and so_detail in (%s)
-		group by so_detail, parent
-	""" % (', '.join(['%s']*len(so_item_rows))), tuple(so_item_rows), as_dict=1)
+	if so_item_rows:
+		delivery_notes = frappe.db.sql("""
+			select parent, so_detail
+			from `tabDelivery Note Item`
+			where docstatus=1 and so_detail in (%s)
+			group by so_detail, parent
+		""" % (', '.join(['%s']*len(so_item_rows))), tuple(so_item_rows), as_dict=1)
 
-	for dn in delivery_notes:
-		so_dn_map.setdefault(dn.so_detail, []).append(dn.parent)
+		for dn in delivery_notes:
+			so_dn_map.setdefault(dn.so_detail, []).append(dn.parent)
 
 	return so_dn_map
 
-def get_tax_accounts(item_list, columns, doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
+def get_tax_accounts(item_list, columns, company_currency,
+		doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
 	import json
 	item_row_map = {}
 	tax_columns = []
 	invoice_item_row = {}
 	itemised_tax = {}
+
+	tax_amount_precision = get_field_precision(frappe.get_meta(tax_doctype).get_field("tax_amount"),
+		currency=company_currency) or 2
+
 	for d in item_list:
 		invoice_item_row.setdefault(d.parent, []).append(d)
 		item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
 
+	conditions = ""
+	if doctype == "Purchase Invoice":
+		conditions = " and category in ('Total', 'Valuation and Total')"
+
 	tax_details = frappe.db.sql("""
 		select
 			parent, description, item_wise_tax_detail,
@@ -158,8 +170,9 @@
 			parenttype = %s and docstatus = 1
 			and (description is not null and description != '')
 			and parent in (%s)
+			%s
 		order by description
-	""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row))),
+	""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row)), conditions),
 		tuple([doctype] + invoice_item_row.keys()))
 
 	for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
@@ -191,7 +204,7 @@
 						if item_tax_amount:
 							itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
 								"tax_rate": tax_rate,
-								"tax_amount": item_tax_amount
+								"tax_amount": flt(item_tax_amount, tax_amount_precision)
 							})
 
 			except ValueError:
@@ -200,7 +213,8 @@
 			for d in invoice_item_row.get(parent, []):
 				itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
 					"tax_rate": "NA",
-					"tax_amount": flt((tax_amount * d.base_net_amount) / d.base_net_total)
+					"tax_amount": flt((tax_amount * d.base_net_amount) / d.base_net_total,
+						tax_amount_precision)
 				})
 
 	tax_columns.sort()
diff --git a/erpnext/accounts/report/purchase_register/purchase_register.js b/erpnext/accounts/report/purchase_register/purchase_register.js
index cd79531..42b35c2 100644
--- a/erpnext/accounts/report/purchase_register/purchase_register.js
+++ b/erpnext/accounts/report/purchase_register/purchase_register.js
@@ -7,7 +7,7 @@
 			"fieldname":"from_date",
 			"label": __("From Date"),
 			"fieldtype": "Date",
-			"default": frappe.defaults.get_user_default("year_start_date"),
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
 			"width": "80"
 		},
 		{
diff --git a/erpnext/accounts/report/sales_register/sales_register.js b/erpnext/accounts/report/sales_register/sales_register.js
index 2ac4ae8..0495976 100644
--- a/erpnext/accounts/report/sales_register/sales_register.js
+++ b/erpnext/accounts/report/sales_register/sales_register.js
@@ -7,7 +7,7 @@
 			"fieldname":"from_date",
 			"label": __("From Date"),
 			"fieldtype": "Date",
-			"default": frappe.defaults.get_default("year_start_date"),
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
 			"width": "80"
 		},
 		{
diff --git a/erpnext/config/manufacturing.py b/erpnext/config/manufacturing.py
index a930ddc..11711ad 100644
--- a/erpnext/config/manufacturing.py
+++ b/erpnext/config/manufacturing.py
@@ -70,8 +70,8 @@
 			"items": [
 				{
 					"type": "doctype",
-					"name": "BOM Replace Tool",
-					"description": _("Replace Item / BOM in all BOMs"),
+					"name": "BOM Update Tool",
+					"description": _("Replace BOM and update latest price in all BOMs"),
 				},
 			]
 		},
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index 6d69a48..11c0790 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -232,7 +232,7 @@
 		select `tabDelivery Note`.name, `tabDelivery Note`.customer, `tabDelivery Note`.posting_date
 		from `tabDelivery Note`
 		where `tabDelivery Note`.`%(key)s` like %(txt)s and
-			`tabDelivery Note`.docstatus = 1 and `tabDelivery Note`.is_return = 0 
+			`tabDelivery Note`.docstatus = 1 and `tabDelivery Note`.is_return = 0
 			and status not in ("Stopped", "Closed") %(fcond)s
 			and (`tabDelivery Note`.per_billed < 100 or `tabDelivery Note`.grand_total = 0)
 			%(mcond)s order by `tabDelivery Note`.`%(key)s` asc
@@ -367,31 +367,30 @@
 	sub_query = """ select round(`tabBin`.actual_qty, 2) from `tabBin`
 		where `tabBin`.warehouse = `tabWarehouse`.name
 		{bin_conditions} """.format(
-		bin_conditions=get_filters_cond(doctype, filter_dict.get("Bin"), 
+		bin_conditions=get_filters_cond(doctype, filter_dict.get("Bin"),
 			bin_conditions, ignore_permissions=True))
 
-	response = frappe.db.sql("""select `tabWarehouse`.name,
+	query = """select `tabWarehouse`.name,
 		CONCAT_WS(" : ", "Actual Qty", ifnull( ({sub_query}), 0) ) as actual_qty
 		from `tabWarehouse`
 		where
-		   `tabWarehouse`.`{key}` like %(txt)s
+		   `tabWarehouse`.`{key}` like '{txt}'
 			{fcond} {mcond}
 		order by
 			`tabWarehouse`.name desc
 		limit
-			%(start)s, %(page_len)s
+			{start}, {page_len}
 		""".format(
 			sub_query=sub_query,
 			key=frappe.db.escape(searchfield),
 			fcond=get_filters_cond(doctype, filter_dict.get("Warehouse"), conditions),
-			mcond=get_match_cond(doctype)
-		),
-		{
-			"txt": "%%%s%%" % frappe.db.escape(txt),
-			"start": start,
-			"page_len": page_len
-		})
-	return response
+			mcond=get_match_cond(doctype),
+			start=start,
+			page_len=page_len,
+			txt=frappe.db.escape('%{0}%'.format(txt))
+		)
+
+	return frappe.db.sql(query)
 
 
 def get_doctype_wise_filters(filters):
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 97bd771..c627664 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -270,7 +270,7 @@
 		if tax.item_wise_tax_detail.get(key):
 			item_wise_tax_amount += tax.item_wise_tax_detail[key][1]
 
-		tax.item_wise_tax_detail[key] = [tax_rate,flt(item_wise_tax_amount, tax.precision("base_tax_amount"))]
+		tax.item_wise_tax_detail[key] = [tax_rate,flt(item_wise_tax_amount)]
 
 	def round_off_totals(self, tax):
 		tax.tax_amount = flt(tax.tax_amount, tax.precision("tax_amount"))
@@ -521,12 +521,20 @@
 	frappe.flags.company = doc.company
 	
 	# get headers
-	tax_accounts = list(set([d.description for d in doc.taxes]))
+	tax_accounts = []
+	for tax in doc.taxes:
+		if getattr(tax, "category", None) and tax.category=="Valuation":
+			continue
+		if tax.description not in tax_accounts:
+			tax_accounts.append(tax.description)
+
 	headers = get_itemised_tax_breakup_header(doc.doctype + " Item", tax_accounts)
 	
 	# get tax breakup data
 	itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(doc)
-	
+
+	get_rounded_tax_amount(itemised_tax, doc.precision("tax_amount", "taxes"))
+
 	frappe.flags.company = None
 	
 	return frappe.render_template(
@@ -554,6 +562,9 @@
 def get_itemised_tax(taxes):
 	itemised_tax = {}
 	for tax in taxes:
+		if getattr(tax, "category", None) and tax.category=="Valuation":
+			continue
+
 		tax_amount_precision = tax.precision("tax_amount")
 		tax_rate_precision = tax.precision("rate")
 		
@@ -562,16 +573,16 @@
 		for item_code, tax_data in item_tax_map.items():
 			itemised_tax.setdefault(item_code, frappe._dict())
 			
-			if isinstance(tax_data, list) and tax_data[0]:
+			if isinstance(tax_data, list):
 				precision = tax_amount_precision if tax.charge_type == "Actual" else tax_rate_precision
 				
 				itemised_tax[item_code][tax.description] = frappe._dict(dict(
-					tax_rate=flt(tax_data[0], precision),
-					tax_amount=flt(tax_data[1], tax_amount_precision)
+					tax_rate=flt(tax_data[0]),
+					tax_amount=flt(tax_data[1])
 				))
 			else:
 				itemised_tax[item_code][tax.description] = frappe._dict(dict(
-					tax_rate=flt(tax_data, tax_rate_precision),
+					tax_rate=flt(tax_data),
 					tax_amount=0.0
 				))
 
@@ -584,4 +595,10 @@
 		itemised_taxable_amount.setdefault(item_code, 0)
 		itemised_taxable_amount[item_code] += item.net_amount
 
-	return itemised_taxable_amount
\ No newline at end of file
+	return itemised_taxable_amount
+
+def get_rounded_tax_amount(itemised_tax, precision):
+	# Rounding based on tax_amount precision
+	for taxes in itemised_tax.values():
+		for tax_account in taxes:
+			taxes[tax_account]["tax_amount"] = flt(taxes[tax_account]["tax_amount"], precision)
\ No newline at end of file
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/docs/assets/img/manufacturing/bom-replace-tool.png b/erpnext/docs/assets/img/manufacturing/bom-replace-tool.png
deleted file mode 100644
index 51ac993..0000000
--- a/erpnext/docs/assets/img/manufacturing/bom-replace-tool.png
+++ /dev/null
Binary files differ
diff --git a/erpnext/docs/assets/img/manufacturing/bom-update-tool.png b/erpnext/docs/assets/img/manufacturing/bom-update-tool.png
new file mode 100644
index 0000000..7dbd47f
--- /dev/null
+++ b/erpnext/docs/assets/img/manufacturing/bom-update-tool.png
Binary files differ
diff --git a/erpnext/docs/user/manual/en/manufacturing/tools/bom-replace-tool.md b/erpnext/docs/user/manual/en/manufacturing/tools/bom-replace-tool.md
deleted file mode 100644
index 98d1f3b..0000000
--- a/erpnext/docs/user/manual/en/manufacturing/tools/bom-replace-tool.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# BOM Replace Tool
-
-Replace BOM is the utility to replace BOM of sub-assembly item, which is already updated in the BOM of Finished Good item.
-
-To use the Production Planning Tool, go to:
-
-> Manufacturing > Tools > BOM Replace Tool
-
-Let's consider a scenario to understand this better.
-
-If company manufactures computers, Bill of Material of its finished item will constitute of:
-
-1. Monitor
-1. Key Board
-1. Mouse
-1. CPU
-
-Out of all the items above, CPU is asembled separately. Hence separate BOM will be created for the CPU. Following are the items from the BOM of CPU.
-
-1. 250 GB Hard Disk
-1. Mother Board
-1. Processor
-1. SMTP
-1. DVD player
-
-If we have more items to be added , or existing items to be edited in the BOM of CPU, then we should create new BOM for it.
-
-1. _350 GB Hard Disk_
-1. Mother Board
-1. Processor
-1. SMTP
-1. DVD player
-
-To update new BOM updated in the BOM of finished item, where CPU is selected as raw-material, you can use BOM Replace tool.
-
-<img class="screenshot" alt="BOM replace Tool" src="/docs/assets/img/manufacturing/bom-replace-tool.png">
-
-In this tool, you should select Current BOM, and New BOM. On clicking Replace button, current BOM of CPU will be replaced with New BOM in the BOM of finished Item (Computer).
-
-**Will BOM Replace Tool work for replacing finsihed item in BOM?**
-
-No. You should Cancel and Amend current BOM, or create a new BOM for finished item.
-
-{next}
diff --git a/erpnext/docs/user/manual/en/manufacturing/tools/bom-update-tool.md b/erpnext/docs/user/manual/en/manufacturing/tools/bom-update-tool.md
new file mode 100644
index 0000000..4150353
--- /dev/null
+++ b/erpnext/docs/user/manual/en/manufacturing/tools/bom-update-tool.md
@@ -0,0 +1,54 @@
+# BOM Update Tool
+
+From BOM Update Tool, you can replace a sub-assembly BOM and update costs of all BOMs.
+
+### Replace BOM
+Using this utility, you can replace an existing BOM of sub-assembly item, with a new one. The system will update the new BOM in all the parent BOMs where it was used.
+
+To use the BOM Update Tool, go to:
+
+> Manufacturing > Tools > BOM Update Tool
+
+Let's consider a scenario to understand this better.
+
+Suppose a company manufactures computers, Bill of Material of of the computer will look like this:
+
+1. Monitor
+1. Key Board
+1. Mouse
+1. CPU
+
+Out of all the items above, CPU is asembled separately. Hence separate BOM will be created for the CPU. Following are the items from the BOM of CPU.
+
+1. 250 GB Hard Disk
+1. Mother Board
+1. Processor
+1. SMTP
+1. DVD player
+
+If we have more items to be added , or existing items to be edited in the BOM of CPU, then we should create new BOM for it.
+
+1. _350 GB Hard Disk_
+1. Mother Board
+1. Processor
+1. SMTP
+1. DVD player
+
+To update new BOM in all the parent BOMs, where CPU is selected as raw-material, you can use Replace utility.
+
+<img class="screenshot" alt="BOM Update Tool" src="{{docs_base_url}}/assets/img/manufacturing/bom-update-tool.png">
+
+In this tool, you should select Current BOM, and New BOM. On clicking Replace button, current BOM of CPU will be replaced with New BOM in the BOM of finished Item (Computer).
+
+**Will BOM Replace Tool work for replacing finsihed item in BOM?**
+
+No. You should Cancel and Amend current BOM, or create a new BOM for finished item.
+
+### Update BOM Cost
+Using the button **Update latest price in all BOMs**, you can update cost of all Bill of Materials, based on latest purchase price / price list rate / valuation rate of raw materials.
+
+On clicking of this buttom, system will create a background process to update all the BOM's cost. It is processed via background jobs because this process can take a few minutes (depending on the number of BOMs) to update all the BOMs.
+
+This functionality can also be executed automatically on daily basis. For that, you need to enable "Update BOM Cost Automatically" from Manufacturing Settings.
+
+{next}
diff --git a/erpnext/docs/user/manual/en/manufacturing/tools/index.txt b/erpnext/docs/user/manual/en/manufacturing/tools/index.txt
index aaf7cec..a385154 100644
--- a/erpnext/docs/user/manual/en/manufacturing/tools/index.txt
+++ b/erpnext/docs/user/manual/en/manufacturing/tools/index.txt
@@ -1,2 +1,2 @@
 production-planning-tool
-bom-replace-tool
\ No newline at end of file
+bom-update-tool
\ No newline at end of file
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 4df83af..7e65fc9 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -196,7 +196,8 @@
 		"erpnext.hr.doctype.daily_work_summary_settings.daily_work_summary_settings.send_summary",
 		"erpnext.stock.doctype.serial_no.serial_no.update_maintenance_status",
 		"erpnext.buying.doctype.supplier_scorecard.supplier_scorecard.refresh_scorecards",
-		"erpnext.setup.doctype.company.company.cache_companies_monthly_sales_history"
+		"erpnext.setup.doctype.company.company.cache_companies_monthly_sales_history",
+		"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms",
 	]
 }
 
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.js b/erpnext/manufacturing/doctype/bom/bom.js
index 347314b..c58c89c 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -5,7 +5,7 @@
 
 frappe.ui.form.on("BOM", {
 	setup: function(frm) {
-		frm.add_fetch('buying_price_list', 'currency', 'currency')
+		frm.add_fetch('buying_price_list', 'currency', 'currency');
 
 		frm.set_query("bom_no", "items", function() {
 			return {
@@ -13,15 +13,15 @@
 					'currency': frm.doc.currency,
 					'company': frm.doc.company
 				}
-			}
+			};
 		});
-		
+
 		frm.set_query("source_warehouse", "items", function() {
 			return {
 				filters: {
 					'company': frm.doc.company,
 				}
-			}
+			};
 		});
 	},
 
@@ -57,10 +57,14 @@
 			doc: frm.doc,
 			method: "update_cost",
 			freeze: true,
+			args: {
+				update_parent: true,
+				from_child_bom:false
+			},
 			callback: function(r) {
 				if(!r.exc) frm.refresh_fields();
 			}
-		})
+		});
 	}
 });
 
diff --git a/erpnext/manufacturing/doctype/bom/bom.json b/erpnext/manufacturing/doctype/bom/bom.json
index f41087b..46a1ffd 100644
--- a/erpnext/manufacturing/doctype/bom/bom.json
+++ b/erpnext/manufacturing/doctype/bom/bom.json
@@ -232,7 +232,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
@@ -262,7 +262,7 @@
   }, 
   {
    "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
+   "allow_on_submit": 1, 
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
@@ -293,6 +293,37 @@
   }, 
   {
    "allow_bulk_edit": 0, 
+   "allow_on_submit": 1, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "default": "1", 
+   "fieldname": "set_rate_of_sub_assembly_item_based_on_bom", 
+   "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": "Set rate of sub-assembly item based on BOM", 
+   "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, 
@@ -1640,7 +1671,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-08-11 14:09:30.492628", 
+ "modified": "2017-08-23 14:09:30.492628", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "BOM", 
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 7130a3e..e48a002 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -92,7 +92,7 @@
 
 	def validate_rm_item(self, item):
 		if (item[0]['name'] in [it.item_code for it in self.items]) and item[0]['name'] == self.item:
-			frappe.throw(_("Raw material cannot be same as main Item"))
+			frappe.throw(_("BOM #{0}: Raw material cannot be same as main Item").format(self.name))
 
 	def set_bom_material_details(self):
 		for item in self.get("items"):
@@ -155,15 +155,17 @@
 				rate = frappe.db.get_value("Item Price", {"price_list": self.buying_price_list,
 					"item_code": arg["item_code"]}, "price_list_rate") or 0
 
-		if not rate and arg['bom_no']:
-			rate = self.get_bom_unitcost(arg['bom_no'])
+			if arg['bom_no'] and (not rate or self.set_rate_of_sub_assembly_item_based_on_bom):
+				rate = self.get_bom_unitcost(arg['bom_no'])
 
 		return rate
 
-	def update_cost(self):
+	def update_cost(self, update_parent=True, from_child_bom=False):
 		if self.docstatus == 2:
 			return
 
+		existing_bom_cost = self.total_cost
+
 		for d in self.get("items"):
 			rate = self.get_bom_material_detail({'item_code': d.item_code, 'bom_no': d.bom_no,
 				'stock_qty': d.stock_qty})["rate"]
@@ -176,7 +178,16 @@
 		self.save()
 		self.update_exploded_items()
 
-		frappe.msgprint(_("Cost Updated"))
+		# update parent BOMs
+		if self.total_cost != existing_bom_cost and update_parent:
+			parent_boms = frappe.db.sql_list("""select distinct parent from `tabBOM Item`
+				where bom_no = %s and docstatus=1""", self.name)
+
+			for bom in parent_boms:
+				frappe.get_doc("BOM", bom).update_cost(from_child_bom=True)
+
+		if not from_child_bom:
+			frappe.msgprint(_("Cost Updated"))
 
 	def get_bom_unitcost(self, bom_no):
 		bom = frappe.db.sql("""select name, total_cost/quantity as unit_cost from `tabBOM`
@@ -248,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):
@@ -566,4 +577,27 @@
 			where bom_item.parent=%s
 			and bom_item.item_code = item.name
 			order by bom_item.idx
-			""", frappe.form_dict.parent, as_dict=True)
\ No newline at end of file
+			""", frappe.form_dict.parent, as_dict=True)
+
+def get_boms_in_bottom_up_order(bom_no=None):
+	def _get_parent(bom_no):
+		return frappe.db.sql_list("""select distinct parent from `tabBOM Item`
+			where bom_no = %s and docstatus=1""", bom_no)
+
+	count = 0
+	bom_list = []
+	if bom_no:
+		bom_list.append(bom_no)
+	else:
+		# get all leaf BOMs
+		bom_list = frappe.db.sql_list("""select name from `tabBOM` bom where docstatus=1
+			and not exists(select bom_no from `tabBOM Item`
+				where parent=bom.name and ifnull(bom_no, '')!='')""")
+
+	while(count < len(bom_list)):
+		for child_bom in _get_parent(bom_list[count]):
+			if child_bom not in bom_list:
+				bom_list.append(child_bom)
+		count += 1
+
+	return bom_list
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/bom/test_bom.py b/erpnext/manufacturing/doctype/bom/test_bom.py
index 4e520ef..d678444 100644
--- a/erpnext/manufacturing/doctype/bom/test_bom.py
+++ b/erpnext/manufacturing/doctype/bom/test_bom.py
@@ -6,6 +6,8 @@
 import unittest
 import frappe
 from frappe.utils import cstr
+from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import create_stock_reconciliation
+from erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool import update_cost
 
 test_records = frappe.get_test_records('BOM')
 
@@ -46,6 +48,32 @@
 		bom.save()
 
 		self.assertTrue(_get_default_bom_in_item(), bom.name)
+
+	def test_update_bom_cost_in_all_boms(self):
+		# get current rate for '_Test Item 2'
+		rm_rate = frappe.db.sql("""select rate from `tabBOM Item`
+			where parent='BOM-_Test Item Home Desktop Manufactured-001'
+			and item_code='_Test Item 2' and docstatus=1""")
+		rm_rate = rm_rate[0][0] if rm_rate else 0
+
+		# update valuation rate of item '_Test Item 2'
+		warehouse_list = frappe.db.sql_list("""select warehouse from `tabBin`
+			where item_code='_Test Item 2' and actual_qty > 0""")
+
+		if not warehouse_list:
+			warehouse_list.append("_Test Warehouse - _TC")
+
+		for warehouse in warehouse_list:
+			create_stock_reconciliation(item_code="_Test Item 2", warehouse=warehouse,
+				qty=200, rate=rm_rate + 10)
+
+		# update cost of all BOMs based on latest valuation rate
+		update_cost()
 		
+		# check if new valuation rate updated in all BOMs
+		for d in frappe.db.sql("""select rate from `tabBOM Item`
+			where item_code='_Test Item 2' and docstatus=1""", as_dict=1):
+				self.assertEqual(d.rate, rm_rate + 10)
+
 def get_default_bom(item_code="_Test FG Item 2"):
 	return frappe.db.get_value("BOM", {"item": item_code, "is_active": 1, "is_default": 1})
diff --git a/erpnext/manufacturing/doctype/bom_replace_tool/README.md b/erpnext/manufacturing/doctype/bom_replace_tool/README.md
deleted file mode 100644
index 4abce74..0000000
--- a/erpnext/manufacturing/doctype/bom_replace_tool/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Tool to replace one Item with another in all Bill of Material (BOM) trees.
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/bom_replace_tool/bom_replace_tool.js b/erpnext/manufacturing/doctype/bom_replace_tool/bom_replace_tool.js
deleted file mode 100644
index 8a3f70c..0000000
--- a/erpnext/manufacturing/doctype/bom_replace_tool/bom_replace_tool.js
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
-
-
-cur_frm.cscript.refresh = function(doc) {
-	cur_frm.disable_save();
-}
-
-cur_frm.set_query("current_bom", function(doc) {
-	return{
-		query: "erpnext.controllers.queries.bom",
-		filters: {name: "!" + doc.new_bom}
-	}
-});
-
-
-cur_frm.set_query("new_bom", function(doc) {
-	return{
-		query: "erpnext.controllers.queries.bom",
-		filters: {name: "!" + doc.current_bom}
-	}
-});
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/bom_replace_tool/bom_replace_tool.json b/erpnext/manufacturing/doctype/bom_replace_tool/bom_replace_tool.json
deleted file mode 100644
index bf7e6fc..0000000
--- a/erpnext/manufacturing/doctype/bom_replace_tool/bom_replace_tool.json
+++ /dev/null
@@ -1,119 +0,0 @@
-{
- "allow_copy": 1, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "creation": "2012-12-06 12:10:10", 
- "custom": 0, 
- "description": "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM", 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "Other", 
- "fields": [
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "description": "The BOM which will be replaced", 
-   "fieldname": "current_bom", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Current BOM", 
-   "no_copy": 0, 
-   "options": "BOM", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "description": "The new BOM after replacement", 
-   "fieldname": "new_bom", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "New BOM", 
-   "no_copy": 0, 
-   "options": "BOM", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
-  {
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "fieldname": "replace", 
-   "fieldtype": "Button", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Replace", 
-   "no_copy": 0, 
-   "options": "replace_bom", 
-   "permlevel": 0, 
-   "print_hide": 0, 
-   "read_only": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }
- ], 
- "hide_heading": 1, 
- "hide_toolbar": 1, 
- "icon": "fa fa-magic", 
- "idx": 1, 
- "in_create": 1, 
- "in_dialog": 0, 
- "is_submittable": 0, 
- "issingle": 1, 
- "istable": 0, 
- "modified": "2015-08-12 08:52:46.035343", 
- "modified_by": "Administrator", 
- "module": "Manufacturing", 
- "name": "BOM Replace Tool", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 0, 
-   "email": 0, 
-   "export": 0, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 0, 
-   "read": 1, 
-   "report": 0, 
-   "role": "Manufacturing Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "read_only": 1, 
- "read_only_onload": 0
-}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/bom_replace_tool/__init__.py b/erpnext/manufacturing/doctype/bom_update_tool/__init__.py
similarity index 100%
rename from erpnext/manufacturing/doctype/bom_replace_tool/__init__.py
rename to erpnext/manufacturing/doctype/bom_update_tool/__init__.py
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.js b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.js
new file mode 100644
index 0000000..a4b48af
--- /dev/null
+++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.js
@@ -0,0 +1,34 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('BOM Update Tool', {
+	setup: function(frm) {
+		frm.set_query("current_bom", function() {
+			return {
+				query: "erpnext.controllers.queries.bom",
+				filters: {name: "!" + frm.doc.new_bom}
+			};
+		});
+
+		frm.set_query("new_bom", function() {
+			return {
+				query: "erpnext.controllers.queries.bom",
+				filters: {name: "!" + frm.doc.current_bom}
+			};
+		});
+	},
+
+	refresh: function(frm) {
+		frm.disable_save();
+	},
+
+	update_latest_price_in_all_boms: function() {
+		frappe.call({
+			method: "erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.enqueue_update_cost",
+			freeze: true,
+			callback: function() {
+				frappe.msgprint(__("Latest price updated in all BOMs"));
+			}
+		});
+	}
+});
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.json b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.json
new file mode 100644
index 0000000..ab63c0b
--- /dev/null
+++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.json
@@ -0,0 +1,244 @@
+{
+ "allow_copy": 1, 
+ "allow_guest_to_view": 0, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2012-12-06 12:10:10", 
+ "custom": 0, 
+ "description": "Replace a particular BOM in all other BOMs where it is used. It will replace the old BOM link, update cost and regenerate \"BOM Explosion Item\" table as per new BOM.\nIt also updates latest price in all the BOMs.", 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "Other", 
+ "editable_grid": 0, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "replace_bom_section", 
+   "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": "Replace BOM", 
+   "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": "The BOM which will be replaced", 
+   "fieldname": "current_bom", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "Current BOM", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "BOM", 
+   "permlevel": 0, 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "description": "The new BOM after replacement", 
+   "fieldname": "new_bom", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 1, 
+   "in_standard_filter": 0, 
+   "label": "New BOM", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "BOM", 
+   "permlevel": 0, 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "replace", 
+   "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": "Replace", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "replace_bom", 
+   "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": "update_cost_section", 
+   "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 Cost", 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "update_latest_price_in_all_boms", 
+   "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 latest price in all BOMs", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }
+ ], 
+ "has_web_view": 0, 
+ "hide_heading": 1, 
+ "hide_toolbar": 1, 
+ "icon": "icon-magic", 
+ "idx": 1, 
+ "image_view": 0, 
+ "in_create": 1, 
+ "is_submittable": 0, 
+ "issingle": 1, 
+ "istable": 0, 
+ "max_attachments": 0, 
+ "modified": "2017-07-31 18:08:05.919276", 
+ "modified_by": "Administrator", 
+ "module": "Manufacturing", 
+ "name": "BOM Update Tool", 
+ "owner": "Administrator", 
+ "permissions": [
+  {
+   "amend": 0, 
+   "apply_user_permissions": 0, 
+   "cancel": 0, 
+   "create": 1, 
+   "delete": 0, 
+   "email": 0, 
+   "export": 0, 
+   "if_owner": 0, 
+   "import": 0, 
+   "permlevel": 0, 
+   "print": 0, 
+   "read": 1, 
+   "report": 0, 
+   "role": "Manufacturing Manager", 
+   "set_user_permissions": 0, 
+   "share": 1, 
+   "submit": 0, 
+   "write": 1
+  }
+ ], 
+ "quick_entry": 0, 
+ "read_only": 1, 
+ "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/manufacturing/doctype/bom_replace_tool/bom_replace_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
similarity index 63%
rename from erpnext/manufacturing/doctype/bom_replace_tool/bom_replace_tool.py
rename to erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
index f0a834c..91b5070 100644
--- a/erpnext/manufacturing/doctype/bom_replace_tool/bom_replace_tool.py
+++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
@@ -1,14 +1,15 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
 
 from __future__ import unicode_literals
 import frappe
 from frappe.utils import cstr, flt
 from frappe import _
-
+from erpnext.manufacturing.doctype.bom.bom import get_boms_in_bottom_up_order
 from frappe.model.document import Document
 
-class BOMReplaceTool(Document):
+class BOMUpdateTool(Document):
 	def replace_bom(self):
 		self.validate_bom()
 		self.update_new_bom()
@@ -40,3 +41,17 @@
 		return [d[0] for d in frappe.db.sql("""select distinct parent
 			from `tabBOM Item` where ifnull(bom_no, '') = %s and docstatus < 2""",
 			self.new_bom)]
+
+@frappe.whitelist()
+def enqueue_update_cost():
+	frappe.enqueue("erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_cost")
+	frappe.msgprint(_("Queued for updating latest price in all Bill of Materials. It may take a few minutes."))
+
+def update_latest_price_in_all_boms():
+	if frappe.db.get_single_value("Manufacturing Settings", "update_bom_costs_automatically"):
+		update_cost()
+
+def update_cost():
+	bom_list = get_boms_in_bottom_up_order()
+	for bom in bom_list:
+		frappe.get_doc("BOM", bom).update_cost(update_parent=False, from_child_bom=True)
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.js b/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.js
new file mode 100644
index 0000000..d220df2
--- /dev/null
+++ b/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: BOM Update Tool", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially('BOM Update Tool', [
+		// insert a new BOM Update Tool
+		() => frappe.tests.make([
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py
new file mode 100644
index 0000000..154addf
--- /dev/null
+++ b/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py
@@ -0,0 +1,30 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+
+from __future__ import unicode_literals
+import unittest
+import frappe
+
+test_records = frappe.get_test_records('BOM')
+
+class TestBOMUpdateTool(unittest.TestCase):
+	def test_replace_bom(self):
+		current_bom = "BOM-_Test Item Home Desktop Manufactured-001"
+
+		bom_doc = frappe.copy_doc(test_records[0])
+		bom_doc.items[1].item_code = "_Test Item"
+		bom_doc.insert()
+
+		update_tool = frappe.get_doc("BOM Update Tool")
+		update_tool.current_bom = current_bom
+		update_tool.new_bom = bom_doc.name
+		update_tool.replace_bom()
+
+		self.assertFalse(frappe.db.sql("select name from `tabBOM Item` where bom_no=%s", current_bom))
+		self.assertTrue(frappe.db.sql("select name from `tabBOM Item` where bom_no=%s", bom_doc.name))
+
+		# reverse, as it affects other testcases
+		update_tool.current_bom = bom_doc.name
+		update_tool.new_bom = current_bom
+		update_tool.replace_bom()
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json b/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json
index 9f12e45..455a983 100644
--- a/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json
+++ b/erpnext/manufacturing/doctype/manufacturing_settings/manufacturing_settings.json
@@ -1,23 +1,32 @@
 {
  "allow_copy": 0, 
+ "allow_guest_to_view": 0, 
  "allow_import": 0, 
  "allow_rename": 0, 
+ "beta": 0, 
  "creation": "2014-11-27 14:12:07.542534", 
  "custom": 0, 
  "docstatus": 0, 
  "doctype": "DocType", 
  "document_type": "Document", 
+ "editable_grid": 0, 
+ "engine": "InnoDB", 
  "fields": [
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "capacity_planning", 
    "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": "Capacity Planning", 
    "length": 0, 
    "no_copy": 0, 
@@ -26,6 +35,7 @@
    "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, 
@@ -33,16 +43,21 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "description": "Disables creation of time logs against Production Orders. Operations shall not be tracked against Production Order", 
    "fieldname": "disable_capacity_planning", 
    "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": "Disable Capacity Planning and Time Tracking", 
    "length": 0, 
    "no_copy": 0, 
@@ -51,6 +66,7 @@
    "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, 
@@ -58,16 +74,21 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "description": "Plan time logs outside Workstation Working Hours.", 
    "fieldname": "allow_overtime", 
    "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": "Allow Overtime", 
    "length": 0, 
    "no_copy": 0, 
@@ -76,6 +97,7 @@
    "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, 
@@ -83,16 +105,21 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "default": "", 
    "fieldname": "allow_production_on_holidays", 
    "fieldtype": "Check", 
    "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": "Allow Production on Holidays", 
    "length": 0, 
    "no_copy": 0, 
@@ -102,6 +129,7 @@
    "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, 
@@ -109,15 +137,20 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "column_break_3", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
    "in_filter": 0, 
+   "in_global_search": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -125,6 +158,7 @@
    "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, 
@@ -132,17 +166,22 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "default": "30", 
    "description": "Try planning operations for X days in advance.", 
    "fieldname": "capacity_planning_for_days", 
    "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": "Capacity Planning For (Days)", 
    "length": 0, 
    "no_copy": 0, 
@@ -151,6 +190,7 @@
    "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, 
@@ -158,16 +198,21 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "description": "Default 10 mins", 
    "fieldname": "mins_between_operations", 
    "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": "Time Between Operations (in mins)", 
    "length": 0, 
    "no_copy": 0, 
@@ -176,6 +221,7 @@
    "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, 
@@ -183,15 +229,20 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "section_break_6", 
    "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, 
@@ -199,6 +250,7 @@
    "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, 
@@ -206,15 +258,20 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "over_production_allowance_percentage", 
    "fieldtype": "Percent", 
    "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": "Over Production Allowance Percentage", 
    "length": 0, 
    "no_copy": 0, 
@@ -223,6 +280,7 @@
    "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, 
@@ -230,16 +288,21 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "default": "BOM", 
    "fieldname": "backflush_raw_materials_based_on", 
    "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": "Backflush Raw Materials Based On", 
    "length": 0, 
    "no_copy": 0, 
@@ -249,6 +312,7 @@
    "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, 
@@ -256,15 +320,22 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "column_break_11", 
-   "fieldtype": "Column Break", 
+   "columns": 0, 
+   "description": "Update BOM cost automatically via Scheduler, based on latest valuation rate / price list rate / last purchase rate of raw materials.", 
+   "fieldname": "update_bom_costs_automatically", 
+   "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": "Update BOM Cost Automatically", 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -272,6 +343,7 @@
    "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, 
@@ -279,15 +351,49 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_11", 
+   "fieldtype": "Column Break", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_global_search": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "length": 0, 
+   "no_copy": 0, 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 0, 
+   "remember_last_selected_value": 0, 
+   "report_hide": 0, 
+   "reqd": 0, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_bulk_edit": 0, 
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "default_wip_warehouse", 
    "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": "Default Work In Progress Warehouse", 
    "length": 0, 
    "no_copy": 0, 
@@ -297,6 +403,7 @@
    "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, 
@@ -304,15 +411,20 @@
    "unique": 0
   }, 
   {
+   "allow_bulk_edit": 0, 
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "default_fg_warehouse", 
    "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": "Default Finished Goods Warehouse", 
    "length": 0, 
    "no_copy": 0, 
@@ -322,6 +434,7 @@
    "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, 
@@ -329,18 +442,19 @@
    "unique": 0
   }
  ], 
+ "has_web_view": 0, 
  "hide_heading": 0, 
  "hide_toolbar": 0, 
- "icon": "fa fa-wrench", 
+ "icon": "icon-wrench", 
  "idx": 0, 
+ "image_view": 0, 
  "in_create": 0, 
- "in_dialog": 0, 
  "is_submittable": 0, 
  "issingle": 1, 
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2015-12-10 00:03:20.895790", 
+ "modified": "2017-07-31 19:25:04.242693", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Manufacturing Settings", 
@@ -368,8 +482,12 @@
    "write": 1
   }
  ], 
+ "quick_entry": 0, 
  "read_only": 0, 
  "read_only_onload": 0, 
+ "show_name_in_global_search": 0, 
  "sort_field": "modified", 
- "sort_order": "DESC"
+ "sort_order": "DESC", 
+ "track_changes": 1, 
+ "track_seen": 0
 }
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/manufacturing_settings/test_manufacturing_settings.js b/erpnext/manufacturing/doctype/manufacturing_settings/test_manufacturing_settings.js
new file mode 100644
index 0000000..2b2589e
--- /dev/null
+++ b/erpnext/manufacturing/doctype/manufacturing_settings/test_manufacturing_settings.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: Manufacturing Settings", function (assert) {
+	let done = assert.async();
+
+	// number of asserts
+	assert.expect(1);
+
+	frappe.run_serially('Manufacturing Settings', [
+		// insert a new Manufacturing Settings
+		() => frappe.tests.make([
+			// values to be set
+			{key: 'value'}
+		]),
+		() => {
+			assert.equal(cur_frm.doc.key, 'value');
+		},
+		() => done()
+	]);
+
+});
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js
index c61eec6..33acb41 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order.js
@@ -91,7 +91,7 @@
 		frm.set_indicator_formatter('operation',
 			function(doc) { return (frm.doc.qty==doc.completed_qty) ? "green" : "orange" });
 	},
-	
+
 	refresh: function(frm) {
 		erpnext.toggle_naming_series();
 		erpnext.production_order.set_custom_buttons(frm);
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 022e9f3..5fedc72 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -523,7 +523,8 @@
 @frappe.whitelist()
 def make_stock_entry(production_order_id, purpose, qty=None):
 	production_order = frappe.get_doc("Production Order", production_order_id)
-	if not frappe.db.get_value("Warehouse", production_order.wip_warehouse, "is_group"):
+	if not frappe.db.get_value("Warehouse", production_order.wip_warehouse, "is_group") \
+			and not production_order.skip_transfer:
 		wip_warehouse = production_order.wip_warehouse
 	else:
 		wip_warehouse = None
diff --git a/erpnext/manufacturing/doctype/production_order_item/production_order_item.json b/erpnext/manufacturing/doctype/production_order_item/production_order_item.json
index 00e3adf..c0b1d00 100644
--- a/erpnext/manufacturing/doctype/production_order_item/production_order_item.json
+++ b/erpnext/manufacturing/doctype/production_order_item/production_order_item.json
@@ -229,6 +229,7 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "depends_on": "eval:!parent.skip_transfer", 
    "fieldname": "transferred_qty", 
    "fieldtype": "Float", 
    "hidden": 0, 
@@ -353,7 +354,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2017-07-10 17:37:20.212361", 
+ "modified": "2017-08-18 18:11:10.311736", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Order Item", 
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index f7a6abb..2ac000b 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -433,4 +433,6 @@
 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_8.update_gl_due_date_for_pi_and_si
\ No newline at end of file
+erpnext.patches.v8_7.fix_purchase_receipt_status
+erpnext.patches.v8_6.rename_bom_update_tool
+erpnext.patches.v8_8.update_gl_due_date_for_pi_and_si
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_0/reset_values_in_tools.py b/erpnext/patches/v5_0/reset_values_in_tools.py
index 5aac83e..fd970ba 100644
--- a/erpnext/patches/v5_0/reset_values_in_tools.py
+++ b/erpnext/patches/v5_0/reset_values_in_tools.py
@@ -6,7 +6,7 @@
 
 def execute():
 	for dt in ["Payment Tool", "Bank Reconciliation", "Payment Reconciliation", "Leave Control Panel", 
-		"Salary Manager", "Upload Attenadance", "Production Planning Tool", "BOM Replace Tool", "Customize Form",
-		 "Employee Attendance Tool", "Rename Tool", "BOM Replace Tool", "Process Payroll", "Naming Series"]:
+		"Salary Manager", "Upload Attenadance", "Production Planning Tool", "BOM Update Tool", "Customize Form",
+		 "Employee Attendance Tool", "Rename Tool", "BOM Update Tool", "Process Payroll", "Naming Series"]:
 			frappe.db.sql("delete from `tabSingles` where doctype=%s", dt)
 		
\ 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/patches/v8_6/rename_bom_update_tool.py b/erpnext/patches/v8_6/rename_bom_update_tool.py
new file mode 100644
index 0000000..45a4ddc
--- /dev/null
+++ b/erpnext/patches/v8_6/rename_bom_update_tool.py
@@ -0,0 +1,7 @@
+import frappe
+def execute():
+	frappe.delete_doc_if_exists("DocType", "BOM Replace Tool")
+
+	frappe.reload_doctype("BOM")
+	frappe.db.sql("update tabBOM set conversion_rate=1 where conversion_rate is null or conversion_rate=0")
+	frappe.db.sql("update tabBOM set set_rate_of_sub_assembly_item_based_on_bom=1")
\ No newline at end of file
diff --git a/erpnext/patches/v8_7/fix_purchase_receipt_status.py b/erpnext/patches/v8_7/fix_purchase_receipt_status.py
new file mode 100644
index 0000000..f7037dd
--- /dev/null
+++ b/erpnext/patches/v8_7/fix_purchase_receipt_status.py
@@ -0,0 +1,12 @@
+import frappe
+
+def execute():
+	# there is no more status called "Submitted", there was an old issue that used
+	# to set it as Submitted, fixed in this commit
+	frappe.db.sql("""
+	update
+		`tabPurchase Receipt`
+	set
+		status = 'To Bill'
+	where
+		status = 'Submitted'""")
\ No newline at end of file
diff --git a/erpnext/public/js/help_links.js b/erpnext/public/js/help_links.js
index 7de87b7..d8af0e5 100644
--- a/erpnext/public/js/help_links.js
+++ b/erpnext/public/js/help_links.js
@@ -508,8 +508,8 @@
 	{ label: 'Production Planning Tool', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/tools/production-planning-tool' },
 ]
 
-frappe.help.help_links['Form/BOM Replace Tool'] = [
-	{ label: 'BOM Replace Tool', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/tools/bom-replace-tool' },
+frappe.help.help_links['Form/BOM Update Tool'] = [
+	{ label: 'BOM Update Tool', url: 'https://frappe.github.io/erpnext/user/manual/en/manufacturing/tools/bom-update-tool' },
 ]
 
 //Customize
diff --git a/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py b/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py
index 1d94c97..1a54cc3 100644
--- a/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py
+++ b/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py
@@ -13,7 +13,8 @@
 		dict(fieldtype='Data', label='Invoice Type', width=120),
 		dict(fieldtype='Data', label='Export Type', width=120),
 		dict(fieldtype='Data', label='E-Commerce GSTIN', width=130),
-		dict(fieldtype='Data', label='HSN Code', width=120)
+		dict(fieldtype='Data', label='HSN Code', width=120),
+		dict(fieldtype='Data', label='Supplier Invoice No', width=120)
 	], additional_query_columns=[
 		'supplier_gstin',
 		'company_gstin',
@@ -21,5 +22,6 @@
 		'invoice_type',
 		'export_type',
 		'ecommerce_gstin',
-		'gst_hsn_code'
+		'gst_hsn_code',
+		'bill_no'
 	])
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/company/test_company.py b/erpnext/setup/doctype/company/test_company.py
index adbc598..a5afbdb 100644
--- a/erpnext/setup/doctype/company/test_company.py
+++ b/erpnext/setup/doctype/company/test_company.py
@@ -47,7 +47,7 @@
 	def test_coa_based_on_country_template(self):
 		countries = ["India", "Brazil", "United Arab Emirates", "Canada", "Germany", "France",
 			"Guatemala", "Indonesia", "Mexico", "Nicaragua", "Netherlands", "Singapore",
-			"Brazil", "Argentina", "Hungary"]
+			"Brazil", "Argentina", "Hungary", "Taiwan"]
 		
 		for country in countries:
 			templates = get_charts_for_country(country)
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 0444369..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`
@@ -115,9 +115,6 @@
 		frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
 			self.company, self.base_grand_total)
 
-		# Set status as Submitted
-		frappe.db.set(self, 'status', 'Submitted')
-
 		self.update_prevdoc_status()
 		if self.per_billed < 100:
 			self.update_billing_status()
@@ -152,8 +149,6 @@
 		if submitted:
 			frappe.throw(_("Purchase Invoice {0} is already submitted").format(submitted[0][0]))
 
-		frappe.db.set(self,'status','Cancelled')
-
 		self.update_prevdoc_status()
 		self.update_billing_status()
 
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 7c7e630..fbadbc5 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -556,7 +556,7 @@
 
 					item_dict = self.get_bom_raw_materials(self.fg_completed_qty)
 					for item in item_dict.values():
-						if self.pro_doc:
+						if self.pro_doc and not self.pro_doc.skip_transfer:
 							item["from_warehouse"] = self.pro_doc.wip_warehouse
 
 						item["to_warehouse"] = self.to_warehouse if self.purpose=="Subcontract" else ""
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/itemised_tax_breakup.html b/erpnext/templates/includes/itemised_tax_breakup.html
index 2ffc8b4..75212d5 100644
--- a/erpnext/templates/includes/itemised_tax_breakup.html
+++ b/erpnext/templates/includes/itemised_tax_breakup.html
@@ -22,7 +22,9 @@
 						{% set tax_details = taxes.get(tax_account) %}
 						{% if tax_details %}
 							<td class='text-right'>
-								({{ tax_details.tax_rate }})
+								{% if tax_details.tax_rate or not tax_details.tax_amount %}
+									({{ tax_details.tax_rate }})
+								{% endif %}
 								{{ frappe.utils.fmt_money(tax_details.tax_amount, None, company_currency) }}
 							</td>
 						{% else %}
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