Packing Slip and its patches
diff --git a/erpnext/patches/jan_mar_2012/deploy_packing_slip.py b/erpnext/patches/jan_mar_2012/deploy_packing_slip.py
new file mode 100644
index 0000000..94bda6e
--- /dev/null
+++ b/erpnext/patches/jan_mar_2012/deploy_packing_slip.py
@@ -0,0 +1,48 @@
+import webnotes
+from webnotes.modules.module_manager import reload_doc
+
+def execute():
+	delete_fields_dn_detail()
+	deploy_packing_slip()
+	del_packing_slip_pf()
+
+
+def delete_fields_dn_detail():
+	"""
+		Delete old fields related to packing slip
+	"""
+	from webnotes.model import delete_fields
+	delete_fields({
+		'Delivery Note': [
+			'print_packing_slip', 'shipping_mark', 'packed_by',
+			'packing_checked_by', 'Text', 'pack_size'
+		],
+		'Delivery Note Detail': [
+			'pack_no', 'pack_gross_wt', 'weight_uom', 
+			'pack_nett_wt', 'no_of_packs', 'pack_unit', 'pack_size', 
+			'packed_by', 'packing_checked_by'
+		]
+	}, delete=1)
+	delete_fields({'Item': ['nett_weight', 'gross_weight']}, delete=1)
+	reload_doc('stock', 'doctype', 'delivery_note')
+	reload_doc('stock', 'doctype', 'delivery_note_detail')
+	reload_doc('stock', 'doctype', 'item')
+
+
+def deploy_packing_slip():
+	reload_doc('stock', 'doctype', 'packing_slip')
+	reload_doc('stock', 'doctype', 'packing_slip_detail')
+	reload_doc('stock', 'Module Def', 'Stock')
+	reload_doc('stock', 'DocType Mapper', 'Delivery Note-Packing Slip')
+
+
+def del_packing_slip_pf():
+	"""
+		Delete Print Format: 'Delivery Note Packing List Wise'
+	"""
+	webnotes.conn.sql("""\
+		DELETE FROM `tabDocFormat`
+		WHERE parent='Delivery Note'
+		AND format='Delivery Note Packing List Wise'""")
+	from webnotes.model import delete_doc
+	delete_doc('Print Format', 'Delivery Note Packing List Wise')
diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py
index c05912b..f569813 100644
--- a/erpnext/patches/patch_list.py
+++ b/erpnext/patches/patch_list.py
@@ -60,4 +60,9 @@
 		'patch_file': 'cancel_purchase_returned',
 		'description': "Set docstatus = 2 where status = 'Purchase Returned' for serial no"
 	},
+	{
+		'patch_module': 'patches.jan_mar_2012',
+		'patch_file': 'deploy_packing_slip',
+		'description': "Delete old packing slip fields & print format & deploy new doctypes related to Packing Slip"
+	},
 ]
diff --git a/erpnext/selling/doctype/sales_common/sales_common.js b/erpnext/selling/doctype/sales_common/sales_common.js
index a2f2760..8876fa4 100644
--- a/erpnext/selling/doctype/sales_common/sales_common.js
+++ b/erpnext/selling/doctype/sales_common/sales_common.js
@@ -5,11 +5,6 @@
 // cur_frm.cscript.other_fname - Other Charges fieldname
 // cur_frm.cscript.sales_team_fname - Sales Team fieldname
 
-function roundNumber(num, dec) {
-	var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
-	return result;
-}
-
 // ============== Load Default Taxes ===================
 cur_frm.cscript.load_taxes = function(doc, cdt, cdn) {
   // run if this is not executed from dt_map...
diff --git a/erpnext/stock/DocType Mapper/Delivery Note-Packing Slip/Delivery Note-Packing Slip.txt b/erpnext/stock/DocType Mapper/Delivery Note-Packing Slip/Delivery Note-Packing Slip.txt
new file mode 100644
index 0000000..171e08f
--- /dev/null
+++ b/erpnext/stock/DocType Mapper/Delivery Note-Packing Slip/Delivery Note-Packing Slip.txt
@@ -0,0 +1,93 @@
+# DocType Mapper, Delivery Note-Packing Slip
+[
+
+	# These values are common in all dictionaries
+	{
+		'creation': '2012-02-02 11:35:53',
+		'docstatus': 0,
+		'modified': '2012-02-02 11:35:53',
+		'modified_by': 'Administrator',
+		'owner': 'Administrator'
+	},
+
+	# These values are common for all Table Mapper Detail
+	{
+		'doctype': 'Table Mapper Detail',
+		'name': '__common__',
+		'parent': 'Delivery Note-Packing Slip',
+		'parentfield': 'table_mapper_details',
+		'parenttype': 'DocType Mapper'
+	},
+
+	# These values are common for all Field Mapper Detail
+	{
+		'doctype': 'Field Mapper Detail',
+		'name': '__common__',
+		'parent': 'Delivery Note-Packing Slip',
+		'parentfield': 'field_mapper_details',
+		'parenttype': 'DocType Mapper'
+	},
+
+	# These values are common for all DocType Mapper
+	{
+		'doctype': u'DocType Mapper',
+		'from_doctype': 'Delivery Note',
+		'module': 'Stock',
+		'name': '__common__',
+		'ref_doc_submitted': 1,
+		'to_doctype': 'Packing Slip'
+	},
+
+	# DocType Mapper, Delivery Note-Packing Slip
+	{
+		'doctype': u'DocType Mapper',
+		'name': 'Delivery Note-Packing Slip'
+	},
+
+	# Field Mapper Detail
+	{
+		'doctype': 'Field Mapper Detail',
+		'from_field': 'name',
+		'map': 'Yes',
+		'match_id': 0,
+		'to_field': 'delivery_note'
+	},
+
+	# Field Mapper Detail
+	{
+		'doctype': 'Field Mapper Detail',
+		'from_field': 'qty',
+		'map': 'No',
+		'match_id': 1,
+		'to_field': 'qty'
+	},
+
+	# Field Mapper Detail
+	{
+		'doctype': 'Field Mapper Detail',
+		'from_field': 'naming_series',
+		'map': 'No',
+		'match_id': 0,
+		'to_field': 'naming_series'
+	},
+
+	# Table Mapper Detail
+	{
+		'doctype': 'Table Mapper Detail',
+		'from_table': 'Delivery Note',
+		'match_id': 0,
+		'to_table': 'Packing Slip',
+		'validation_logic': 'docstatus=1'
+	},
+
+	# Table Mapper Detail
+	{
+		'doctype': 'Table Mapper Detail',
+		'from_field': 'delivery_note_details',
+		'from_table': 'Delivery Note Detail',
+		'match_id': 1,
+		'to_field': 'item_details',
+		'to_table': 'Packing Slip Detail',
+		'validation_logic': 'IFNULL(packed_qty, 0) < IFNULL(qty, 0)'
+	}
+]
\ No newline at end of file
diff --git a/erpnext/stock/Module Def/Stock/Stock.txt b/erpnext/stock/Module Def/Stock/Stock.txt
index 4fc8790..991d410 100644
--- a/erpnext/stock/Module Def/Stock/Stock.txt
+++ b/erpnext/stock/Module Def/Stock/Stock.txt
@@ -5,7 +5,7 @@
 	{
 		'creation': '2011-07-01 17:40:49',
 		'docstatus': 0,
-		'modified': '2011-10-10 17:01:34',
+		'modified': '2012-02-01 15:43:00',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
@@ -90,6 +90,16 @@
 
 	# Module Def Item
 	{
+		'description': 'Generate Packing Slips based on a Delivery Note',
+		'display_name': 'Packing Slip',
+		'doc_name': 'Packing Slip',
+		'doc_type': 'Forms',
+		'doctype': 'Module Def Item',
+		'fields': 'delivery_note\nfrom_case_no\nto_case_no\nnet_weight_pkg\ngross_weight_pkg'
+	},
+
+	# Module Def Item
+	{
 		'description': 'Record of incoming material from your suppliers',
 		'display_name': 'Purchase Receipt',
 		'doc_name': 'Purchase Receipt',
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 5cb4276..59dff8a 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -46,6 +46,10 @@
     cur_frm.add_custom_button('Send SMS', cur_frm.cscript['Send SMS']);
     unhide_field(['SMS','Send SMS', 'message', 'customer_mobile_no', 'Repair Delivery Note']);
   }
+
+  if(doc.docstatus==1) {
+    cur_frm.add_custom_button('Make Packing Slip', cur_frm.cscript['Make Packing Slip']);
+  }
   
   set_print_hide(doc, cdt, cdn);
 }
@@ -280,6 +284,23 @@
     msgprint("Item installation is already completed")
 }
 
+//-----------------------------------Make Sales Invoice----------------------------------------------
+cur_frm.cscript['Make Packing Slip'] = function() {
+  var doc = cur_frm.doc
+  n = createLocal('Packing Slip');
+  $c('dt_map', args={
+    'docs':compress_doclist([locals['Packing Slip'][n]]),
+    'from_doctype':doc.doctype,
+    'to_doctype':'Packing Slip',
+    'from_docname':doc.name,
+    'from_to_list':"[['Delivery Note','Packing Slip'],['Delivery Note Detail','Packing Slip Detail']]"
+    }, function(r,rt) {
+       loaddoc('Packing Slip', n);
+    }
+  );
+}
+
+
 //get query select Territory
 //=======================================================================================================================
 cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 8fc1abc..f791893 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -171,9 +171,6 @@
 		self.doc.in_words = sales_com_obj.get_total_in_words(dcc, self.doc.rounded_total)
 		self.doc.in_words_export = sales_com_obj.get_total_in_words(self.doc.currency, self.doc.rounded_total_export)
 
-		# ::::::: Set Net Weight of each Packing
-		self.update_pack_nett_weight()
-		self.print_packing_slip()
 		# ::::::: Set actual qty for each item in selected warehouse :::::::
 		self.update_current_stock()
 		# :::::: set DN status :::::::
@@ -340,6 +337,7 @@
 		self.update_stock_ledger(update_stock = -1)
 		# :::::: set DN status :::::::
 		set(self.doc, 'status', 'Cancelled')
+		self.cancel_packing_slips()
 
 
 	# ******************** Check Next DocStatus **************************
@@ -355,6 +353,23 @@
 			raise Exception , "Validation Error."
 
 
+	def cancel_packing_slips(self):
+		"""
+			Cancel submitted packing slips related to this delivery note
+		"""
+		res = webnotes.conn.sql("""\
+			SELECT name, count(*) FROM `tabPacking Slip`
+			WHERE delivery_note = %s AND docstatus = 1
+			""", self.doc.name)
+
+		if res and res[0][1]>0:
+			from webnotes.model.doclist import DocList
+			for r in res:
+				ps = DocList(dt='Packing Slip', dn=r[0])
+				ps.cancel()
+			webnotes.msgprint("%s Packing Slip(s) Cancelled" % res[0][1])
+
+
 # UPDATE STOCK LEDGER
 # =================================================================================================
 	def update_stock_ledger(self, update_stock, is_stopped = 0):
@@ -432,84 +447,3 @@
 	def repair_delivery_note(self):
 		get_obj('Sales Common', 'Sales Common').repair_curr_doctype_details(self)
 
-	# Packing Slip Related
-	# ==========================================
-	def update_pack_nett_weight(self):
-			for d in getlist(self.doclist, 'delivery_note_details'):
-				if d.item_code and not d.pack_nett_wt:
-					item_wt = sql("select nett_weight from `tabItem` where name = %s", (d.item_code))
-					d.pack_nett_wt = item_wt and flt(item_wt[0][0]) or 0
-
-
-	# ==========================================
-	def get_header(self, so_no, shipping_mark):
-		header = '''
-			<div align="center">[HEADER GOES HERE]</div>
-			<div><center><h2>Packing Slip</h2></center></div>
-			<table width="100%" class="large_font">
-				<tr>
-					<td width="20%">ORDER NO.</td>
-					<td width="30%">'''+cstr(so_no)+'''</td>
-					<td width="20%">SHIPPING MARKS</td>
-					<td width="30%">'''+cstr(shipping_mark)+'''</td>
-				</tr>
-			</table>''';
-			
-		return header
-		
-	def get_footer(self, row, tot_nett, tot_gross):
-		footer = '''
-			<table style="page-break-after:always" width="100%" class="large_font">
-				<tr>
-					<td>CASE NO</td><td>'''+cstr(row.pack_no)+'''</td>
-					<td>NETT WT</td><td>'''+cstr(tot_nett)+'''</td>
-					<td>CHECKED BY</td><td>'''+cstr(row.packing_checked_by)+'''</td>
-				</tr>
-				<tr>
-					<td>SIZE</td><td>'''+cstr(row.pack_size)+'''</td>
-					<td>GROSS WT</td><td>'''+cstr(tot_gross)+'''</td>
-					<td>PACKED BY</td><td>'''+cstr(row.packed_by)+'''</td>
-				</tr>
-			</table>'''
-	
-		return footer
-	
-	def print_packing_slip(self):
-		plist = {}
-		for d in getlist(self.doclist, 'delivery_note_details'):
-			if not plist.has_key(cstr(d.pack_no)):
-				plist[cstr(d.pack_no)] = [d]
-			else:
-				plist.get(cstr(d.pack_no)).append(d)
-
-		html=''
-		
-		for d in sorted(plist.keys()):
-			tot_nett_wt,tot_gross_wt=0,0
-			
-			# header
-			html += self.get_header(self.doc.sales_order_no, self.doc.shipping_mark)
-			
-			# item table header
-			html += '''
-				<table class="cust_tbl" width="100%">
-					<tr>
-						<td><b>SR.NO.</b></td><td><b>CS.NO.</b></td><td><b>DESCRIPTION</b></td>
-						<td><b>QUANTITY</b></td><td><b>WEIGHT</b></td>
-					</tr>'''
-					
-			# item table data
-			sr_no = 1
-			for r in plist.get(d):
-				html += '<tr><td>'+cstr(sr_no)+'</td><td>'+r.item_code+'</td><td>'+r.description+'</td><td>'+cstr(r.qty)+'</td><td>'+cstr(r.pack_nett_wt)+'</td></tr>'
-				
-				tot_nett_wt += flt(r.pack_nett_wt)
-				tot_gross_wt += flt(r.pack_gross_wt)
-				
-				sr_no += 1
-				
-			html += '</table>'
-
-			# footer
-			html += self.get_footer(r, tot_nett_wt, tot_gross_wt)
-		self.doc.print_packing_slip=html
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.txt b/erpnext/stock/doctype/delivery_note/delivery_note.txt
index 3078bf6..00bf9a8 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.txt
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.txt
@@ -5,7 +5,7 @@
 	{
 		'creation': '2011-04-18 15:58:20',
 		'docstatus': 0,
-		'modified': '2012-01-09 16:52:43',
+		'modified': '2012-01-30 16:52:12',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
@@ -21,7 +21,7 @@
 
 	# These values are common for all DocType
 	{
-		'_last_update': '1326105502',
+		'_last_update': '1326273792',
 		'colour': 'White:FFF',
 		'default_print_format': 'Standard',
 		'doctype': 'DocType',
@@ -37,7 +37,7 @@
 		'show_in_menu': 0,
 		'subject': 'To %(customer_name)s on %(transaction_date)s | %(per_billed)s% billed',
 		'tag_fields': 'billing_status',
-		'version': 463
+		'version': 464
 	},
 
 	# These values are common for all DocFormat
@@ -1433,53 +1433,5 @@
 		'options': 'repair_delivery_note',
 		'permlevel': 0,
 		'print_hide': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'print_packing_slip',
-		'fieldtype': 'Text',
-		'hidden': 1,
-		'in_filter': 0,
-		'label': 'Print Packing Slip',
-		'permlevel': 0,
-		'print_hide': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'shipping_mark',
-		'fieldtype': 'Text',
-		'label': 'Shipping Mark',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'packed_by',
-		'fieldtype': 'Text',
-		'label': 'Packed By',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'packing_checked_by',
-		'fieldtype': 'Text',
-		'label': 'Packing Checked By',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'pack_size',
-		'fieldtype': 'Text',
-		'label': 'Pack Size',
-		'permlevel': 0
 	}
 ]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt b/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt
index 806803f..a10d1d6 100644
--- a/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt
+++ b/erpnext/stock/doctype/delivery_note_detail/delivery_note_detail.txt
@@ -5,7 +5,7 @@
 	{
 		'creation': '2010-08-08 17:08:58',
 		'docstatus': 0,
-		'modified': '2011-10-18 16:32:44',
+		'modified': '2012-02-01 16:08:06',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
@@ -23,7 +23,7 @@
 		'section_style': 'Tray',
 		'server_code_error': ' ',
 		'show_in_menu': 0,
-		'version': 43
+		'version': 51
 	},
 
 	# These values are common for all DocField
@@ -292,104 +292,6 @@
 	# DocField
 	{
 		'doctype': 'DocField',
-		'fieldname': 'pack_no',
-		'fieldtype': 'Data',
-		'label': 'Pack No',
-		'permlevel': 0,
-		'print_hide': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'pack_gross_wt',
-		'fieldtype': 'Float',
-		'label': 'Pack Gross Wt',
-		'permlevel': 0,
-		'print_hide': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'weight_uom',
-		'fieldtype': 'Link',
-		'label': 'Weight UOM',
-		'options': 'UOM',
-		'permlevel': 0,
-		'print_hide': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'pack_nett_wt',
-		'fieldtype': 'Float',
-		'label': 'Pack Nett Wt',
-		'permlevel': 0,
-		'print_hide': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'no_of_packs',
-		'fieldtype': 'Int',
-		'label': 'No of Packs',
-		'oldfieldname': 'no_of_packs',
-		'oldfieldtype': 'Int',
-		'permlevel': 0,
-		'print_hide': 1,
-		'width': '100px'
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'pack_unit',
-		'fieldtype': 'Data',
-		'label': 'Pack Unit',
-		'oldfieldname': 'pack_unit',
-		'oldfieldtype': 'Data',
-		'permlevel': 0,
-		'print_hide': 1,
-		'width': '100px'
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'pack_size',
-		'fieldtype': 'Data',
-		'label': 'Pack Size',
-		'no_copy': 0,
-		'permlevel': 0,
-		'print_hide': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'packed_by',
-		'fieldtype': 'Data',
-		'label': 'Packed By',
-		'permlevel': 0,
-		'print_hide': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'packing_checked_by',
-		'fieldtype': 'Data',
-		'label': 'Packing Checked By',
-		'permlevel': 0,
-		'print_hide': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
 		'fieldname': 'installed_qty',
 		'fieldtype': 'Currency',
 		'label': 'Installed Qty',
@@ -507,6 +409,20 @@
 	# DocField
 	{
 		'allow_on_submit': 1,
+		'colour': 'White:FFF',
+		'default': '0',
+		'doctype': 'DocField',
+		'fieldname': 'packed_qty',
+		'fieldtype': 'Currency',
+		'label': 'Packed Quantity',
+		'no_copy': 1,
+		'permlevel': 1,
+		'print_hide': 1
+	},
+
+	# DocField
+	{
+		'allow_on_submit': 1,
 		'doctype': 'DocField',
 		'fieldname': 'page_break',
 		'fieldtype': 'Check',
diff --git a/erpnext/stock/doctype/item/item.txt b/erpnext/stock/doctype/item/item.txt
index d6ac71b..db04bcf 100644
--- a/erpnext/stock/doctype/item/item.txt
+++ b/erpnext/stock/doctype/item/item.txt
@@ -5,14 +5,14 @@
 	{
 		'creation': '2010-08-08 17:09:05',
 		'docstatus': 0,
-		'modified': '2012-01-17 18:39:39',
+		'modified': '2012-01-30 17:34:23',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
 
 	# These values are common for all DocType
 	{
-		'_last_update': '1325570647',
+		'_last_update': '1326963484',
 		'allow_attach': 1,
 		'allow_trash': 1,
 		'autoname': 'field:item_code',
@@ -29,7 +29,7 @@
 		'show_in_menu': 0,
 		'subject': '%(item_name)s',
 		'tag_fields': 'item_group',
-		'version': 164
+		'version': 165
 	},
 
 	# These values are common for all DocField
@@ -467,19 +467,11 @@
 
 	# DocField
 	{
+		'description': 'Net Weight of each Item',
 		'doctype': 'DocField',
-		'fieldname': 'nett_weight',
+		'fieldname': 'net_weight',
 		'fieldtype': 'Float',
-		'label': 'Nett Weight',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'gross_weight',
-		'fieldtype': 'Float',
-		'label': 'Gross Weight',
+		'label': 'Net Weight',
 		'permlevel': 0
 	},
 
diff --git a/erpnext/stock/doctype/packing_slip/__init__.py b/erpnext/stock/doctype/packing_slip/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/stock/doctype/packing_slip/__init__.py
diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.js b/erpnext/stock/doctype/packing_slip/packing_slip.js
new file mode 100644
index 0000000..1bf1f2e
--- /dev/null
+++ b/erpnext/stock/doctype/packing_slip/packing_slip.js
@@ -0,0 +1,123 @@
+cur_frm.fields_dict['delivery_note'].get_query = function(doc, cdt, cdn) {
+	return 'SELECT name FROM `tabDelivery Note` WHERE docstatus=1 AND %(key)s LIKE "%s"';
+}
+
+
+cur_frm.fields_dict['item_details'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
+	return 'SELECT name, description FROM `tabItem` WHERE name IN ( \
+		SELECT item_code FROM `tabDelivery Note Detail` \
+		WHERE parent="'	+ doc.delivery_note + '") AND %(key)s LIKE "%s" LIMIT 50';
+}
+
+
+// Fetch item details
+cur_frm.cscript.item_code = function(doc, cdt, cdn) {
+	if(locals[cdt][cdn].item_code) {
+		$c_obj(make_doclist(cdt, cdn), 'get_item_details', doc.delivery_note, function(r, rt) {
+			if(r.exc) {
+				msgprint(r.exc);
+			} else {
+				refresh_field('item_details');
+			}
+		});
+	}
+}
+
+
+cur_frm.cscript.onload = function(doc, cdt, cdn) {
+	if(doc.delivery_note) {
+		var ps_detail = getchildren('Packing Slip Detail', doc.name, 'item_details');
+		if(!(flt(ps_detail[0].net_weight) && cstr(ps_detail[0].weight_uom))) {
+			cur_frm.cscript.update_item_details(doc);
+			refresh_field('naming_series');
+		}
+	}
+}
+
+
+cur_frm.cscript.update_item_details = function(doc) {
+	$c_obj(make_doclist(doc.doctype, doc.name), 'update_item_details', '', function(r, rt) {
+		if(r.exc) {
+			msgprint(r.exc);
+		} else {
+			refresh_field('item_details');
+		}
+	});
+}
+
+
+cur_frm.cscript.validate = function(doc, cdt, cdn) {
+	cur_frm.cscript.validate_case_nos(doc);
+	cur_frm.cscript.validate_calculate_item_details(doc);
+}
+
+
+// To Case No. cannot be less than From Case No.
+cur_frm.cscript.validate_case_nos = function(doc) {
+	doc = locals[doc.doctype][doc.name];
+	if(cint(doc.from_case_no)==0) {
+		msgprint("Case No. cannot be 0")
+		validated = false;
+	} else if(!cint(doc.to_case_no)) {
+		doc.to_case_no = doc.from_case_no;
+		refresh_field('to_case_no');
+	} else if(cint(doc.to_case_no) < cint(doc.from_case_no)) {
+		msgprint("'To Case No.' cannot be less than 'From Case No.'");
+		validated = false;
+	}	
+}
+
+
+cur_frm.cscript.validate_calculate_item_details = function(doc) {
+	doc = locals[doc.doctype][doc.name];
+	var ps_detail = getchildren('Packing Slip Detail', doc.name, 'item_details');
+
+	cur_frm.cscript.validate_duplicate_items(doc, ps_detail);
+	cur_frm.cscript.calc_net_total_pkg(doc, ps_detail);
+}
+
+
+// Do not allow duplicate items i.e. items with same item_code
+// Also check for 0 qty
+cur_frm.cscript.validate_duplicate_items = function(doc, ps_detail) {
+	for(var i=0; i<ps_detail.length; i++) {
+		for(var j=0; j<ps_detail.length; j++) {
+			if(i!=j && ps_detail[i].item_code==ps_detail[j].item_code) {
+				msgprint("You have entered duplicate items. Please rectify and try again.");
+				validated = false;
+				return;
+			}
+		}
+		if(flt(ps_detail[i].qty)<=0) {
+			msgprint("Invalid quantity specified for item " + ps_detail[i].item_code +
+				". Quantity should be greater than 0.");
+			validated = false;
+		}
+	}
+}
+
+
+// Calculate Net Weight of Package
+cur_frm.cscript.calc_net_total_pkg = function(doc, ps_detail) {
+	var net_weight_pkg = 0;
+	doc.net_weight_uom = ps_detail?ps_detail[0].weight_uom:'';
+	doc.gross_weight_uom = doc.net_weight_uom;
+
+	for(var i=0; i<ps_detail.length; i++) {
+		var item = ps_detail[i];
+		if(item.weight_uom != doc.net_weight_uom) {
+			msgprint("Different UOM for items will lead to incorrect \
+			(Total) Net Weight value. Make sure that Net Weight of each item is \
+			in the same UOM.")
+			validated = false;
+		}
+		net_weight_pkg += flt(item.net_weight) * flt(item.qty);
+	}
+
+	doc.net_weight_pkg = roundNumber(net_weight_pkg, 2);
+	if(!flt(doc.gross_weight_pkg)) {
+		doc.gross_weight_pkg = doc.net_weight_pkg
+	}
+	refresh_many(['net_weight_pkg', 'net_weight_uom', 'gross_weight_uom', 'gross_weight_pkg']);
+}
+
diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.py b/erpnext/stock/doctype/packing_slip/packing_slip.py
new file mode 100644
index 0000000..33ec2b5
--- /dev/null
+++ b/erpnext/stock/doctype/packing_slip/packing_slip.py
@@ -0,0 +1,156 @@
+import webnotes
+from webnotes.utils import flt, cint
+
+class DocType:
+	def __init__(self, d, dl):
+		self.doc, self.doclist = d, dl
+
+
+	def validate(self):
+		"""
+			* Validate existence of submitted Delivery Note
+			* Case nos do not overlap
+			* Check if packed qty doesn't exceed actual qty of delivery note
+
+			It is necessary to validate case nos before checking quantity
+		"""
+		self.validate_delivery_note()
+		self.validate_case_nos()
+		self.validate_qty()
+
+
+	def validate_delivery_note(self):
+		"""
+			Validates if delivery note has status as submitted
+		"""
+		res = webnotes.conn.sql("""\
+			SELECT docstatus FROM `tabDelivery Note`
+			WHERE name=%(delivery_note)s
+			""", self.doc.fields)
+
+		if not(res and res[0][0]==1):
+			webnotes.msgprint("""Invalid Delivery Note. Delivery Note should exist 
+				and should be submitted. Please rectify and try again.""", raise_exception=1)
+
+
+	def validate_case_nos(self):
+		"""
+			Validate if case nos overlap
+			If they do, recommend next case no.
+		"""
+		res = webnotes.conn.sql("""\
+			SELECT name FROM `tabPacking Slip`
+			WHERE delivery_note = %(delivery_note)s AND docstatus = 1 AND
+			(from_case_no BETWEEN %(from_case_no)s AND %(to_case_no)s
+			OR to_case_no BETWEEN %(from_case_no)s AND %(to_case_no)s)\
+			""", self.doc.fields)
+
+		if res:
+			recommended_case_no = webnotes.conn.sql("""\
+				SELECT MAX(to_case_no) FROM `tabPacking Slip`
+				WHERE delivery_note = %(delivery_note)s AND docstatus=1""", self.doc.fields)
+			
+			webnotes.msgprint("""Case No(s). already in use. Please rectify and try again.
+				Recommended <b>From Case No. = %s</b>""" % (cint(recommended_case_no[0][0]) + 1),
+				raise_exception=1)
+
+
+	def validate_qty(self):
+		"""
+			Check packed qty across packing slips and delivery note
+		"""
+		# Get Delivery Note Details, Item Quantity Dict and No. of Cases for this Packing slip
+		dn_details, ps_item_qty, no_of_cases = self.get_details_for_packing()
+
+		for item in dn_details:
+			new_packed_qty = (flt(ps_item_qty[item['item_code']]) * no_of_cases) + flt(item['packed_qty'])
+			if new_packed_qty > flt(item['qty']):
+				self.recommend_new_qty(item, ps_item_qty, no_of_cases)
+
+
+	def get_details_for_packing(self):
+		"""
+			Returns
+			* 'Delivery Note Details' query result as a list of dict
+			* Item Quantity dict of current packing slip doc
+			* No. of Cases of this packing slip
+		"""
+		item_codes = ", ".join([('"' + d.item_code + '"') for d in self.doclist])
+
+		res = webnotes.conn.sql("""\
+			SELECT item_code, IFNULL(SUM(qty), 0) as qty, IFNULL(packed_qty, 0) as packed_qty, stock_uom
+			FROM `tabDelivery Note Detail`
+			WHERE parent = "%s" AND item_code IN (%s)
+			GROUP BY item_code""" % (self.doc.delivery_note, item_codes), as_dict=1)
+
+		ps_item_qty = dict([[d.item_code, d.qty] for d in self.doclist])
+
+		no_of_cases = cint(self.doc.to_case_no) - cint(self.doc.from_case_no) + 1
+
+		return res, ps_item_qty, no_of_cases
+
+
+	def recommend_new_qty(self, item, ps_item_qty, no_of_cases):
+		"""
+			Recommend a new quantity and raise a validation exception
+		"""
+		item['recommended_qty'] = (flt(item['qty']) - flt(item['packed_qty'])) / no_of_cases
+		item['specified_qty'] = flt(ps_item_qty[item['item_code']])
+		
+		webnotes.msgprint("""\
+			Invalid Quantity specified (%(specified_qty)s %(stock_uom)s).
+			%(packed_qty)s out of %(qty)s %(stock_uom)s already packed for %(item_code)s.
+			<b>Recommended quantity for %(item_code)s = %(recommended_qty)s \
+			%(stock_uom)s</b>""" % item, raise_exception=1)
+
+
+	def on_submit(self):
+		"""
+			* Update packed qty for all items
+		"""
+		self.update_packed_qty(event='submit')
+
+
+	def on_cancel(self):
+		"""
+			* Update packed qty for all items
+		"""
+		self.update_packed_qty(event='cancel')
+
+
+	def update_packed_qty(self, event=''):
+		"""
+			Updates packed qty for all items
+		"""
+		if event not in ['submit', 'cancel']:
+			raise Exception('update_packed_quantity can only be called on submit or cancel')
+
+		# Get Delivery Note Details, Item Quantity Dict and No. of Cases for this Packing slip
+		dn_details, ps_item_qty, no_of_cases = self.get_details_for_packing()
+
+		for item in dn_details:
+			if event=='submit':
+				new_packed_qty = flt(item['packed_qty']) + (flt(ps_item_qty[item['item_code']]) * no_of_cases)
+
+			elif event=='cancel':
+				new_packed_qty = flt(item['packed_qty']) - (flt(ps_item_qty[item['item_code']]) * no_of_cases)
+
+			if (new_packed_qty < 0) or (new_packed_qty > flt(item['qty'])):
+				webnotes.msgprint("Invalid new packed quantity for item %s. \
+					Please try again or contact support@erpnext.com" % item['item_code'], raise_exception=1)
+
+			webnotes.conn.sql("""\
+				UPDATE `tabDelivery Note Detail`
+				SET packed_qty = %s
+				WHERE parent = %s AND item_code = %s""",
+				(new_packed_qty, self.doc.delivery_note, item['item_code']))			
+
+
+	def update_item_details(self):
+		"""
+			Fill empty columns in Packing Slip Detail
+		"""
+		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)
diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.txt b/erpnext/stock/doctype/packing_slip/packing_slip.txt
new file mode 100644
index 0000000..6c54a9d
--- /dev/null
+++ b/erpnext/stock/doctype/packing_slip/packing_slip.txt
@@ -0,0 +1,314 @@
+# DocType, Packing Slip
+[
+
+	# These values are common in all dictionaries
+	{
+		'creation': '2012-01-30 12:13:10',
+		'docstatus': 0,
+		'modified': '2012-02-02 10:37:15',
+		'modified_by': 'Administrator',
+		'owner': 'Administrator'
+	},
+
+	# These values are common for all DocType
+	{
+		'_last_update': '1328091392',
+		'autoname': 'PS.#######',
+		'colour': 'White:FFF',
+		'doctype': 'DocType',
+		'document_type': 'Transaction',
+		'is_transaction_doc': 1,
+		'module': 'Stock',
+		'name': '__common__',
+		'read_only_onload': 1,
+		'search_fields': 'delivery_note',
+		'section_style': 'Simple',
+		'show_in_menu': 0,
+		'subject': '[%(delivery_note)s] Case Nos: %(from_case_no)s - %(to_case_no)s  |  Net Weight: %(net_weight_pkg)s %(net_weight_uom)s  |  Gross Weight: %(gross_weight_pkg)s %(gross_weight_uom)s',
+		'version': 40
+	},
+
+	# These values are common for all DocField
+	{
+		'doctype': 'DocField',
+		'name': '__common__',
+		'parent': 'Packing Slip',
+		'parentfield': 'fields',
+		'parenttype': 'DocType'
+	},
+
+	# These values are common for all DocPerm
+	{
+		'doctype': 'DocPerm',
+		'name': '__common__',
+		'parent': 'Packing Slip',
+		'parentfield': 'permissions',
+		'parenttype': 'DocType',
+		'read': 1
+	},
+
+	# DocType, Packing Slip
+	{
+		'doctype': 'DocType',
+		'name': 'Packing Slip'
+	},
+
+	# DocPerm
+	{
+		'amend': 1,
+		'cancel': 1,
+		'create': 1,
+		'doctype': 'DocPerm',
+		'permlevel': 0,
+		'role': 'Material User',
+		'submit': 1,
+		'write': 1
+	},
+
+	# DocPerm
+	{
+		'amend': 1,
+		'cancel': 1,
+		'create': 1,
+		'doctype': 'DocPerm',
+		'permlevel': 0,
+		'role': 'Sales User',
+		'submit': 1,
+		'write': 1
+	},
+
+	# DocPerm
+	{
+		'amend': 1,
+		'cancel': 1,
+		'create': 1,
+		'doctype': 'DocPerm',
+		'permlevel': 0,
+		'role': 'Material Master Manager',
+		'submit': 1,
+		'write': 1
+	},
+
+	# DocPerm
+	{
+		'amend': 1,
+		'cancel': 1,
+		'create': 1,
+		'doctype': 'DocPerm',
+		'permlevel': 0,
+		'role': 'Material Manager',
+		'submit': 1,
+		'write': 1
+	},
+
+	# DocPerm
+	{
+		'amend': 1,
+		'cancel': 1,
+		'create': 1,
+		'doctype': 'DocPerm',
+		'permlevel': 0,
+		'role': 'Sales Manager',
+		'submit': 1,
+		'write': 1
+	},
+
+	# DocPerm
+	{
+		'doctype': 'DocPerm',
+		'permlevel': 1,
+		'role': 'All'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Section Break',
+		'label': 'Packing Slip Details',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Column Break',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'delivery_note',
+		'fieldtype': 'Link',
+		'label': 'Delivery Note',
+		'options': 'Delivery Note',
+		'permlevel': 0,
+		'reqd': 1
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Column Break',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'naming_series',
+		'fieldtype': 'Select',
+		'label': 'Series',
+		'no_copy': 0,
+		'options': 'PS',
+		'permlevel': 0,
+		'print_hide': 1,
+		'reqd': 1
+	},
+
+	# DocField
+	{
+		'colour': 'White:FFF',
+		'doctype': 'DocField',
+		'fieldtype': 'Section Break',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Column Break',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'colour': 'White:FFF',
+		'doctype': 'DocField',
+		'fieldname': 'from_case_no',
+		'fieldtype': 'Data',
+		'label': 'From Case No.',
+		'no_copy': 1,
+		'permlevel': 0,
+		'reqd': 1,
+		'width': '50px'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Column Break',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'colour': 'White:FFF',
+		'doctype': 'DocField',
+		'fieldname': 'to_case_no',
+		'fieldtype': 'Data',
+		'label': 'To Case No.',
+		'no_copy': 1,
+		'permlevel': 0,
+		'width': '50px'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Section Break',
+		'label': 'Package Item Details',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'item_details',
+		'fieldtype': 'Table',
+		'label': 'Items',
+		'options': 'Packing Slip Detail',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Section Break',
+		'label': 'Package Weight Details',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'colour': 'White:FFF',
+		'doctype': 'DocField',
+		'fieldname': 'net_weight_pkg',
+		'fieldtype': 'Currency',
+		'label': 'Net Weight',
+		'no_copy': 1,
+		'permlevel': 1
+	},
+
+	# DocField
+	{
+		'colour': 'White:FFF',
+		'doctype': 'DocField',
+		'fieldname': 'net_weight_uom',
+		'fieldtype': 'Data',
+		'label': 'Net Weight UOM',
+		'no_copy': 1,
+		'permlevel': 1
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Column Break',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'colour': 'White:FFF',
+		'doctype': 'DocField',
+		'fieldname': 'gross_weight_pkg',
+		'fieldtype': 'Currency',
+		'label': 'Gross Weight',
+		'no_copy': 1,
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'colour': 'White:FFF',
+		'doctype': 'DocField',
+		'fieldname': 'gross_weight_uom',
+		'fieldtype': 'Link',
+		'label': 'Gross Weight UOM',
+		'no_copy': 1,
+		'options': 'UOM',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'depends_on': 'eval:doc.amended_from',
+		'doctype': 'DocField',
+		'fieldtype': 'Section Break',
+		'label': 'Misc Details',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'amended_from',
+		'fieldtype': 'Link',
+		'label': 'Amended From',
+		'no_copy': 1,
+		'options': 'Packing Slip',
+		'permlevel': 1,
+		'print_hide': 1
+	}
+]
\ No newline at end of file
diff --git a/erpnext/stock/doctype/packing_slip_detail/__init__.py b/erpnext/stock/doctype/packing_slip_detail/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/stock/doctype/packing_slip_detail/__init__.py
diff --git a/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.py b/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.py
new file mode 100644
index 0000000..05f502c
--- /dev/null
+++ b/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.py
@@ -0,0 +1,29 @@
+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 Detail`
+			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/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.txt b/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.txt
new file mode 100644
index 0000000..5a83b6f
--- /dev/null
+++ b/erpnext/stock/doctype/packing_slip_detail/packing_slip_detail.txt
@@ -0,0 +1,113 @@
+# DocType, Packing Slip Detail
+[
+
+	# These values are common in all dictionaries
+	{
+		'creation': '2012-01-30 17:40:50',
+		'docstatus': 0,
+		'modified': '2012-01-31 13:15:40',
+		'modified_by': 'Administrator',
+		'owner': 'Administrator'
+	},
+
+	# These values are common for all DocType
+	{
+		'autoname': 'PSD/.#######',
+		'colour': 'White:FFF',
+		'doctype': 'DocType',
+		'istable': 1,
+		'module': 'Stock',
+		'name': '__common__',
+		'section_style': 'Simple',
+		'show_in_menu': 0,
+		'version': 9
+	},
+
+	# These values are common for all DocField
+	{
+		'doctype': 'DocField',
+		'name': '__common__',
+		'parent': 'Packing Slip Detail',
+		'parentfield': 'fields',
+		'parenttype': 'DocType'
+	},
+
+	# DocType, Packing Slip Detail
+	{
+		'doctype': 'DocType',
+		'name': 'Packing Slip Detail'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'item_code',
+		'fieldtype': 'Link',
+		'label': 'Item Code',
+		'options': 'Item',
+		'permlevel': 0,
+		'reqd': 1,
+		'width': '100px'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'item_name',
+		'fieldtype': 'Data',
+		'label': 'Item Name',
+		'permlevel': 1,
+		'width': '200px'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'qty',
+		'fieldtype': 'Currency',
+		'label': 'Quantity',
+		'permlevel': 0,
+		'reqd': 1,
+		'width': '100px'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'stock_uom',
+		'fieldtype': 'Data',
+		'label': 'UOM',
+		'permlevel': 1,
+		'width': '100px'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'net_weight',
+		'fieldtype': 'Float',
+		'label': 'Net Weight',
+		'permlevel': 1,
+		'width': '100px'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'weight_uom',
+		'fieldtype': 'Link',
+		'label': 'Weight UOM',
+		'options': 'UOM',
+		'permlevel': 1,
+		'width': '100px'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'page_break',
+		'fieldtype': 'Check',
+		'label': 'Page Break',
+		'permlevel': 0
+	}
+]
\ No newline at end of file
diff --git a/index.html b/index.html
index 94822ef..2793bd7 100644
--- a/index.html
+++ b/index.html
@@ -3,7 +3,7 @@
 	<meta charset="utf-8">
 	<title>ERPNext</title>
 	<meta name="author" content="">
-	<script type="text/javascript">window._version_number="131"
+	<script type="text/javascript">window._version_number="140"
 
 wn={}
 wn.provide=function(namespace){var nsl=namespace.split('.');var l=nsl.length;var parent=window;for(var i=0;i<l;i++){var n=nsl[i];if(!parent[n]){parent[n]={}}
diff --git a/version.num b/version.num
index b9c6c00..c2807f7 100644
--- a/version.num
+++ b/version.num
@@ -1 +1 @@
-131
\ No newline at end of file
+140
\ No newline at end of file