Merge branch 'hotfix'
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 2597ed9..04f881c 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -4,7 +4,7 @@
 import frappe
 from erpnext.hooks import regional_overrides
 
-__version__ = '9.2.21'
+__version__ = '9.2.22'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.json b/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.json
index 1ff56d3..8c6242f 100644
--- a/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.json
+++ b/erpnext/accounts/report/sales_payment_summary/sales_payment_summary.json
@@ -1,5 +1,5 @@
 {
- "add_total_row": 0, 
+ "add_total_row": 1, 
  "apply_user_permissions": 1, 
  "creation": "2017-11-03 16:31:45.757516", 
  "disabled": 0, 
@@ -7,7 +7,7 @@
  "doctype": "Report", 
  "idx": 0, 
  "is_standard": "Yes", 
- "modified": "2017-11-03 17:00:37.871577", 
+ "modified": "2017-11-04 05:15:35.892659", 
  "modified_by": "Administrator", 
  "module": "Accounts", 
  "name": "Sales Payment Summary", 
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index e85e56b..4b73abd 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -399,7 +399,8 @@
 
 			for tax in self.doc.get("taxes"):
 				if tax.charge_type == "Actual":
-					actual_taxes_dict.setdefault(tax.idx, tax.tax_amount)
+					tax_amount = self.get_tax_amount_if_for_valuation_or_deduction(tax.tax_amount, tax)
+					actual_taxes_dict.setdefault(tax.idx, tax_amount)
 				elif tax.row_id in actual_taxes_dict:
 					actual_tax_amount = flt(actual_taxes_dict.get(tax.row_id, 0)) * flt(tax.rate) / 100
 					actual_taxes_dict.setdefault(tax.idx, actual_tax_amount)
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.js b/erpnext/manufacturing/doctype/production_order/production_order.js
index c3e6f20..68a5dc4 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/production_order.js
@@ -157,6 +157,7 @@
 					item: frm.doc.production_item,
 					project: frm.doc.project
 				},
+				freeze: true,
 				callback: function(r) {
 					if(r.message) {
 						erpnext.in_production_item_onchange = true;
@@ -184,6 +185,7 @@
 		return frm.call({
 			doc: frm.doc,
 			method: "get_items_and_operations_from_bom",
+			freeze: true,
 			callback: function(r) {
 				if(r.message["set_scrap_wh_mandatory"]){
 					frm.toggle_reqd("scrap_warehouse", true);
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 34ade10..891e6dc 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -43,10 +43,7 @@
 
 		validate_uom_is_integer(self, "stock_uom", ["qty", "produced_qty"])
 
-		if not self.get("required_items"):
-			self.set_required_items()
-		else:
-			self.set_available_qty()
+		self.set_required_items(reset_only_qty = len(self.get("required_items")))
 
 	def validate_sales_order(self):
 		if self.sales_order:
@@ -57,6 +54,19 @@
 					and so.docstatus = 1 and so_item.item_code=%s
 			""", (self.sales_order, self.production_item), as_dict=1)
 
+			if not so:
+				so = frappe.db.sql("""
+					select
+						so.name, so_item.delivery_date, so.project
+					from
+						`tabSales Order` so, `tabSales Order Item` so_item, `tabPacked Item` packed_item
+					where so.name=%s 
+						and so.name=so_item.parent
+						and so.name=packed_item.parent
+						and so_item.item_code = packed_item.parent_item
+						and so.docstatus = 1 and packed_item.item_code=%s
+				""", (self.sales_order, self.production_item), as_dict=1)
+
 			if len(so):
 				if not self.expected_delivery_date:
 					self.expected_delivery_date = so[0].delivery_date
@@ -431,21 +441,27 @@
 			if self.wip_warehouse:
 				d.available_qty_at_wip_warehouse = get_latest_stock_qty(d.item_code, self.wip_warehouse)
 
-	def set_required_items(self):
+	def set_required_items(self, reset_only_qty=False):
 		'''set required_items for production to keep track of reserved qty'''
-		self.required_items = []
+		if not reset_only_qty:
+			self.required_items = []
+
 		if self.bom_no and self.qty:
 			item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty,
 				fetch_exploded = self.use_multi_level_bom)
 
-			for item in sorted(item_dict.values(), key=lambda d: d['idx']):
-				self.append('required_items', {
-					'item_code': item.item_code,
-					'item_name': item.item_name,
-					'description': item.description,
-					'required_qty': item.qty,
-					'source_warehouse': item.source_warehouse or item.default_warehouse
-				})
+			if reset_only_qty:
+				for d in self.get("required_items"):
+					d.required_qty = item_dict.get(d.item_code).get("qty")
+			else:
+				for item in sorted(item_dict.values(), key=lambda d: d['idx']):
+					self.append('required_items', {
+						'item_code': item.item_code,
+						'item_name': item.item_name,
+						'description': item.description,
+						'required_qty': item.qty,
+						'source_warehouse': item.source_warehouse or item.default_warehouse
+					})
 
 			self.set_available_qty()
 
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 84624b8..960807a 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -521,9 +521,11 @@
 			var actual_taxes_dict = {};
 
 			$.each(this.frm.doc["taxes"] || [], function(i, tax) {
-				if (tax.charge_type == "Actual")
-					actual_taxes_dict[tax.idx] = tax.tax_amount;
-				else if (actual_taxes_dict[tax.row_id] !== null) {
+				if (tax.charge_type == "Actual") {
+					var tax_amount = (tax.category == "Valuation") ? 0.0 : tax.tax_amount;
+					tax_amount *= (tax.add_deduct_tax == "Deduct") ? -1.0 : 1.0;
+					actual_taxes_dict[tax.idx] = tax_amount;
+				} else if (actual_taxes_dict[tax.row_id] !== null) {
 					var actual_tax_amount = flt(actual_taxes_dict[tax.row_id]) * flt(tax.rate) / 100;
 					actual_taxes_dict[tax.idx] = actual_tax_amount;
 				}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 51e6c61..d928405 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -762,10 +762,15 @@
 	out = []
 
 	for i in items:
+		if not i.get("bom"):
+			frappe.throw(_("Please select BOM against item {0}").format(i.get("item_code")))
+		if not i.get("pending_qty"):
+			frappe.throw(_("Please select Qty against item {0}").format(i.get("item_code")))
+
 		production_order = frappe.get_doc(dict(
 			doctype='Production Order',
 			production_item=i['item_code'],
-			bom_no=i['bom'],
+			bom_no=i.get('bom'),
 			qty=i['pending_qty'],
 			company=company,
 			sales_order=sales_order,
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index 853b20d..d45db3e 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -281,7 +281,7 @@
 				'item_code'			: d.item_code,
 				'warehouse'			: cstr(d.s_warehouse) || cstr(d.t_warehouse),
 				'transfer_qty'		: d.transfer_qty,
-				'serial_no	'		: d.serial_no,
+				'serial_no'		: d.serial_no,
 				'bom_no'			: d.bom_no,
 				'expense_account'	: d.expense_account,
 				'cost_center'		: d.cost_center,