Merge branch 'master' of github.com:webnotes/erpnext into edge
diff --git a/selling/doctype/sales_common/sales_common.py b/selling/doctype/sales_common/sales_common.py
index 82acaa1..4f883b2 100644
--- a/selling/doctype/sales_common/sales_common.py
+++ b/selling/doctype/sales_common/sales_common.py
@@ -415,8 +415,8 @@
 							'qty': flt(p.qty),
 							'reserved_qty': (flt(p.qty)/qty)*(reserved_qty),
 							'uom': p.uom,
-							'batch_no': p.batch_no,
-							'serial_no': p.serial_no,
+							'batch_no': cstr(p.batch_no).strip(),
+							'serial_no': cstr(p.serial_no).strip(),
 							'name': d.name
 						})
 			else:
@@ -427,8 +427,8 @@
 					'qty': qty,
 					'reserved_qty': reserved_qty,
 					'uom': d.stock_uom,
-					'batch_no': d.batch_no,
-					'serial_no': d.serial_no,
+					'batch_no': cstr(d.batch_no).strip(),
+					'serial_no': cstr(d.serial_no).strip(),
 					'name': d.name
 				})
 		return il
diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js
index 1ee4695..7af9b71 100644
--- a/selling/page/selling_home/selling_home.js
+++ b/selling/page/selling_home/selling_home.js
@@ -161,7 +161,7 @@
 			},
 			{
 				"label":wn._("Sales Orders Pending to be Delivered"),
-				route: "query-report/Sales Orders Pending to be Delivered"
+				route: "query-report/Sales Orders Pending To Be Delivered"
 			},
 		]
 	}
diff --git a/stock/doctype/packing_slip/packing_slip.py b/stock/doctype/packing_slip/packing_slip.py
index b90b0e6..5f4fda0 100644
--- a/stock/doctype/packing_slip/packing_slip.py
+++ b/stock/doctype/packing_slip/packing_slip.py
@@ -186,10 +186,30 @@
 		if not self.doc.from_case_no:
 			self.doc.from_case_no = self.get_recommended_case_no()
 
-		from webnotes.model.code import get_obj
-		for d in self.doclist:
-			psd_obj = get_obj(doc=d)
-			psd_obj.get_item_details(self.doc.delivery_note)
+		for d in self.doclist.get({"parentfield": "item_details"}):
+			self.set_item_details(d)
+
+
+	def set_item_details(self, row):
+		res = webnotes.conn.sql("""\
+			SELECT item_name, SUM(IFNULL(qty, 0)) as total_qty,
+			IFNULL(packed_qty,	0) as packed_qty, stock_uom
+			FROM `tabDelivery Note Item`
+			WHERE parent=%s AND item_code=%s GROUP BY item_code""",
+			(self.doc.delivery_note, row.item_code), as_dict=1)
+
+		if res and len(res)>0:
+			qty = res[0]['total_qty'] - res[0]['packed_qty']
+			if not row.qty:
+				row.qty = qty >= 0 and qty or 0
+
+		res = webnotes.conn.sql("""\
+			SELECT net_weight, weight_uom FROM `tabItem`
+			WHERE name=%s""", self.doc.item_code, as_dict=1)
+
+		if res and len(res)>0:
+			row.net_weight = res[0]["net_weight"]
+			row.weight_uom = res[0]["weight_uom"]
 
 
 	def get_recommended_case_no(self):
@@ -201,6 +221,4 @@
 			SELECT MAX(to_case_no) FROM `tabPacking Slip`
 			WHERE delivery_note = %(delivery_note)s AND docstatus=1""", self.doc.fields)
 
-		return cint(recommended_case_no[0][0]) + 1
-		
-
+		return cint(recommended_case_no[0][0]) + 1
\ No newline at end of file
diff --git a/stock/doctype/packing_slip_item/packing_slip_item.py b/stock/doctype/packing_slip_item/packing_slip_item.py
deleted file mode 100644
index cfd57e7..0000000
--- a/stock/doctype/packing_slip_item/packing_slip_item.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# ERPNext - web based ERP (http://erpnext.com)
-# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
-# 
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-# 
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-from __future__ import unicode_literals
-import webnotes
-
-class DocType:
-	def __init__(self, d, dl):
-		self.doc, self.doclist = d, dl
-
-	def get_item_details(self, delivery_note):
-		res = webnotes.conn.sql("""\
-			SELECT item_name, SUM(IFNULL(qty, 0)) as total_qty,
-			IFNULL(packed_qty,	0) as packed_qty, stock_uom
-			FROM `tabDelivery Note Item`
-			WHERE parent=%s AND item_code=%s GROUP BY item_code""",
-			(delivery_note, self.doc.item_code), as_dict=1)
-
-		if res and len(res)>0:
-			res = res[0]
-			res['qty'] = res['total_qty'] - res['packed_qty']
-			res['qty'] = self.doc.qty or (res['qty']>=0 and res['qty'] or 0)
-			del res['total_qty']
-			del res['packed_qty']
-			self.doc.fields.update(res)
-
-		res = webnotes.conn.sql("""\
-			SELECT net_weight, weight_uom FROM `tabItem`
-			WHERE name=%s""", self.doc.item_code, as_dict=1)
-
-		if res and len(res)>0:
-			res = res[0]
-			self.doc.fields.update(res)
diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py
index 46484e0..5bc0776 100644
--- a/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -154,15 +154,9 @@
 	def scrub_rejected_serial_nos(self):
 		for d in getlist(self.doclist, 'purchase_receipt_details'):
 			if d.rejected_serial_no:
-				d.rejected_serial_no = d.rejected_serial_no.replace(',', '\n')
+				d.rejected_serial_no = cstr(d.rejected_serial_no).strip().replace(',', '\n')
 				d.save()
 
-
-
-	# On Submit
-	# -----------------------------------------------------------------------------------------------------
-
- # Update Stock
 	def update_stock(self, is_submit):
 		pc_obj = get_obj('Purchase Common')
 		self.values = []
@@ -211,9 +205,9 @@
 	# make Stock Entry
 	def make_sl_entry(self, d, wh, qty, in_value, is_submit, rejected = 0):
 		if rejected:
-			serial_no = d.rejected_serial_no
+			serial_no = cstr(d.rejected_serial_no).strip()
 		else:
-			serial_no = d.serial_no
+			serial_no = cstr(d.serial_no).strip()
 
 		self.values.append({
 			'item_code'					: d.fields.has_key('item_code') and d.item_code or d.rm_item_code,
@@ -229,7 +223,7 @@
 			'company'					: self.doc.company,
 			'fiscal_year'				: self.doc.fiscal_year,
 			'is_cancelled'				: (is_submit==1) and 'No' or 'Yes',
-			'batch_no'					: d.batch_no,
+			'batch_no'					: cstr(d.batch_no).strip(),
 			'serial_no'					: serial_no
 			})
 
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index 6d09045..73af2bf 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -166,7 +166,7 @@
 				"posting_date": self.doc.posting_date,
 				"posting_time": self.doc.posting_time,
 				"qty": d.s_warehouse and -1*d.transfer_qty or d.transfer_qty,
-				"serial_no": d.serial_no,
+				"serial_no": cstr(d.serial_no).strip(),
 				"bom_no": d.bom_no,
 			})
 			# get actual stock at source warehouse
@@ -257,7 +257,7 @@
 			sl_obj.validate_serial_no_warehouse(self, 'mtn_details')
 		
 		for d in getlist(self.doclist, 'mtn_details'):
-			if d.serial_no:
+			if cstr(d.serial_no).strip():
 				for x in get_valid_serial_nos(d.serial_no):
 					serial_no = x.strip()
 					if d.s_warehouse:
@@ -536,8 +536,8 @@
 			'stock_uom': d.stock_uom,
 			'company': self.doc.company,
 			'is_cancelled': (is_cancelled ==1) and 'Yes' or 'No',
-			'batch_no': d.batch_no,
-			'serial_no': d.serial_no
+			'batch_no': cstr(d.batch_no).strip(),
+			'serial_no': cstr(d.serial_no).strip()
 		})
 	
 	def get_cust_values(self):
diff --git a/stock/doctype/stock_ledger/stock_ledger.py b/stock/doctype/stock_ledger/stock_ledger.py
index 86a8663..9f498d2 100644
--- a/stock/doctype/stock_ledger/stock_ledger.py
+++ b/stock/doctype/stock_ledger/stock_ledger.py
@@ -38,14 +38,14 @@
 		
 		for d in getlist(obj.doclist, table_name):
 			if d.serial_no:
-				d.serial_no = d.serial_no.replace(',', '\n')
+				d.serial_no = cstr(d.serial_no).strip().replace(',', '\n')
 				d.save()
 
 
 	def validate_serial_no_warehouse(self, obj, fname):
 		for d in getlist(obj.doclist, fname):
 			wh = d.warehouse or d.s_warehouse
-			if d.serial_no and wh:
+			if cstr(d.serial_no).strip() and wh:
 				serial_nos = get_valid_serial_nos(d.serial_no)
 				for s in serial_nos:
 					s = s.strip()
@@ -172,7 +172,6 @@
 
 
 	def update_serial_record(self, obj, fname, is_submit = 1, is_incoming = 0):
-		import datetime
 		for d in getlist(obj.doclist, fname):
 			if d.serial_no:
 				serial_nos = get_valid_serial_nos(d.serial_no)
@@ -191,10 +190,12 @@
 				
 	def update_stock(self, values, is_amended = 'No'):
 		for v in values:
-			sle_id, serial_nos = '', ''
+			sle_id, valid_serial_nos = '', ''
 			# get serial nos
-			if v.get("serial_no"):
-				serial_nos = get_valid_serial_nos(v["serial_no"], v['actual_qty'], v['item_code'])
+			if v.get("serial_no", "").strip():
+				valid_serial_nos = get_valid_serial_nos(v["serial_no"], 
+					v['actual_qty'], v['item_code'])
+				v["serial_no"] = valid_serial_nos and "\n".join(valid_serial_nos) or ""
 			
 			# reverse quantities for cancel
 			if v.get('is_cancelled') == 'Yes':