fixed conflict in setup control
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
index a44b756..c1b4663 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
@@ -204,9 +204,6 @@
 		if sql("select name from `tabFiscal Year` where year_start_date < %s", self.doc.year_start_date) and not self.doc.past_year:
 			msgprint("Please enter Past Year", raise_exception=1)
 
-		if not self.doc.is_fiscal_year_closed:
-			self.doc.is_fiscal_year_closed = 'No'
-
 
 	# on update
 	def on_update(self):
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 82314ca..eb869e5 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -40,18 +40,12 @@
 		self.fname = 'entries'
 
 
-	# Autoname
-	# ---------
 	def autoname(self):
 		self.doc.name = make_autoname(self.doc.naming_series+ '.#####')
 
 
-
-# ********************************* Trigger Functions ******************************
-
-	#Set retail related fields from pos settings
-	#-------------------------------------------------------------------------
 	def set_pos_fields(self):
+		"""Set retail related fields from pos settings"""
 		pos = webnotes.conn.sql("select * from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1)
 		if not pos:
 			pos = webnotes.conn.sql("select * from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % (self.doc.company), as_dict=1)
@@ -79,9 +73,8 @@
 			if self.doc.charge:		self.get_other_charges()
 
 
-	# Set default values related to pos for previously created sales invoice.
-	# -------------------------------------------------------------------------- 
 	def set_pos_item_values(self):
+		"""Set default values related to pos for previously created sales invoice."""
 		if cint(self.doc.is_pos) ==1:
 			dtl = webnotes.conn.sql("select income_account, warehouse, cost_center from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1)
 			if not dtl:
@@ -94,10 +87,8 @@
 				d.warehouse = item and item[0]['default_warehouse'] or dtl and dtl[0]['warehouse'] or d.warehouse
 
 
-			
-	# Get Account Head to which amount needs to be Debited based on Customer
-	# ----------------------------------------------------------------------
 	def get_customer_account(self):
+		"""Get Account Head to which amount needs to be Debited based on Customer"""
 		if not self.doc.company:
 			msgprint("Please select company first and re-select the customer after doing so", raise_exception=1)
 			
@@ -115,10 +106,8 @@
 		return acc_head and {'debit_to' : acc_head} or {}
 
 
-
-	# Set Due Date = Posting Date + Credit Days
-	# -----------------------------------------
 	def get_cust_and_due_date(self):
+		"""Set Due Date = Posting Date + Credit Days"""
 		credit_days = 0
 		if self.doc.debit_to:
 			credit_days = webnotes.conn.sql("select credit_days from `tabAccount` where name='%s' and docstatus != 2" % self.doc.debit_to)
@@ -134,9 +123,8 @@
 			self.doc.customer = webnotes.conn.get_value('Account',self.doc.debit_to,'master_name')
 
 
-	# Pull Details of Delivery Note or Sales Order Selected
-	# ------------------------------------------------------
 	def pull_details(self):
+		"""Pull Details of Delivery Note or Sales Order Selected"""
 		# Delivery Note
 		if self.doc.delivery_note_main:
 			self.validate_prev_docname('delivery note')
@@ -153,14 +141,14 @@
 		ret = self.get_debit_to()
 		self.doc.debit_to = ret.get('debit_to')
 					
-	# onload pull income account
-	# --------------------------
+					
 	def load_default_accounts(self):
 		"""
 			Loads default accounts from items, customer when called from mapper
 		"""
 		self.get_income_account('entries')
 		
+		
 	def get_income_account(self,doctype):		
 		for d in getlist(self.doclist, doctype):			
 			if d.item_code:
@@ -168,8 +156,7 @@
 				d.income_account = item and item[0]['default_income_account'] or ''
 				d.cost_center = item and item[0]['default_sales_cost_center'] or ''				
 
-	# Item Details
-	# -------------
+
 	def get_item_details(self, args=None):
 		import json
 		args = args and json.loads(args) or {}
@@ -215,61 +202,49 @@
 		return get_obj('Sales Common').get_barcode_details(barcode)
 
 
-	# Fetch ref rate from item master as per selected price list
 	def get_adj_percent(self, arg=''):
+		"""Fetch ref rate from item master as per selected price list"""
 		get_obj('Sales Common').get_adj_percent(self)
 
 
-	# Get tax rate if account type is tax
-	# ------------------------------------
 	def get_rate(self,arg):
+		"""Get tax rate if account type is tax"""
 		get_obj('Sales Common').get_rate(arg)
 		
 		
-	# Get Commission rate of Sales Partner
-	# -------------------------------------
 	def get_comm_rate(self, sales_partner):
+		"""Get Commission rate of Sales Partner"""
 		return get_obj('Sales Common').get_comm_rate(sales_partner, self)	
 	
- 
-	# GET TERMS & CONDITIONS
-	# -------------------------------------
+	
 	def get_tc_details(self):
 		return get_obj('Sales Common').get_tc_details(self)
 
-	# Load Default Charges
-	# ----------------------------------------------------------
+
 	def load_default_taxes(self):
 		self.doclist = get_obj('Sales Common').load_default_taxes(self)
 
-	# Get Sales Taxes and Charges Master Details
-	# --------------------------
+
 	def get_other_charges(self):
 		self.doclist = get_obj('Sales Common').get_other_charges(self)
 
-	# Get Advances
-	# -------------
+
 	def get_advances(self):
 		self.doclist = get_obj('GL Control').get_advances(self, self.doc.debit_to, 'Sales Invoice Advance', 'advance_adjustment_details', 'credit')
 
-	#pull project customer
-	#-------------------------
+	
 	def pull_project_customer(self):
 		res = webnotes.conn.sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name)
 		if res:
 			get_obj('DocType Mapper', 'Project-Sales Invoice').dt_map('Project', 'Sales Invoice', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Sales Invoice']]")
 
-# ********************************** Server Utility Functions ******************************
-	
-	# Get Company Abbr.
-	# ------------------
+
 	def get_company_abbr(self):
 		return webnotes.conn.sql("select abbr from tabCompany where name=%s", self.doc.company)[0][0]
 		
-	
-	# Check whether sales order / delivery note items already pulled
-	#----------------------------------------------------------------
+		
 	def validate_prev_docname(self,doctype):
+		"""Check whether sales order / delivery note items already pulled"""
 		for d in getlist(self.doclist, 'entries'): 
 			if doctype == 'delivery note' and self.doc.delivery_note_main == d.delivery_note:
 				msgprint(cstr(self.doc.delivery_note_main) + " delivery note details have already been pulled.")
@@ -279,7 +254,6 @@
 				raise Exception , "Validation Error. Sales order details have already been pulled."
 
 
-	#-----------------------------------------------------------------
 	def update_against_document_in_jv(self):
 		"""
 			Links invoice and advance voucher:
@@ -308,11 +282,8 @@
 			get_obj('GL Control').reconcile_against_document(lst)
 	
 	
-	# ------------------------------------------------------------------------
 	def validate_customer(self):
-		"""
-			Validate customer name with SO and DN
-		"""
+		"""	Validate customer name with SO and DN"""
 		for d in getlist(self.doclist,'entries'):
 			dt = d.delivery_note and 'Delivery Note' or d.sales_order and 'Sales Order' or ''
 			if dt:
@@ -322,9 +293,8 @@
 					msgprint("Customer %s does not match with customer of %s: %s." %(self.doc.customer, dt, dt_no), raise_exception=1)
 			
 
-	# Validates Debit To Account and Customer Matches
-	# ------------------------------------------------
-	def validate_debit_to_acc(self):
+	def validate_customer_account(self):
+		"""Validates Debit To Account and Customer Matches"""
 		if self.doc.customer and self.doc.debit_to and not cint(self.doc.is_pos):
 			acc_head = webnotes.conn.sql("select master_name from `tabAccount` where name = %s and docstatus != 2", self.doc.debit_to)
 			
@@ -334,11 +304,6 @@
 					and Master Name in account master." %(self.doc.debit_to, self.doc.customer,self.doc.company), raise_exception=1)
 
 
-	# Validate Debit To Account
-	# 1. Account Exists
-	# 2. Is a Debit Account
-	# 3. Is a PL Account
-	# ---------------------------
 	def validate_debit_acc(self):
 		acc = webnotes.conn.sql("select debit_or_credit, is_pl_account from tabAccount where name = '%s' and docstatus != 2" % self.doc.debit_to)
 		if not acc:
@@ -352,9 +317,8 @@
 			raise Exception
 
 
-	# Validate Fixed Asset Account and whether Income Account Entered Exists
-	# -----------------------------------------------------------------------
 	def validate_fixed_asset_account(self):
+		"""Validate Fixed Asset Account and whether Income Account Entered Exists"""
 		for d in getlist(self.doclist,'entries'):
 			item = webnotes.conn.sql("select name,is_asset_item,is_sales_item from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life >	now())"% d.item_code)
 			acc =	webnotes.conn.sql("select account_type from `tabAccount` where name = '%s' and docstatus != 2" % d.income_account)
@@ -366,22 +330,16 @@
 				raise Exception
 
 
-
-	# Set totals in words
-	#--------------------
 	def set_in_words(self):
 		dcc = TransactionBase().get_company_currency(self.doc.company)
 		self.doc.in_words = get_obj('Sales Common').get_total_in_words(dcc, self.doc.rounded_total)
 		self.doc.in_words_export = get_obj('Sales Common').get_total_in_words(self.doc.currency, self.doc.rounded_total_export)
 
-	# Clear Advances
-	# --------------
+
 	def clear_advances(self):
 		get_obj('GL Control').clear_advances(self, 'Sales Invoice Advance','advance_adjustment_details')
 
 
-	# set aging date
-	#-------------------
 	def set_aging_date(self):
 		if self.doc.is_opening != 'Yes':
 			self.doc.aging_date = self.doc.posting_date
@@ -390,20 +348,21 @@
 			raise Exception
 			
 
-	# Set against account for debit to account
-	#------------------------------------------
 	def set_against_income_account(self):
+		"""Set against account for debit to account"""
 		against_acc = []
 		for d in getlist(self.doclist, 'entries'):
 			if d.income_account not in against_acc:
 				against_acc.append(d.income_account)
 		self.doc.against_income_account = ','.join(against_acc)
 
+
 	def add_remarks(self):
 		if not self.doc.remarks: self.doc.remarks = 'No Remarks'
 
-	#check in manage account if sales order / delivery note required or not.
+
 	def so_dn_required(self):
+		"""check in manage account if sales order / delivery note required or not."""
 		dict = {'Sales Order':'so_required','Delivery Note':'dn_required'}
 		for i in dict:	
 			res = webnotes.conn.sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = '%s'"%dict[i])
@@ -413,9 +372,9 @@
 						msgprint("%s No. required against item %s"%(i,d.item_code))
 						raise Exception
 
-	#check for does customer belong to same project as entered..
-	#-------------------------------------------------------------------------------------------------
+
 	def validate_proj_cust(self):
+		"""check for does customer belong to same project as entered.."""
 		if self.doc.project_name and self.doc.customer:
 			res = webnotes.conn.sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer))
 			if not res:
@@ -431,20 +390,13 @@
 			raise Exception
 
 
-	# ********* UPDATE CURRENT STOCK *****************************
-	def update_current_stock(self):
-		for d in getlist(self.doclist, 'entries'):
-			bin = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
-			d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
-
 	def validate_item_code(self):
 		for d in getlist(self.doclist, 'entries'):
 			if not d.item_code:
 				msgprint("Please enter Item Code at line no : %s to update stock for POS or remove check from Update Stock in Basic Info Tab." % (d.idx))
 				raise Exception
 
-	# Validate Write Off Account
-	# -------------------------------
+
 	def validate_write_off_account(self):
 		if flt(self.doc.write_off_amount) and not self.doc.write_off_account:
 			msgprint("Please enter Write Off Account", raise_exception=1)
@@ -457,12 +409,22 @@
 					and parent = %s""", (self.doc.amended_from,	self.doc.c_form_no))
 
 			webnotes.conn.set(self.doc, 'c_form_no', '')
+			
+
+	def update_current_stock(self):
+		for d in getlist(self.doclist, 'entries'):
+			if d.item_code and d.warehouse:
+				bin = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
+				d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
+
+		for d in getlist(self.doclist, 'packing_details'):
+			bin = sql("select actual_qty, projected_qty from `tabBin` where item_code =	%s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
+			d.actual_qty = bin and flt(bin[0]['actual_qty']) or 0
+			d.projected_qty = bin and flt(bin[0]['projected_qty']) or 0
 	 
-	# VALIDATE
-	# ====================================================================================
+	
 	def validate(self):
 		self.so_dn_required()
-		#self.dn_required()
 		self.validate_proj_cust()
 		sales_com_obj = get_obj('Sales Common')
 		sales_com_obj.check_stop_sales_order(self)
@@ -472,7 +434,7 @@
 		sales_com_obj.get_allocated_sum(self)	# this is to verify that the allocated % of sales persons is 100%
 		sales_com_obj.validate_fiscal_year(self.doc.fiscal_year,self.doc.posting_date,'Posting Date')
 		self.validate_customer()
-		self.validate_debit_to_acc()
+		self.validate_customer_account()
 		self.validate_debit_acc()
 		self.validate_fixed_asset_account()
 		self.add_remarks()
@@ -480,7 +442,9 @@
 			self.validate_pos()
 			self.validate_write_off_account()
 			if cint(self.doc.update_stock):
-				get_obj('Stock Ledger').validate_serial_no(self, 'entries')
+				sl = get_obj('Stock Ledger')
+				sl.validate_serial_no(self, 'entries')
+				sl.validate_serial_no(self, 'packing_details')
 				self.validate_item_code()
 				self.update_current_stock()
 		self.set_in_words()
@@ -488,14 +452,62 @@
 			self.doc.is_opening = 'No'
 		self.set_aging_date()
 		self.clear_advances()
-		# Set against account
 		self.set_against_income_account()
 		self.validate_c_form()
 
+
+	def get_warehouse(self):
+		w = webnotes.conn.sql("select warehouse from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company))
+		w = w and w[0][0] or ''
+		if not w:
+			ps = webnotes.conn.sql("select name, warehouse from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % self.doc.company)
+			if not ps:
+				msgprint("To make POS entry, please create POS Setting from Accounts --> POS Setting page and refresh the system.")
+				raise Exception
+			elif not ps[0][1]:
+				msgprint("Please enter warehouse in POS Setting")
+			else:
+				w = ps[0][1]
+		return w
+
+	
+	def make_packing_list(self):
+		get_obj('Sales Common').make_packing_list(self,'entries')
+		sl = get_obj('Stock Ledger')
+		sl.scrub_serial_nos(self)
+		sl.scrub_serial_nos(self, 'packing_details')
+
+
+	def on_update(self):
+		# Set default warehouse from pos setting
+		if cint(self.doc.is_pos) == 1:
+			if cint(self.doc.update_stock) == 1:
+				w = self.get_warehouse()
+				if w:
+					for d in getlist(self.doclist, 'entries'):
+						if not d.warehouse:
+							d.warehouse = cstr(w)
+							
+				self.make_packing_list()
+			else:
+				self.doclist = self.doc.clear_table(self.doclist, 'packing_details')
+
+			if flt(self.doc.paid_amount) == 0:
+				if self.doc.cash_bank_account: 
+					webnotes.conn.set(self.doc, 'paid_amount', 
+						(flt(self.doc.grand_total) - flt(self.doc.write_off_amount)))
+				else:
+					# show message that the amount is not paid
+					webnotes.conn.set(self.doc,'paid_amount',0)
+					webnotes.msgprint("Note: Payment Entry will not be created since 'Cash/Bank Account' was not specified.")
+
+		else:
+			self.doclist = self.doc.clear_table(self.doclist, 'packing_details')
+			webnotes.conn.set(self.doc,'paid_amount',0)
+
+		webnotes.conn.set(self.doc,'outstanding_amount',flt(self.doc.grand_total) - flt(self.doc.total_advance) - flt(self.doc.paid_amount) - flt(self.doc.write_off_amount))
+
 		
-# *************************************************** ON SUBMIT **********************************************
-	# Check Ref Document's docstatus
-	# -------------------------------
 	def check_prev_docstatus(self):
 		for d in getlist(self.doclist,'entries'):
 			if d.sales_order:
@@ -511,56 +523,45 @@
 					raise Exception , "Validation Error."
 
 
-	#Set Actual Qty based on item code and warehouse
-	#------------------------------------------------------
-	def set_actual_qty(self):
-		for d in getlist(self.doclist, 'entries'):
-			if d.item_code and d.warehouse:
-				actual_qty = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code, d.warehouse))
-				d.actual_qty = actual_qty and flt(actual_qty[0][0]) or 0
-
-
-
-	# ********************** Make Stock Entry ************************************
 	def make_sl_entry(self, d, wh, qty, in_value, update_stock):
-		st_uom = webnotes.conn.sql("select stock_uom from `tabItem` where name = '%s'"%d.item_code)
+		st_uom = webnotes.conn.sql("select stock_uom from `tabItem` where name = '%s'"%d['item_code'])
 		self.values.append({
-			'item_code'					 : d.item_code,
+			'item_code'					 : d['item_code'],
 			'warehouse'					 : wh,
 			'transaction_date'			: getdate(self.doc.modified).strftime('%Y-%m-%d'),
 			'posting_date'				: self.doc.posting_date,
 			'posting_time'				: self.doc.posting_time,
 			'voucher_type'				: 'Sales Invoice',
 			'voucher_no'					: cstr(self.doc.name),
-			'voucher_detail_no'	 : cstr(d.name), 
+			'voucher_detail_no'	 : cstr(d['name']), 
 			'actual_qty'					: qty, 
 			'stock_uom'					 : st_uom and st_uom[0][0] or '',
 			'incoming_rate'			 : in_value,
 			'company'						 : self.doc.company,
 			'fiscal_year'				 : self.doc.fiscal_year,
 			'is_cancelled'				: (update_stock==1) and 'No' or 'Yes',
-			'batch_no'						: cstr(d.batch_no),
-			'serial_no'					 : d.serial_no
-		})		
+			'batch_no'						: cstr(d['batch_no']),
+			'serial_no'					 : d['serial_no']
+		})	
 			
 
-	# UPDATE STOCK LEDGER
-	# ---------------------------------------------------------------------------
-	def update_stock_ledger(self, update_stock, clear = 0):
+	def update_stock_ledger(self, update_stock):
 		self.values = []
-		for d in getlist(self.doclist, 'entries'):
-			stock_item = webnotes.conn.sql("SELECT is_stock_item, is_sample_item FROM tabItem where name = '%s'"%(d.item_code), as_dict = 1) # stock ledger will be updated only if it is a stock item
+		items = get_obj('Sales Common').get_item_list(self)
+		for d in items:
+			stock_item = webnotes.conn.sql("SELECT is_stock_item, is_sample_item \
+				FROM tabItem where name = '%s'"%(d['item_code']), as_dict = 1)
 			if stock_item[0]['is_stock_item'] == "Yes":
+				if not d['warehouse']:
+					msgprint("Message: Please enter Warehouse for item %s as it is stock item." \
+						% d['item_code'], raise_exception=1)
+
 				# Reduce actual qty from warehouse
-				self.make_sl_entry( d, d.warehouse, - flt(d.qty) , 0, update_stock)
-		get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values, self.doc.amended_from and 'Yes' or 'No')
-
-
-	#-------------------POS Stock Updatation Part----------------------------------------------
-	def pos_update_stock(self):
-		self.update_stock_ledger(update_stock = 1)
+				self.make_sl_entry( d, d['warehouse'], - flt(d['qty']) , 0, update_stock)
+				
+		get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
 	
-	# ********** Get Actual Qty of item in warehouse selected *************
+
 	def get_actual_qty(self,args):
 		args = eval(args)
 		actual_qty = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1)
@@ -569,23 +570,39 @@
 		}
 		return ret
 
-	# Make GL Entries
-	# -------------------------
+
 	def make_gl_entries(self, is_cancel=0):
 		mapper = self.doc.is_pos and self.doc.write_off_account and 'POS with write off' or self.doc.is_pos and not self.doc.write_off_account and 'POS' or ''
 		update_outstanding = self.doc.is_pos and self.doc.write_off_account and 'No' or 'Yes'
 		get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist,cancel = is_cancel, use_mapper = mapper, update_outstanding = update_outstanding, merge_entries = cint(self.doc.is_pos) != 1 and 1 or 0)
 		
 
-	# On Submit
-	# ---------
+	def update_c_form(self):
+		"""Update amended id in C-form"""
+		if self.doc.c_form_no and self.doc.amended_from:
+			webnotes.conn.sql("""update `tabC-Form Invoice Detail` set invoice_no = %s,
+					invoice_date = %s, territory = %s, net_total = %s,
+					grand_total = %s where invoice_no = %s and parent = %s""", (self.doc.name, self.doc.amended_from, self.doc.c_form_no))
+
+
+	def check_next_docstatus(self):
+		submit_jv = webnotes.conn.sql("select t1.name from `tabJournal Voucher` t1,`tabJournal Voucher Detail` t2 where t1.name = t2.parent and t2.against_invoice = '%s' and t1.docstatus = 1" % (self.doc.name))
+		if submit_jv:
+			msgprint("Journal Voucher : " + cstr(submit_jv[0][0]) + " has been created against " + cstr(self.doc.doctype) + ". So " + cstr(self.doc.doctype) + " cannot be Cancelled.")
+			raise Exception, "Validation Error."
+
+
 	def on_submit(self):
 		if cint(self.doc.is_pos) == 1:
 			if cint(self.doc.update_stock) == 1:
 				sl_obj = get_obj("Stock Ledger")
 				sl_obj.validate_serial_no_warehouse(self, 'entries')
+				sl_obj.validate_serial_no_warehouse(self, 'packing_details')
+				
 				sl_obj.update_serial_record(self, 'entries', is_submit = 1, is_incoming = 0)
-				self.pos_update_stock()
+				sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
+				
+				self.update_stock_ledger(update_stock=1)
 		else:
 			self.check_prev_docstatus()
 			get_obj("Sales Common").update_prevdoc_detail(1,self)
@@ -603,31 +620,13 @@
 		self.update_c_form()
 
 
-	def update_c_form(self):
-		"""Update amended id in C-form"""
-		if self.doc.c_form_no and self.doc.amended_from:
-			webnotes.conn.sql("""update `tabC-Form Invoice Detail` set invoice_no = %s,
-					invoice_date = %s, territory = %s, net_total = %s,
-					grand_total = %s where invoice_no = %s and parent = %s""", (self.doc.name, self.doc.amended_from, self.doc.c_form_no))
-	
-
-			
-# *************************************************** ON CANCEL **********************************************
-	# Check Next Document's docstatus
-	# --------------------------------
-	def check_next_docstatus(self):
-		submit_jv = webnotes.conn.sql("select t1.name from `tabJournal Voucher` t1,`tabJournal Voucher Detail` t2 where t1.name = t2.parent and t2.against_invoice = '%s' and t1.docstatus = 1" % (self.doc.name))
-		if submit_jv:
-			msgprint("Journal Voucher : " + cstr(submit_jv[0][0]) + " has been created against " + cstr(self.doc.doctype) + ". So " + cstr(self.doc.doctype) + " cannot be Cancelled.")
-			raise Exception, "Validation Error."
-
-
-	# On Cancel
-	# ----------
 	def on_cancel(self):
 		if cint(self.doc.is_pos) == 1:
 			if cint(self.doc.update_stock) == 1:
-				get_obj('Stock Ledger').update_serial_record(self, 'entries', is_submit = 0, is_incoming = 0)
+				sl = get_obj('Stock Ledger')
+				sl.update_serial_record(self, 'entries', is_submit = 0, is_incoming = 0)
+				sl.update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
+				
 				self.update_stock_ledger(update_stock = -1)
 		else:
 			sales_com_obj = get_obj(dt = 'Sales Common')
@@ -636,51 +635,6 @@
 			sales_com_obj.update_prevdoc_detail(0,self)
 
 		self.make_gl_entries(is_cancel=1)
-
-	# Get Warehouse
-	def get_warehouse(self):
-		w = webnotes.conn.sql("select warehouse from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company))
-		w = w and w[0][0] or ''
-		if not w:
-			ps = webnotes.conn.sql("select name, warehouse from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % self.doc.company)
-			if not ps:
-				msgprint("To make POS entry, please create POS Setting from Setup --> Accounts --> POS Setting and refresh the system.")
-				raise Exception
-			elif not ps[0][1]:
-				msgprint("Please enter warehouse in POS Setting")
-			else:
-				w = ps[0][1]
-		return w
-
-	# on update
-	def on_update(self):
-		# Set default warehouse from pos setting
-		#----------------------------------------
-		if cint(self.doc.is_pos) == 1:
-			self.set_actual_qty()
-			w = self.get_warehouse()
-			if w:
-				for d in getlist(self.doclist, 'entries'):
-					if not d.warehouse:
-						d.warehouse = cstr(w)
-
-			if flt(self.doc.paid_amount) == 0:
-				if self.doc.cash_bank_account: 
-					webnotes.conn.set(self.doc, 'paid_amount', 
-						(flt(self.doc.grand_total) - flt(self.doc.write_off_amount)))
-				else:
-					# show message that the amount is not paid
-					webnotes.conn.set(self.doc,'paid_amount',0)
-					webnotes.msgprint("Note: Payment Entry not created since 'Cash/Bank Account' was not specified.")
-
-		else:
-			webnotes.conn.set(self.doc,'paid_amount',0)
-
-		webnotes.conn.set(self.doc,'outstanding_amount',flt(self.doc.grand_total) - flt(self.doc.total_advance) - flt(self.doc.paid_amount) - flt(self.doc.write_off_amount))
-
-	#-------------------------------------------------------------------------------------
-	def on_update_after_submit(self):
-		self.convert_into_recurring()
 		
 
 	def convert_into_recurring(self):
@@ -717,3 +671,7 @@
 		next_date = next_date.strftime("%Y-%m-%d")
 
 		webnotes.conn.set(self.doc, 'next_date', next_date)
+
+
+	def on_update_after_submit(self):
+		self.convert_into_recurring()
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt b/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt
index 969a7dc..a2b341f 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt
@@ -3,9 +3,9 @@
 
 	# These values are common in all dictionaries
 	{
-		'creation': '2012-06-11 12:09:54',
+		'creation': '2012-07-05 11:04:09',
 		'docstatus': 0,
-		'modified': '2012-06-17 21:37:40',
+		'modified': '2012-07-11 12:19:49',
 		'modified_by': u'Administrator',
 		'owner': u'Administrator'
 	},
@@ -353,6 +353,16 @@
 	# DocField
 	{
 		'doctype': u'DocField',
+		'fieldname': u'sales_bom_help',
+		'fieldtype': u'HTML',
+		'label': u'Sales BOM Help',
+		'permlevel': 0,
+		'print_hide': 1
+	},
+
+	# DocField
+	{
+		'doctype': u'DocField',
 		'fieldname': u'section_break0',
 		'fieldtype': u'Section Break',
 		'options': u'Simple',
@@ -1346,6 +1356,27 @@
 	# DocField
 	{
 		'doctype': u'DocField',
+		'fieldname': u'packing_list',
+		'fieldtype': u'Section Break',
+		'label': u'Packing List',
+		'permlevel': 0,
+		'print_hide': 1
+	},
+
+	# DocField
+	{
+		'doctype': u'DocField',
+		'fieldname': u'packing_details',
+		'fieldtype': u'Table',
+		'label': u'Packing Details',
+		'options': u'Delivery Note Packing Item',
+		'permlevel': 0,
+		'print_hide': 1
+	},
+
+	# DocField
+	{
+		'doctype': u'DocField',
 		'fieldname': u'sales_team_section_break',
 		'fieldtype': u'Section Break',
 		'label': u'Sales Team',
diff --git a/erpnext/hr/doctype/salary_manager/salary_manager.py b/erpnext/hr/doctype/salary_manager/salary_manager.py
index 111366b..660890a 100644
--- a/erpnext/hr/doctype/salary_manager/salary_manager.py
+++ b/erpnext/hr/doctype/salary_manager/salary_manager.py
@@ -24,7 +24,6 @@
 from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
 from webnotes import session, form, is_testing, msgprint, errprint
 
-set = webnotes.conn.set
 sql = webnotes.conn.sql
 get_value = webnotes.conn.get_value
 in_transaction = webnotes.conn.in_transaction
@@ -84,7 +83,7 @@
 		emp_list = self.get_emp_list()
 		log = ""
 		if emp_list:
-			log = "<table><tr><td colspan = 2>Following Salary Slip has been created: </td></tr><tr><td><u>SAL SLIP ID</u></td><td><u>EMPLOYEE NAME</u></td></tr>"
+			log = "<table width=100%><tr><td colspan = 2>Following Salary Slip has been created: </td></tr><tr><td width=50%><u>SAL SLIP ID</u></td><td width=50%><u>EMPLOYEE NAME</u></td></tr>"
 		else:
 			log = "<table><tr><td colspan = 2>No employee found for the above selected criteria</td></tr>"
 			
@@ -111,7 +110,7 @@
 				for d in getlist(ss_obj.doclist, 'deduction_details'):
 					d.save()
 					
-				log += '<tr><td>' + ss.name + '</td><td>' + ss_obj.doc.employee_name + '</td></tr>'
+				log += '<tr><td width=50%>' + ss.name + '</td><td width=50%>' + ss_obj.doc.employee_name + '</td></tr>'
 		log += '</table>'
 		return log	
 				
@@ -132,28 +131,49 @@
 		"""
 			Submit all salary slips based on selected criteria
 		"""
-		ss_list = self.get_sal_slip_list()
-		log = ""
-		if ss_list:
-			log = 	"""<table>
-						<tr>
-							<td colspan = 2>Following Salary Slip has been submitted: </td>
-						</tr>
-						<tr>
-							<td><u>SAL SLIP ID</u></td>
-							<td><u>EMPLOYEE NAME</u></td>
-						</tr>
-					"""
-		else:
-			log = "<table><tr><td colspan = 2>No salary slip found to submit for the above selected criteria</td></tr>"
-			
+		ss_list = self.get_sal_slip_list()		
+		not_submitted_ss = []
 		for ss in ss_list:
 			ss_obj = get_obj("Salary Slip",ss[0],with_children=1)
-			set(ss_obj.doc, 'docstatus', 1)
-			ss_obj.on_submit()
+			try:
+				webnotes.conn.set(ss_obj.doc, 'email_check', cint(self.doc.send_mail))
+				if cint(self.doc.send_email) == 1:
+					ss_obj.send_mail_funct()
+					
+				webnotes.conn.set(ss_obj.doc, 'docstatus', 1)
+			except Exception,e:
+				not_submitted_ss.append(ss[0])
+				msgprint(e)
+				continue
+				
+		return self.create_log(ss_list, not_submitted_ss)
+		
+		
+	def create_log(self, all_ss, not_submitted_ss):
+		log = ''
+		if not all_ss:
+			log = "No salary slip found to submit for the above selected criteria"
+		else:
+			all_ss = [d[0] for d in all_ss]
 			
-			log += '<tr><td>' + ss[0] + '</td><td>' + ss_obj.doc.employee_name + '</td></tr>'
-		log += '</table>'	
+		submitted_ss = list(set(all_ss) - set(not_submitted_ss))		
+		if submitted_ss:
+			mail_sent_msg = self.doc.send_email and " (Mail has been sent to the employee)" or ""
+			log = """
+			<b>Submitted Salary Slips%s:</b>\
+			<br><br> %s <br><br>
+			""" % (mail_sent_msg, '<br>'.join(submitted_ss))
+			
+		if not_submitted_ss:
+			log += """
+				<b>Not Submitted Salary Slips: </b>\
+				<br><br> %s <br><br> \
+				Reason: <br>\
+				May be company email id specified in employee master is not valid. <br> \
+				Please mention correct email id in employee master or if you don't want to \
+				send mail, uncheck 'Send Email' checkbox. <br>\
+				Then try to submit Salary Slip again.
+			"""% ('<br>'.join(not_submitted_ss))
 		return log	
 			
 			
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 3439fc8..3187eb4 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -281,4 +281,4 @@
 			</table></div>'''%(cstr(letter_head[0][0]),cstr(self.doc.employee), cstr(self.doc.employee_name), cstr(self.doc.month), cstr(self.doc.fiscal_year), cstr(self.doc.department), cstr(self.doc.branch), cstr(self.doc.designation), cstr(self.doc.grade), cstr(self.doc.bank_account_no), cstr(self.doc.bank_name), cstr(self.doc.arrear_amount), cstr(self.doc.payment_days), earn_table, ded_table, cstr(flt(self.doc.gross_pay)), cstr(flt(self.doc.total_deduction)), cstr(flt(self.doc.net_pay)), cstr(self.doc.total_in_words))
 			sendmail([receiver], subject=subj, msg = msg)
 		else:
-			msgprint("Company Email ID not found.")
+			msgprint("Company Email ID not found, hence mail not sent")
diff --git a/erpnext/hr/doctype/salary_structure/listview.js b/erpnext/hr/doctype/salary_structure/listview.js
new file mode 100644
index 0000000..77259b5
--- /dev/null
+++ b/erpnext/hr/doctype/salary_structure/listview.js
@@ -0,0 +1,47 @@
+// render
+wn.doclistviews['Salary Structure'] = wn.views.ListView.extend({
+	init: function(d) {
+		this._super(d)
+		this.fields = this.fields.concat([
+			"`tabSalary Structure`.employee_name",
+			"`tabSalary Structure`.designation",
+			"`tabSalary Structure`.branch",
+			"`tabSalary Structure`.net_pay",
+			"`tabSalary Structure`.from_date",
+			"`tabSalary Structure`.to_date",
+			"`tabSalary Structure`.company"
+		]);
+		this.stats = this.stats.concat(['company']);
+	},
+
+	prepare_data: function(data) {
+		this._super(data);
+		var concat_list = [];
+		data.designation && concat_list.push(data.designation);
+		data.branch && concat_list.push(data.branch);
+		data.description = concat_list.join(", ");
+		data.period = data.from_date + (data.to_date && ' to ' + data.to_date);
+	},
+	
+	columns: [
+		{width: '2%', content: 'check'},
+		{width: '2%', content: 'docstatus'},
+		{width: '13%', content: 'name'},
+		{width: '18%', content: 'employee_name'},
+		{width: '24%', content: 'description+tags', css: {'color': '#aaa'}},
+		{width: '26%', content:'period', css: {'text-align': 'right', 'color':'#aaa'}},
+		{
+			width: '15%',
+			content: function(parent, data) {
+				$(parent).html(
+					(
+						data.company
+						? wn.boot.company[data.company].default_currency
+						: sys_defaults.currency
+					)
+					+ ' ' + fmt_money(data.net_pay));
+			},
+			css: {'text-align': 'right'},
+		},
+]
+});
\ No newline at end of file
diff --git a/erpnext/production/doctype/bom/bom.py b/erpnext/production/doctype/bom/bom.py
index 81297b4..bc166ce 100644
--- a/erpnext/production/doctype/bom/bom.py
+++ b/erpnext/production/doctype/bom/bom.py
@@ -106,7 +106,6 @@
 		return ret_item
 
 
-
 	def get_rm_rate(self, arg):
 		"""	Get raw material rate as per selected method, if bom exists takes bom cost """
 
@@ -293,7 +292,6 @@
 		self.validate_main_item()
 		self.validate_operations()
 		self.validate_materials()
-		self.validate_operations()
 
 
 
@@ -353,8 +351,6 @@
 			})
 
 
-
-
 	# Get Current Flat BOM Items
 	# -----------------------------
 	def get_current_flat_bom_items(self):
diff --git a/erpnext/selling/doctype/sales_common/sales_common.js b/erpnext/selling/doctype/sales_common/sales_common.js
index 00618e9..952a55f 100644
--- a/erpnext/selling/doctype/sales_common/sales_common.js
+++ b/erpnext/selling/doctype/sales_common/sales_common.js
@@ -127,10 +127,34 @@
 	cur_frm.cscript.base_currency = base_curr;
 	set_dynamic_label_par(doc, cdt, cdn, base_curr);
 	set_dynamic_label_child(doc, cdt, cdn, base_curr);
+	set_sales_bom_help(doc);
 
 	if (callback) callback(doc, cdt, cdn);
 }
 
+// Help for Sales BOM items
+var set_sales_bom_help = function(doc) {
+	if (getchildren('Delivery Note Packing Item', doc.name, 'packing_details').length) {
+		$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(true);
+		
+		if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
+			help_msg = "<div class='help-box'> \
+				For 'Sales BOM' items, warehouse, serial no and batch no \
+				will be considered from the 'Packing List' table. \
+				If warehouse and batch no are same for all packing items for any 'Sales BOM' item, \
+				those values can be entered in the main item table, values will be copied to 'Packing List' table. \
+			</div>";
+			get_field(doc.doctype, 'sales_bom_help', doc.name).options = help_msg;
+		} 
+	} else {
+		$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(false);
+		if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
+			get_field(doc.doctype, 'sales_bom_help', doc.name).options = '';
+		}
+	}
+	refresh_field('sales_bom_help');
+}
+
 
 // hide / unhide price list currency based on availability of price list in customer's currency
 //---------------------------------------------------------------------------------------------------
diff --git a/erpnext/selling/doctype/sales_common/sales_common.py b/erpnext/selling/doctype/sales_common/sales_common.py
index 74963fb..a658209 100644
--- a/erpnext/selling/doctype/sales_common/sales_common.py
+++ b/erpnext/selling/doctype/sales_common/sales_common.py
@@ -385,7 +385,7 @@
 		return ret
 
 
-	def get_item_list(self, obj, is_stopped):
+	def get_item_list(self, obj, is_stopped=0):
 		"""get item list"""
 		il = []
 		for d in getlist(obj.doclist,obj.fname):
@@ -394,7 +394,7 @@
 			if is_stopped:
 				qty = flt(d.qty) > flt(d.delivered_qty) and flt(flt(d.qty) - flt(d.delivered_qty)) or 0
 				
-			if d.prevdoc_doctype == 'Sales Order':			
+			if d.prevdoc_doctype == 'Sales Order':
 				# used in delivery note to reduce reserved_qty 
 				# Eg.: if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12.
 				# But in this case reserved qty should only be reduced by 10 and not 12.
@@ -413,7 +413,7 @@
 					if p.parent_detail_docname == d.name:
 						# the packing details table's qty is already multiplied with parent's qty
 						il.append({
-							'warehouse': d.warehouse,
+							'warehouse': p.warehouse,
 							'reserved_warehouse': reserved_wh,
 							'item_code': p.item_code,
 							'qty': flt(p.qty),
@@ -496,23 +496,21 @@
 		pi.qty = flt(qty)
 		pi.actual_qty = bin and flt(bin['actual_qty']) or 0
 		pi.projected_qty = bin and flt(bin['projected_qty']) or 0
-		pi.warehouse = warehouse
 		pi.prevdoc_doctype = line.prevdoc_doctype
-		if packing_item_code == line.item_code:
-			pi.serial_no = cstr(line.serial_no)
+		if not pi.warehouse:
+			pi.warehouse = warehouse
+		if not pi.batch_no:
 			pi.batch_no = cstr(line.batch_no)
 		pi.idx = self.packing_list_idx
 		
-		# has to be saved, since this function is called on_update of delivery note
+		# saved, since this function is called on_update of delivery note
 		pi.save()
 		
 		self.packing_list_idx += 1
 
 
-	# ------------------
-	# make packing list from sales bom if exists or directly copy item with balance
-	# ------------------ 
 	def make_packing_list(self, obj, fname):
+		"""make packing list for sales bom item"""
 		self.packing_list_idx = 0
 		parent_items = []
 		for d in getlist(obj.doclist, fname):
@@ -520,10 +518,9 @@
 			if self.has_sales_bom(d.item_code):
 				for i in self.get_sales_bom_items(d.item_code):
 					self.update_packing_list_item(obj, i['item_code'], flt(i['qty'])*flt(d.qty), warehouse, d)
-			else:
-				self.update_packing_list_item(obj, d.item_code, d.qty, warehouse, d)
-			if [d.item_code, d.name] not in parent_items:
-				parent_items.append([d.item_code, d.name])
+
+				if [d.item_code, d.name] not in parent_items:
+					parent_items.append([d.item_code, d.name])
 				
 		self.cleanup_packing_list(obj, parent_items)
 		
diff --git a/erpnext/setup/doctype/setup_control/setup_control.py b/erpnext/setup/doctype/setup_control/setup_control.py
index 3634516..ee1cb7e 100644
--- a/erpnext/setup/doctype/setup_control/setup_control.py
+++ b/erpnext/setup/doctype/setup_control/setup_control.py
@@ -49,8 +49,7 @@
 		master_dict = {'Fiscal Year':{
 			'year': curr_fiscal_year,
 			'year_start_date': fy_start_date,
-			'company': args.get('company_name'),
-			'is_fiscal_year_closed': 'No'}}
+			'company': args.get('company_name')}}
 		self.create_records(master_dict)
 		
 		# Company
diff --git a/erpnext/startup/js/complete_setup.js b/erpnext/startup/js/complete_setup.js
index 9180dfa..ff51282 100644
--- a/erpnext/startup/js/complete_setup.js
+++ b/erpnext/startup/js/complete_setup.js
@@ -138,7 +138,7 @@
 		'Dominican Republic', 'East Timor', 'Ecuador', 'Egypt', 'El Salvador', 
 		'Equatorial Guinea', 'Eritrea', 'Estonia', 'Ethiopia', 'Federated States of Micronesia', 
 		'Fiji', 'Finland', 'France', 'Gabon', 'Georgia', 'Germany', 'Ghana', 'Greece', 
-		'Grenada', 'Guatemala', 'Guinea', 'Guinea-Bissau', 'Guyana', 'Haiti', 'Honduras', 
+		'Grenada', 'Guatemala', 'Guinea', 'Guinea-Bissau', 'Guyana', 'Haiti', 'Honduras', 'Hong Kong'
 		'Hungary', 'Iceland', 'India', 'Indonesia', 'Iran', 'Iraq', 'Israel', 'Italy', 
 		'Jamaica', 'Japan', 'Jordan', 'Kazakhstan', 'Kenya', 'Kingdom of the Netherlands', 
 		'Kiribati', 'Kuwait', 'Kyrgyzstan', 'Laos', 'Latvia', 'Lebanon', 'Lesotho', 'Liberia', 
@@ -147,7 +147,7 @@
 		'Mexico', 'Moldova', 'Monaco', 'Mongolia', 'Montenegro', 'Morocco', 'Mozambique', 
 		'Myanmar', 'Namibia', 'Nauru', 'Nepal', 'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 
 		'North Korea', 'Norway', 'Oman', 'Pakistan', 'Palau', 'Panama', 'Papua New Guinea', 
-		'Paraguay', "People's Republic of China", 'Peru', 'Philippines', 'Poland', 'Portugal', 
+		'Paraguay', "China", 'Peru', 'Philippines', 'Poland', 'Portugal', 
 		'Qatar', 'Republic of Ireland', 'Republic of the Congo', 'Romania', 'Russia', 'Rwanda', 
 		'Saint Kitts and Nevis', 'Saint Lucia', 'Saint Vincent and the Grenadines', 'Samoa', 
 		'San Marino', 'Saudi Arabia', 'Senegal', 'Serbia', 'Seychelles', 'Sierra Leone', 
@@ -252,6 +252,11 @@
 		'Cape Verde': ['Atlantic/Cape_Verde'],
 		'Central African Republic': ['Africa/Bangui'],
 		'Chad': ['Africa/Ndjamena'],
+		'China': ['Asia/Shanghai',
+		                               'Asia/Harbin',
+		                               'Asia/Chongqing',
+		                               'Asia/Urumqi',
+		                               'Asia/Kashgar'],
 		'Chile': ['America/Santiago', 'Pacific/Easter'],
 		'Colombia': ['America/Bogota'],
 		'Comoros': ['Indian/Comoro'],
@@ -292,6 +297,7 @@
 		'Guyana': ['America/Guyana'],
 		'Haiti': ['America/Guatemala'],
 		'Honduras': ['America/Tegucigalpa'],
+		'Hong Kong': ['Asia/Hong_Kong'],
 		'Hungary': ['Europe/Budapest'],
 		'Iceland': ['Atlantic/Reykjavik'],
 		'India': ['Asia/Calcutta'],
@@ -365,11 +371,6 @@
 		'Panama': ['America/Panama'],
 		'Papua New Guinea': ['Pacific/Port_Moresby'],
 		'Paraguay': ['America/Asuncion'],
-		"People's Republic of China": ['Asia/Shanghai',
-		                               'Asia/Harbin',
-		                               'Asia/Chongqing',
-		                               'Asia/Urumqi',
-		                               'Asia/Kashgar'],
 		'Peru': ['America/Lima'],
 		'Philippines': ['Asia/Manila'],
 		'Poland': ['Europe/Warsaw'],
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index ad95cf1..490051b 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -197,51 +197,6 @@
 		get_obj('DocType Mapper', 'Sales Order-Delivery Note', with_children = 1).validate_reference_value(self, self.doc.name)
 
 
-	def validate_prevdoc_details(self):
-		for d in getlist(self.doclist,'delivery_note_details'):
-			prevdoc = d.prevdoc_doctype
-			prevdoc_docname = d.prevdoc_docname
-
-			if prevdoc_docname and prevdoc:
-				# Validates Transaction Date of DN and previous doc (i.e. SO , PO, PR)
-				trans_date = sql("select posting_date from `tab%s` where name = '%s'" %(prevdoc,prevdoc_docname))[0][0]
-				if trans_date and getdate(self.doc.posting_date) < (trans_date):
-					msgprint("Your Posting Date cannot be before "+cstr(prevdoc)+" Date.")
-					raise Exception
-				# Validates DN and previous doc details
-				get_name = sql("select name from `tab%s` where name = '%s'" % (prevdoc, prevdoc_docname))
-				name = get_name and get_name[0][0] or ''
-				if name:	#check for incorrect docname
-					if prevdoc == 'Sales Order':
-						dt = sql("select company, docstatus, customer, currency, sales_partner from `tab%s` where name = '%s'" % (prevdoc, name))
-						cust_name = dt and dt[0][2] or ''
-						if cust_name != self.doc.customer:
-							msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " customer :" + cstr(cust_name) + " does not match with customer : " + cstr(self.doc.customer) + " of current document.")
-							raise Exception, "Validation Error. "
-						sal_partner = dt and dt[0][4] or ''
-						if sal_partner != self.doc.sales_partner:
-							msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " sales partner name :" + cstr(sal_partner) + " does not match with sales partner name : " + cstr(self.doc.sales_partner_name) + " of current document.")
-							raise Exception, "Validation Error. "
-					else:
-						dt = sql("select company, docstatus, supplier, currency from `tab%s` where name = '%s'" % (prevdoc, name))
-						supp_name = dt and dt[0][2] or ''
-						company_name = dt and dt[0][0] or ''
-						docstatus = dt and dt[0][1] or 0
-						currency = dt and dt[0][3] or ''
-						if (currency != self.doc.currency):
-							msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " currency : "+ cstr(currency) + "does not match with Currency: " + cstr(self.doc.currency) + "of current document")
-							raise Exception, "Validation Error."
-						if (company_name != self.doc.company):
-							msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " does not belong to the Company: " + cstr(self.doc.company_name))
-							raise Exception, "Validation Error."
-						if (docstatus != 1):
-							msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " is not Submitted Document.")
-							raise Exception, "Validation Error."
-				else:
-					msgprint(cstr(prevdoc) + ": " + cstr(prevdoc_docname) + " is not a valid " + cstr(prevdoc))
-					raise Exception, "Validation Error."
-
-
 	def validate_for_items(self):
 		check_list, chk_dupl_itm = [], []
 		for d in getlist(self.doclist,'delivery_note_details'):
@@ -292,11 +247,22 @@
 		set(self.doc, 'message', 'Items against your Order #%s have been delivered. Delivery #%s: ' % (self.doc.po_no, self.doc.name))
 		# Check for Approving Authority
 		get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self)
+		
+		# validate serial no for item table (non-sales-bom item) and packing list (sales-bom item)
 		sl_obj = get_obj("Stock Ledger")
+		sl_obj.validate_serial_no(self, 'delivery_note_details')
+		sl_obj.validate_serial_no_warehouse(self, 'delivery_note_details')
 		sl_obj.validate_serial_no(self, 'packing_details')
 		sl_obj.validate_serial_no_warehouse(self, 'packing_details')
+		
+		# update delivery details in serial no
+		sl_obj.update_serial_record(self, 'delivery_note_details', is_submit = 1, is_incoming = 0)
 		sl_obj.update_serial_record(self, 'packing_details', is_submit = 1, is_incoming = 0)
+		
+		# update delivered qty in sales order
 		get_obj("Sales Common").update_prevdoc_detail(1,self)
+		
+		# create stock ledger entry
 		self.update_stock_ledger(update_stock = 1)
 
 		self.credit_limit()
@@ -332,10 +298,14 @@
 		sales_com_obj = get_obj(dt = 'Sales Common')
 		sales_com_obj.check_stop_sales_order(self)
 		self.check_next_docstatus()
-		get_obj('Stock Ledger').update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
+		
+		# remove delivery details from serial no
+		sl = get_obj('Stock Ledger')		
+		sl.update_serial_record(self, 'delivery_note_details', is_submit = 0, is_incoming = 0)
+		sl.update_serial_record(self, 'packing_details', is_submit = 0, is_incoming = 0)
+		
 		sales_com_obj.update_prevdoc_detail(0,self)
 		self.update_stock_ledger(update_stock = -1)
-		# :::::: set DN status :::::::
 		set(self.doc, 'status', 'Cancelled')
 		self.cancel_packing_slips()
 
@@ -435,7 +405,8 @@
 
 	def on_update(self):
 		get_obj('Sales Common').make_packing_list(self,'delivery_note_details')
-		self.set_actual_qty()
-		get_obj('Stock Ledger').scrub_serial_nos(self)
+		sl = get_obj('Stock Ledger')
+		sl.scrub_serial_nos(self)
+		sl.scrub_serial_nos(self, 'packing_details')
 
 
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.txt b/erpnext/stock/doctype/delivery_note/delivery_note.txt
index 7db9513..a0c2df0 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.txt
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.txt
@@ -3,9 +3,9 @@
 
 	# These values are common in all dictionaries
 	{
-		'creation': '2012-05-15 12:15:05',
+		'creation': '2012-06-11 12:10:09',
 		'docstatus': 0,
-		'modified': '2012-05-18 18:06:26',
+		'modified': '2012-07-11 11:56:53',
 		'modified_by': u'Administrator',
 		'owner': u'Administrator'
 	},
@@ -72,26 +72,14 @@
 
 	# DocPerm
 	{
-		'amend': 1,
-		'cancel': 1,
-		'create': 1,
+		'amend': 0,
+		'cancel': 0,
+		'create': 0,
 		'doctype': u'DocPerm',
-		'permlevel': 0,
-		'role': u'Sales User',
-		'submit': 1,
-		'write': 1
-	},
-
-	# DocPerm
-	{
-		'amend': 1,
-		'cancel': 1,
-		'create': 1,
-		'doctype': u'DocPerm',
-		'permlevel': 0,
-		'role': u'Material Master Manager',
-		'submit': 1,
-		'write': 1
+		'permlevel': 1,
+		'role': u'Material User',
+		'submit': 0,
+		'write': 0
 	},
 
 	# DocPerm
@@ -108,16 +96,72 @@
 
 	# DocPerm
 	{
+		'amend': 0,
+		'cancel': 0,
+		'create': 0,
 		'doctype': u'DocPerm',
 		'permlevel': 1,
-		'role': u'All'
+		'role': u'Material Manager',
+		'submit': 0,
+		'write': 0
+	},
+
+	# DocPerm
+	{
+		'amend': 1,
+		'cancel': 1,
+		'create': 1,
+		'doctype': u'DocPerm',
+		'permlevel': 0,
+		'role': u'Sales User',
+		'submit': 1,
+		'write': 1
+	},
+
+	# DocPerm
+	{
+		'amend': 0,
+		'cancel': 0,
+		'create': 0,
+		'doctype': u'DocPerm',
+		'permlevel': 1,
+		'role': u'Sales User',
+		'submit': 0,
+		'write': 0
+	},
+
+	# DocPerm
+	{
+		'cancel': 0,
+		'create': 0,
+		'doctype': u'DocPerm',
+		'permlevel': 0,
+		'role': u'Accounts User',
+		'submit': 0,
+		'write': 0
+	},
+
+	# DocPerm
+	{
+		'doctype': u'DocPerm',
+		'permlevel': 1,
+		'role': u'Accounts User'
+	},
+
+	# DocPerm
+	{
+		'doctype': u'DocPerm',
+		'match': u'customer_name',
+		'permlevel': 0,
+		'role': u'Customer'
 	},
 
 	# DocPerm
 	{
 		'doctype': u'DocPerm',
 		'permlevel': 2,
-		'role': u'All'
+		'role': u'All',
+		'write': 1
 	},
 
 	# DocField
@@ -340,6 +384,7 @@
 	# DocField
 	{
 		'allow_on_submit': 1,
+		'colour': u'White:FFF',
 		'doctype': u'DocField',
 		'fieldname': u'delivery_note_details',
 		'fieldtype': u'Table',
@@ -355,6 +400,16 @@
 	# DocField
 	{
 		'doctype': u'DocField',
+		'fieldname': u'sales_bom_help',
+		'fieldtype': u'HTML',
+		'label': u'Sales BOM Help',
+		'permlevel': 0,
+		'print_hide': 1
+	},
+
+	# DocField
+	{
+		'doctype': u'DocField',
 		'fieldname': u'section_break0',
 		'fieldtype': u'Section Break',
 		'options': u'Simple',
diff --git a/erpnext/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt b/erpnext/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt
index 51001fc..db512c6 100644
--- a/erpnext/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt
+++ b/erpnext/stock/doctype/delivery_note_packing_item/delivery_note_packing_item.txt
@@ -3,9 +3,9 @@
 
 	# These values are common in all dictionaries
 	{
-		'creation': '2012-04-13 11:56:35',
+		'creation': '2012-06-11 12:10:10',
 		'docstatus': 0,
-		'modified': '2012-05-09 12:55:23',
+		'modified': '2012-07-10 12:05:31',
 		'modified_by': u'Administrator',
 		'owner': u'Administrator'
 	},
@@ -111,7 +111,7 @@
 		'oldfieldname': u'warehouse',
 		'oldfieldtype': u'Link',
 		'options': u'Warehouse',
-		'permlevel': 1
+		'permlevel': 0
 	},
 
 	# DocField
diff --git a/erpnext/stock/doctype/stock_ledger/stock_ledger.py b/erpnext/stock/doctype/stock_ledger/stock_ledger.py
index 0cb4b96..42ad6f6 100644
--- a/erpnext/stock/doctype/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/doctype/stock_ledger/stock_ledger.py
@@ -51,19 +51,16 @@
 		self.doclist = doclist
 
 
-	# -----------------
-	# scrub serial nos
-	# -----------------
-	def scrub_serial_nos(self, obj):
-		for d in getlist(obj.doclist, obj.fname):
+	def scrub_serial_nos(self, obj, table_name = ''):
+		if not table_name:
+			table_name = obj.fname
+		
+		for d in getlist(obj.doclist, table_name):
 			if d.serial_no:
 				d.serial_no = d.serial_no.replace(',', '\n')
 				d.save()
 
 
-	# -----------------------------
-	# validate serial no warehouse
-	# -----------------------------
 	def validate_serial_no_warehouse(self, obj, fname):
 		for d in getlist(obj.doclist, fname):
 			wh = d.warehouse or d.s_warehouse
@@ -80,10 +77,8 @@
 						msgprint("Serial No : %s for Item : %s doesn't exists in Warehouse : %s" % (s, d.item_code, wh), raise_exception = 1)
 
 
-	# ------------------------------------
-	# check whether serial no is required
-	# ------------------------------------
 	def validate_serial_no(self, obj, fname):
+		"""check whether serial no is required"""
 		for d in getlist(obj.doclist, fname):
 			is_stock_item = get_value('Item', d.item_code, 'is_stock_item')
 			ar_required = get_value('Item', d.item_code, 'has_serial_no')
@@ -101,18 +96,10 @@
 				msgprint("Rejected serial no is mandatory for rejected qty of item: "+ d.item_code, raise_exception = 1)
 				
 				
-
-
-
-	# -------------------
-	# get serial no list
-	# -------------------
 	def get_sr_no_list(self, sr_nos, qty = 0, item_code = ''):
 		return get_sr_no_list(sr_nos, qty, item_code)
 
-	# ---------------------
-	# set serial no values
-	# ---------------------
+
 	def set_pur_serial_no_values(self, obj, serial_no, d, s, new_rec):
 		item_details = sql("select item_group, warranty_period from `tabItem` where name = '%s' and \
 			(ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) " %(d.item_code), as_dict=1)
@@ -143,9 +130,6 @@
 		s.save(new_rec)
 
 
-	# ----------------------------------
-	# update serial no purchase details
-	# ----------------------------------
 	def update_serial_purchase_details(self, obj, d, serial_no, is_submit, purpose = ''):
 		exists = sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
 		if is_submit:
@@ -168,9 +152,6 @@
 				sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
 
 
-	# -------------------------------
-	# check whether serial no exists
-	# -------------------------------
 	def check_serial_no_exists(self, serial_no, item_code):
 		chk = sql("select name, status, docstatus, item_code from `tabSerial No` where name = %s", (serial_no), as_dict=1)
 		if not chk:
@@ -182,9 +163,7 @@
 		elif chk and chk[0]['status'] == 'Delivered':
 			msgprint("Serial No: %s of Item : %s is already delivered." % (serial_no, item_code), raise_exception = 1)
 
-	# ---------------------
-	# set serial no values
-	# ---------------------
+
 	def set_delivery_serial_no_values(self, obj, serial_no):
 		s = Document('Serial No', serial_no)
 		s.delivery_document_type =	 obj.doc.doctype
@@ -203,9 +182,6 @@
 		s.save()
 
 
-	# ----------------------------------
-	# update serial no delivery details
-	# ----------------------------------
 	def update_serial_delivery_details(self, obj, d, serial_no, is_submit):
 		if is_submit:
 			self.check_serial_no_exists(serial_no, d.item_code)
@@ -214,9 +190,6 @@
 			sql("update `tabSerial No` set docstatus = 0, status = 'In Store', delivery_document_type = '', delivery_document_no = '', delivery_date = null, customer = null, customer_name = '', delivery_address = '', territory = null where name = '%s'" % (serial_no))
 
 
-	# ---------------------
-	# update serial record
-	# ---------------------
 	def update_serial_record(self, obj, fname, is_submit = 1, is_incoming = 0):
 		import datetime
 		for d in getlist(obj.doclist, fname):
@@ -235,11 +208,6 @@
 					self.update_serial_purchase_details(obj, d, a, is_submit)
 				
 				
-
-
-	# -------------
-	# update stock
-	# -------------
 	def update_stock(self, values, is_amended = 'No'):
 		for v in values:
 			sle_id, serial_nos = '', ''
@@ -261,9 +229,6 @@
 				v["posting_date"], sle_id, v["posting_time"], '', v["is_cancelled"],v["voucher_type"],v["voucher_no"], is_amended)
 
 
-	# -----------
-	# make entry
-	# -----------
 	def make_entry(self, args):
 		sle = Document(doctype = 'Stock Ledger Entry')
 		for k in args.keys():