[enhance] scrap management
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index dbff91b..4882354 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -143,8 +143,6 @@
 	for(var i=0;i<sm.length;i++) {
 		amt =	flt(sm[i].rate) * flt(sm[i].qty);
 		set_multiple('BOM Scrap Item',sm[i].name, {'amount': amt}, 'scrap_items');
-		set_multiple('BOM Scrap Item',sm[i].name,
-			{'qty_consumed_per_unit': flt(sm[i].qty)/flt(doc.quantity)}, 'scrap_items');
 	}
 }
 
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 67c2129..e75d82b 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -425,6 +425,48 @@
 
 	return item_dict
 
+def get_bom_scrap_items_as_dict(bom, company, qty=1, fetch_exploded=1):
+	item_dict = {}
+
+	# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
+	query = """select
+				bom_scrap_item.item_code,
+				item.item_name,
+				sum(bom_scrap_item.qty/ifnull(bom.quantity, 1)) * %(qty)s as qty,
+				item.description,
+				item.image,
+				item.stock_uom,
+				item.default_warehouse,
+				item.expense_account as expense_account,
+				item.buying_cost_center as cost_center
+			from
+				`tabBOM Scrap Item` bom_scrap_item, `tabBOM` bom, `tabItem` item
+			where
+				bom_scrap_item.parent = bom.name
+				and bom_scrap_item.docstatus < 2
+				and bom_scrap_item.parent = %(bom)s
+				and item.name = bom_scrap_item.item_code
+				and is_stock_item = 1
+				group by item_code, stock_uom"""
+
+	items = frappe.db.sql(query, { "qty": qty, "bom": bom }, as_dict=True)
+
+	# make unique
+	for item in items:
+		if item_dict.has_key(item.item_code):
+			item_dict[item.item_code]["qty"] += flt(item.qty)
+		else:
+			item_dict[item.item_code] = item
+
+	for item, item_details in item_dict.items():
+		for d in [["Account", "expense_account", "default_expense_account"],
+			["Cost Center", "cost_center", "cost_center"], ["Warehouse", "default_warehouse", ""]]:
+				company_in_record = frappe.db.get_value(d[0], item_details.get(d[1]), "company")
+				if not item_details.get(d[1]) or (company_in_record and company != company_in_record):
+					item_dict[item][d[1]] = frappe.db.get_value("Company", company, d[2]) if d[2] else None
+
+	return item_dict
+
 @frappe.whitelist()
 def get_bom_items(bom, company, qty=1, fetch_exploded=1):
 	items = get_bom_items_as_dict(bom, company, qty, fetch_exploded).values()
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.json b/erpnext/manufacturing/doctype/production_order/production_order.json
index 28c1176..304c1c4 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.json
+++ b/erpnext/manufacturing/doctype/production_order/production_order.json
@@ -456,6 +456,33 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "scrap_warehouse", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "label": "Scrap Warehouse", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Warehouse", 
+   "permlevel": 0, 
+   "precision": "", 
+   "print_hide": 0, 
+   "print_hide_if_no_value": 0, 
+   "read_only": 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": "time", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -1133,7 +1160,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-09-19 02:48:09.412858", 
+ "modified": "2016-09-26 07:01:12.863755", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Order", 
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index ec3873e..98924db 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -148,7 +148,7 @@
 						if not d.t_warehouse:
 							frappe.throw(_("Target warehouse is mandatory for row {0}").format(d.idx))
 
-						elif self.pro_doc and cstr(d.t_warehouse) != self.pro_doc.fg_warehouse:
+						elif self.pro_doc and (cstr(d.t_warehouse) != self.pro_doc.fg_warehouse and cstr(d.t_warehouse) != self.pro_doc.scrap_warehouse):
 							frappe.throw(_("Target warehouse in row {0} must be same as Production Order").format(d.idx))
 
 					else:
@@ -348,14 +348,14 @@
 
 	def validate_bom(self):
 		for d in self.get('items'):
-			if d.bom_no:
+			if d.bom_no and (d.t_warehouse != self.pro_doc.scrap_warehouse):
 				validate_bom_no(d.item_code, d.bom_no)
 
 	def validate_finished_goods(self):
 		"""validation: finished good quantity should be same as manufacturing quantity"""
 		items_with_target_warehouse = []
 		for d in self.get('items'):
-			if d.bom_no and flt(d.transfer_qty) != flt(self.fg_completed_qty):
+			if d.bom_no and flt(d.transfer_qty) != flt(self.fg_completed_qty) and (d.t_warehouse != self.pro_doc.scrap_warehouse):
 				frappe.throw(_("Quantity in row {0} ({1}) must be same as manufactured quantity {2}"). \
 					format(d.idx, d.transfer_qty, self.fg_completed_qty))
 
@@ -557,7 +557,15 @@
 							item["from_warehouse"] = self.pro_doc.wip_warehouse
 
 						item["to_warehouse"] = self.to_warehouse if self.purpose=="Subcontract" else ""
+					
 					self.add_to_stock_entry_detail(item_dict)
+
+					scrap_item_dict = self.get_bom_scrap_material(self.fg_completed_qty)
+					for item in scrap_item_dict.values():
+						if self.pro_doc and self.pro_doc.scrap_warehouse:
+							item["to_warehouse"] = self.pro_doc.scrap_warehouse
+					self.add_to_stock_entry_detail(scrap_item_dict, bom_no=self.bom_no)
+					
 			# fetch the serial_no of the first stock entry for the second stock entry
 			if self.production_order and self.purpose == "Manufacture":
 				self.set_serial_nos(self.production_order)
@@ -607,7 +615,18 @@
 		for item in item_dict.values():
 			item.from_warehouse = self.from_warehouse or item.default_warehouse
 		return item_dict
+	
+	def get_bom_scrap_material(self, qty):
+		from erpnext.manufacturing.doctype.bom.bom import get_bom_scrap_items_as_dict
+		
+		# item dict = { item_code: {qty, description, stock_uom} }
+		item_dict = get_bom_scrap_items_as_dict(self.bom_no, self.company, qty=qty,
+			fetch_exploded = self.use_multi_level_bom)
 
+		for item in item_dict.values():
+			item.from_warehouse = ""
+		return item_dict
+	
 	def get_transfered_raw_materials(self):
 		transferred_materials = frappe.db.sql("""
 			select