Merge branch 'wsgi' of github.com:webnotes/erpnext into wsgi
diff --git a/accounts/doctype/gl_entry/gl_entry.py b/accounts/doctype/gl_entry/gl_entry.py
index 2243512..7a73b06 100644
--- a/accounts/doctype/gl_entry/gl_entry.py
+++ b/accounts/doctype/gl_entry/gl_entry.py
@@ -107,7 +107,7 @@
 					_(" does not belong to the company") + ": " + self.doc.company)
 						
 def check_negative_balance(account, adv_adj=False):
-	if not adv_adj:
+	if not adv_adj and account:
 		account_details = webnotes.conn.get_value("Account", account, 
 				["allow_negative_balance", "debit_or_credit"], as_dict=True)
 		if not account_details["allow_negative_balance"]:
diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py
index 46faf3d..c79bfd6 100644
--- a/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -337,7 +337,7 @@
 			)
 	
 		# tax table gl entries
-		valuation_tax = 0
+		valuation_tax = {}
 		for tax in self.doclist.get({"parentfield": "purchase_tax_details"}):
 			if tax.category in ("Total", "Valuation and Total") and flt(tax.tax_amount):
 				gl_entries.append(
@@ -352,8 +352,11 @@
 				)
 			
 			# accumulate valuation tax
-			if tax.category in ("Valuation", "Valuation and Total") and flt(tax.tax_amount):
-				valuation_tax += (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)
+			if tax.category in ("Valuation", "Valuation and Total") and flt(tax.tax_amount) \
+				and tax.cost_center:
+					valuation_tax.setdefault(tax.cost_center, 0)
+					valuation_tax[tax.cost_center] += \
+						(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)
 					
 		# item gl entries
 		stock_item_and_auto_accounting_for_stock = False
@@ -394,15 +397,19 @@
 		if stock_item_and_auto_accounting_for_stock and valuation_tax:
 			# credit valuation tax amount in "Expenses Included In Valuation"
 			# this will balance out valuation amount included in cost of goods sold
-			gl_entries.append(
-				self.get_gl_dict({
-					"account": self.get_company_default("expenses_included_in_valuation"),
-					"cost_center": self.get_company_default("cost_center"),
-					"against": self.doc.credit_to,
-					"credit": valuation_tax,
-					"remarks": self.doc.remarks or "Accounting Entry for Stock"
-				})
-			)
+			expenses_included_in_valuation = \
+				self.get_company_default("expenses_included_in_valuation")
+				
+			for cost_center, amount in valuation_tax.items():
+				gl_entries.append(
+					self.get_gl_dict({
+						"account": expenses_included_in_valuation,
+						"cost_center": cost_center,
+						"against": self.doc.credit_to,
+						"credit": amount,
+						"remarks": self.doc.remarks or "Accounting Entry for Stock"
+					})
+				)
 		
 		# writeoff account includes petty difference in the invoice amount 
 		# and the amount that is paid
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index 1dca77b..5c7597c 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -83,7 +83,6 @@
 	def on_submit(self):
 		if cint(self.doc.update_stock) == 1:			
 			self.update_stock_ledger()
-			self.update_serial_nos()
 		else:
 			# Check for Approving Authority
 			if not self.doc.recurring_id:
@@ -111,7 +110,6 @@
 	def on_cancel(self):
 		if cint(self.doc.update_stock) == 1:
 			self.update_stock_ledger()
-			self.update_serial_nos(cancel = True)
 		
 		sales_com_obj = get_obj(dt = 'Sales Common')
 		sales_com_obj.check_stop_sales_order(self)
diff --git a/accounts/doctype/sales_invoice/sales_invoice.txt b/accounts/doctype/sales_invoice/sales_invoice.txt
index 77cf2cc..8cd83c4 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.txt
+++ b/accounts/doctype/sales_invoice/sales_invoice.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-05-24 19:29:05", 
   "docstatus": 0, 
-  "modified": "2013-10-02 14:24:50", 
+  "modified": "2013-10-03 18:54:31", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -181,7 +181,6 @@
   "search_index": 1
  }, 
  {
-  "default": "Today", 
   "description": "Enter the date by which payments from customer is expected against this invoice.", 
   "doctype": "DocField", 
   "fieldname": "due_date", 
diff --git a/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
index bd0726e..1c3cef3 100644
--- a/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
+++ b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
@@ -81,12 +81,12 @@
 		if account_head not in tax_accounts:
 			tax_accounts.append(account_head)
 		
-		invoice = item_tax.setdefault(parent, {})
 		if item_wise_tax_detail:
 			try:
 				item_wise_tax_detail = json.loads(item_wise_tax_detail)
 				for item, tax_amount in item_wise_tax_detail.items():
-					invoice.setdefault(item, {})[account_head] = flt(tax_amount)
+					item_tax.setdefault(parent, {}).setdefault(item, {})[account_head] = \
+						flt(tax_amount[1])
 				
 			except ValueError:
 				continue
diff --git a/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/accounts/report/item_wise_sales_register/item_wise_sales_register.py
index 77fb6f2..48bc463 100644
--- a/accounts/report/item_wise_sales_register/item_wise_sales_register.py
+++ b/accounts/report/item_wise_sales_register/item_wise_sales_register.py
@@ -9,7 +9,7 @@
 	if not filters: filters = {}
 	columns = get_columns()
 	last_col = len(columns)
-	
+
 	item_list = get_items(filters)
 	item_tax, tax_accounts = get_tax_accounts(item_list, columns)
 	
@@ -21,7 +21,7 @@
 			
 		for tax in tax_accounts:
 			row.append(item_tax.get(d.parent, {}).get(d.item_code, {}).get(tax, 0))
-			
+
 		total_tax = sum(row[last_col:])
 		row += [total_tax, d.amount + total_tax]
 		
@@ -71,19 +71,19 @@
 	tax_details = webnotes.conn.sql("""select parent, account_head, item_wise_tax_detail
 		from `tabSales Taxes and Charges` where parenttype = 'Sales Invoice' 
 		and docstatus = 1 and ifnull(account_head, '') != ''
-		and parent in (%s)""" % ', '.join(['%s']*len(item_list)), tuple([item.parent for item in item_list]))
+		and parent in (%s)""" % ', '.join(['%s']*len(item_list)), 
+		tuple([item.parent for item in item_list]))
 		
 	for parent, account_head, item_wise_tax_detail in tax_details:
 		if account_head not in tax_accounts:
 			tax_accounts.append(account_head)
-		
-		invoice = item_tax.setdefault(parent, {})
+				
 		if item_wise_tax_detail:
 			try:
 				item_wise_tax_detail = json.loads(item_wise_tax_detail)
 				for item, tax_amount in item_wise_tax_detail.items():
-					invoice.setdefault(item, {})[account_head] = flt(tax_amount)
-				
+					item_tax.setdefault(parent, {}).setdefault(item, {})[account_head] = \
+						 flt(tax_amount[1])
 			except ValueError:
 				continue
 	
diff --git a/buying/page/buying_home/buying_home.js b/buying/page/buying_home/buying_home.js
index 5db57f4..eec0725 100644
--- a/buying/page/buying_home/buying_home.js
+++ b/buying/page/buying_home/buying_home.js
@@ -145,6 +145,11 @@
 				route: "query-report/Purchase Order Trends",
 				doctype: "Purchase Order"
 			},
+			{
+				"label":wn._("Supplier Addresses And Contacts"),
+				route: "query-report/Supplier Addresses and Contacts",
+				doctype: "Supplier"
+			},
 		]
 	}
 ]
diff --git a/buying/report/supplier_addresses_and_contacts/__init__.py b/buying/report/supplier_addresses_and_contacts/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/buying/report/supplier_addresses_and_contacts/__init__.py
diff --git a/buying/report/supplier_addresses_and_contacts/supplier_addresses_and_contacts.txt b/buying/report/supplier_addresses_and_contacts/supplier_addresses_and_contacts.txt
new file mode 100644
index 0000000..fac1e9e
--- /dev/null
+++ b/buying/report/supplier_addresses_and_contacts/supplier_addresses_and_contacts.txt
@@ -0,0 +1,22 @@
+[
+ {
+  "creation": "2013-10-09 10:38:40", 
+  "docstatus": 0, 
+  "modified": "2013-10-09 10:53:52", 
+  "modified_by": "Administrator", 
+  "owner": "Administrator"
+ }, 
+ {
+  "doctype": "Report", 
+  "is_standard": "Yes", 
+  "name": "__common__", 
+  "query": "SELECT\n    `tabSupplier`.name as \"Supplier:Link/Supplier:120\",\n\t`tabSupplier`.supplier_name as \"Supplier Name::120\",\n\t`tabSupplier`.supplier_type as \"Supplier Type:Link/Supplier Type:120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2), \n\t\ttabAddress.state, tabAddress.pincode, tabAddress.country\n\t) as 'Address::180',\n    concat_ws(', ', `tabContact`.first_name, `tabContact`.last_name) as 'Contact Name::180',\n\t`tabContact`.phone as \"Phone\",\n\t`tabContact`.mobile_no as \"Mobile No\",\n\t`tabContact`.email_id as \"Email Id::120\",\n\t`tabContact`.is_primary_contact as \"Is Primary Contact::120\"\nFROM\n\t`tabSupplier`\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.supplier=`tabSupplier`.name\n\t)\n\tleft join `tabContact` on (\n\t\t`tabContact`.supplier=`tabSupplier`.name\n\t)\nWHERE\n\t`tabSupplier`.docstatus<2\nORDER BY\n\t`tabSupplier`.name asc", 
+  "ref_doctype": "Supplier", 
+  "report_name": "Supplier Addresses and Contacts", 
+  "report_type": "Query Report"
+ }, 
+ {
+  "doctype": "Report", 
+  "name": "Supplier Addresses and Contacts"
+ }
+]
\ No newline at end of file
diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py
index 7e49e60..25d76aa 100644
--- a/controllers/buying_controller.py
+++ b/controllers/buying_controller.py
@@ -24,7 +24,7 @@
 			self.doc.supplier_name = webnotes.conn.get_value("Supplier", 
 				self.doc.supplier, "supplier_name")
 		self.validate_stock_or_nonstock_items()
-		self.validate_warehouse_belongs_to_company()
+		self.validate_warehouse()
 		
 	def set_missing_values(self, for_validate=False):
 		super(BuyingController, self).set_missing_values(for_validate)
@@ -49,17 +49,20 @@
 				if supplier:
 					self.doc.supplier = supplier
 					break
+					
+	def validate_warehouse(self):
+		from stock.utils import validate_warehouse_user, validate_warehouse_company
+		
+		warehouses = list(set([d.warehouse for d in 
+			self.doclist.get({"doctype": self.tname}) if d.warehouse]))
+				
+		for w in warehouses:
+			validate_warehouse_user(w)
+			validate_warehouse_company(w, self.doc.company)
 
 	def get_purchase_tax_details(self):
 		self.doclist = self.doc.clear_table(self.doclist, "purchase_tax_details")
 		self.set_taxes("purchase_tax_details", "purchase_other_charges")
-		
-	def validate_warehouse_belongs_to_company(self):
-		for warehouse, company in webnotes.conn.get_values("Warehouse", 
-			self.doclist.get_distinct_values("warehouse"), "company").items():
-			if company and company != self.doc.company:
-				webnotes.msgprint(_("Company mismatch for Warehouse") + (": %s" % (warehouse,)),
-					raise_exception=WrongWarehouseCompany)
 
 	def validate_stock_or_nonstock_items(self):
 		if not self.get_stock_items():
diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py
index 2816524..d78cf93 100644
--- a/controllers/selling_controller.py
+++ b/controllers/selling_controller.py
@@ -236,34 +236,4 @@
 			self.doc.order_type = "Sales"
 		elif self.doc.order_type not in valid_types:
 			msgprint(_(self.meta.get_label("order_type")) + " " + 
-				_("must be one of") + ": " + comma_or(valid_types),
-				raise_exception=True)
-				
-	def update_serial_nos(self, cancel=False):
-		from stock.doctype.stock_ledger_entry.stock_ledger_entry import update_serial_nos_after_submit, get_serial_nos
-		update_serial_nos_after_submit(self, self.doc.doctype, self.fname)
-		update_serial_nos_after_submit(self, self.doc.doctype, "packing_details")
-
-		for table_fieldname in (self.fname, "packing_details"):
-			for d in self.doclist.get({"parentfield": table_fieldname}):
-				for serial_no in get_serial_nos(d.serial_no):
-					sr = webnotes.bean("Serial No", serial_no)
-					if cancel:
-						sr.doc.status = "Available"
-						for fieldname in ("warranty_expiry_date", "delivery_document_type", 
-							"delivery_document_no", "delivery_date", "delivery_time", "customer", 
-							"customer_name"):
-							sr.doc.fields[fieldname] = None
-					else:
-						sr.doc.delivery_document_type = self.doc.doctype
-						sr.doc.delivery_document_no = self.doc.name
-						sr.doc.delivery_date = self.doc.posting_date
-						sr.doc.delivery_time = self.doc.posting_time
-						sr.doc.customer = self.doc.customer
-						sr.doc.customer_name	= self.doc.customer_name
-						if sr.doc.warranty_period:
-							sr.doc.warranty_expiry_date = add_days(cstr(self.doc.posting_date), 
-								cint(sr.doc.warranty_period))
-						sr.doc.status =	'Delivered'
-
-					sr.save()
+				_("must be one of") + ": " + comma_or(valid_types), raise_exception=True)
diff --git a/hr/doctype/employee/employee.js b/hr/doctype/employee/employee.js
index 01200e7..615e276 100644
--- a/hr/doctype/employee/employee.js
+++ b/hr/doctype/employee/employee.js
@@ -4,7 +4,6 @@
 wn.provide("erpnext.hr");
 erpnext.hr.EmployeeController = wn.ui.form.Controller.extend({
 	setup: function() {
-		this.setup_leave_approver_select();
 		this.frm.fields_dict.user_id.get_query = function(doc,cdt,cdn) {
 				return { query:"core.doctype.profile.profile.profile_query"} }
 		this.frm.fields_dict.reports_to.get_query = function(doc,cdt,cdn) {	
@@ -12,6 +11,7 @@
 	},
 	
 	onload: function() {
+		this.setup_leave_approver_select();
 		this.frm.toggle_display(["esic_card_no", "gratuity_lic_id", "pan_number", "pf_number"],
 			wn.control_panel.country==="India");
 		if(this.frm.doc.__islocal) this.frm.set_value("employee_name", "");
diff --git a/manufacturing/doctype/production_order/production_order.py b/manufacturing/doctype/production_order/production_order.py
index a280a82..6bceca6 100644
--- a/manufacturing/doctype/production_order/production_order.py
+++ b/manufacturing/doctype/production_order/production_order.py
@@ -21,13 +21,14 @@
 		utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", 
 			"In Process", "Completed", "Cancelled"])
 
-		if self.doc.production_item :
-			item_detail = webnotes.conn.sql("select name from `tabItem` where name = '%s' and docstatus != 2"
-			 	% self.doc.production_item, as_dict = 1)
-			if not item_detail:
-				msgprint("Item '%s' does not exist or cancelled in the system." 
-					% cstr(self.doc.production_item), raise_exception=1)
-
+		self.validate_bom_no()
+		self.validate_sales_order()
+		self.validate_warehouse()
+		
+		from utilities.transaction_base import validate_uom_is_integer
+		validate_uom_is_integer(self.doclist, "stock_uom", ["qty", "produced_qty"])
+		
+	def validate_bom_no(self):
 		if self.doc.bom_no:
 			bom = webnotes.conn.sql("""select name from `tabBOM` where name=%s and docstatus=1 
 				and is_active=1 and item=%s"""
@@ -37,16 +38,20 @@
 					May be BOM not exists or inactive or not submitted 
 					or for some other item.""" % cstr(self.doc.bom_no), raise_exception=1)
 					
+	def validate_sales_order(self):
 		if self.doc.sales_order:
 			if not webnotes.conn.sql("""select name from `tabSales Order` 
 					where name=%s and docstatus = 1""", self.doc.sales_order):
 				msgprint("Sales Order: %s is not valid" % self.doc.sales_order, raise_exception=1)
-				
+			
 			self.validate_production_order_against_so()
-
-		from utilities.transaction_base import validate_uom_is_integer
-		validate_uom_is_integer(self.doclist, "stock_uom", ["qty", "produced_qty"])
-
+			
+	def validate_warehouse(self):
+		from stock.utils import validate_warehouse_user, validate_warehouse_company
+		
+		for w in [self.doc.fg_warehouse, self.doc.wip_warehouse]:
+			validate_warehouse_user(w)
+			validate_warehouse_company(w, self.doc.company)
 	
 	def validate_production_order_against_so(self):
 		# already ordered qty
diff --git a/patches/august_2013/p06_fix_sle_against_stock_entry.py b/patches/august_2013/p06_fix_sle_against_stock_entry.py
index 02588be..2e6c383 100644
--- a/patches/august_2013/p06_fix_sle_against_stock_entry.py
+++ b/patches/august_2013/p06_fix_sle_against_stock_entry.py
@@ -1,10 +1,9 @@
 import webnotes
 
-cancelled = []
-uncancelled = []
-
 def execute():
-	global cancelled, uncancelled
+	cancelled = []
+	uncancelled = []
+
 	stock_entries = webnotes.conn.sql("""select * from `tabStock Entry` 
 		where docstatus >= 1 and date(modified) >= "2013-08-16" 
 		and ifnull(production_order, '') != '' and ifnull(bom_no, '') != '' 
@@ -17,14 +16,12 @@
 					where voucher_type='Stock Entry' and voucher_no=%s
 					and is_cancelled='No'""", entry.name, as_dict=True)
 				if res:
-					make_stock_entry_detail(entry, res)
+					make_stock_entry_detail(entry, res, cancelled, uncancelled)
 				
 	if cancelled or uncancelled:
-		send_email()
+		send_email(cancelled, uncancelled)
 			
-def make_stock_entry_detail(entry, res):
-	global cancelled, uncancelled
-	
+def make_stock_entry_detail(entry, res, cancelled, uncancelled):
 	fg_item = webnotes.conn.get_value("Production Order", entry.production_order,
 		"production_item")
 	voucher_detail_entries_map = {}
@@ -87,9 +84,8 @@
 
 		uncancelled.append(se.doc.name)
 		
-def send_email():
+def send_email(cancelled, uncancelled):
 	from webnotes.utils.email_lib import sendmail_to_system_managers
-	global cancelled, uncancelled
 	uncancelled = "we have undone the cancellation of the following Stock Entries through a patch:\n" + \
 		"\n".join(uncancelled) if uncancelled else ""
 	cancelled = "and cancelled the following Stock Entries:\n" + "\n".join(cancelled) \
diff --git a/patches/october_2013/p01_fix_serial_no_status.py b/patches/october_2013/p01_fix_serial_no_status.py
new file mode 100644
index 0000000..0bfc400
--- /dev/null
+++ b/patches/october_2013/p01_fix_serial_no_status.py
@@ -0,0 +1,18 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import webnotes
+from webnotes.utils import flt
+
+def execute():	
+	serial_nos = webnotes.conn.sql("""select name from `tabSerial No` where status!='Not in Use' 
+		and docstatus=0""")
+	for sr in serial_nos:
+		sr_bean = webnotes.bean("Serial No", sr[0])
+		sr_bean.make_controller().via_stock_ledger = True
+		sr_bean.run_method("validate")
+		sr_bean.save()
+			
+	webnotes.conn.sql("""update `tabSerial No` set warehouse='' where status in 
+		('Delivered', 'Purchase Returned')""")
\ No newline at end of file
diff --git a/patches/october_2013/p04_wsgi_migration.py b/patches/october_2013/p04_wsgi_migration.py
new file mode 100644
index 0000000..ca73516
--- /dev/null
+++ b/patches/october_2013/p04_wsgi_migration.py
@@ -0,0 +1,30 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import webnotes
+import webnotes.utils
+import os
+
+def execute():
+	base_path = webnotes.utils.get_base_path()
+	
+	# Remove symlinks from public folder:
+	# 	- server.py
+	# 	- web.py
+	# 	- unsupported.html
+	# 	- blank.html
+	# 	- rss.xml
+	# 	- sitemap.xml
+	for file in ("server.py", "web.py", "unsupported.html", "blank.html", "rss.xml", "sitemap.xml"):
+		file_path = os.path.join(base_path, "public", file)
+		if os.path.exists(file_path):
+			os.remove(file_path)
+			
+	# Remove wn-web files
+	# 	- js/wn-web.js
+	# 	- css/wn-web.css
+	for file_path in (("js", "wn-web.js"), ("css", "wn-web.css")):
+		file_path = os.path.join(base_path, "public", *file_path)
+		if os.path.exists(file_path):
+			os.remove(file_path)	
\ No newline at end of file
diff --git a/patches/october_2013/perpetual_inventory_stock_transfer_utility.py b/patches/october_2013/perpetual_inventory_stock_transfer_utility.py
new file mode 100644
index 0000000..d8cade7
--- /dev/null
+++ b/patches/october_2013/perpetual_inventory_stock_transfer_utility.py
@@ -0,0 +1,86 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import webnotes
+from webnotes.utils import nowdate, nowtime, cstr
+from accounts.utils import get_fiscal_year
+
+def execute():
+	item_map = {}
+	for item in webnotes.conn.sql("""select * from tabItem""", as_dict=1):
+		item_map.setdefault(item.name, item)
+	
+	warehouse_map = get_warehosue_map()
+	naming_series = "STE/13/"
+	
+	for company in webnotes.conn.sql("select name from tabCompany"):
+		stock_entry = [{
+			"doctype": "Stock Entry",
+			"naming_series": naming_series,
+			"posting_date": nowdate(),
+			"posting_time": nowtime(),
+			"purpose": "Material Transfer",
+			"company": company[0],
+			"remarks": "Material Transfer to activate perpetual inventory",
+			"fiscal_year": get_fiscal_year(nowdate())[0]
+		}]
+		expense_account = "Cost of Goods Sold - NISL"
+		cost_center = "Default CC Ledger - NISL"
+		
+		for bin in webnotes.conn.sql("""select * from tabBin bin where ifnull(item_code, '')!='' 
+				and ifnull(warehouse, '') in (%s) and ifnull(actual_qty, 0) != 0
+				and (select company from tabWarehouse where name=bin.warehouse)=%s""" %
+				(', '.join(['%s']*len(warehouse_map)), '%s'), 
+				(warehouse_map.keys() + [company[0]]), as_dict=1):
+			item_details = item_map[bin.item_code]
+			new_warehouse = warehouse_map[bin.warehouse].get("fixed_asset_warehouse") \
+				if cstr(item_details.is_asset_item) == "Yes" \
+				else warehouse_map[bin.warehouse].get("current_asset_warehouse")
+				
+			if item_details.has_serial_no == "Yes":
+				serial_no = "\n".join([d[0] for d in webnotes.conn.sql("""select name 
+					from `tabSerial No` where item_code = %s and warehouse = %s 
+					and status in ('Available', 'Sales Returned')""", 
+					(bin.item_code, bin.warehouse))])
+			else:
+				serial_no = None
+			
+			stock_entry.append({
+				"doctype": "Stock Entry Detail",
+				"parentfield": "mtn_details",
+				"s_warehouse": bin.warehouse,
+				"t_warehouse": new_warehouse,
+				"item_code": bin.item_code,
+				"description": item_details.description,
+				"qty": bin.actual_qty,
+				"transfer_qty": bin.actual_qty,
+				"uom": item_details.stock_uom,
+				"stock_uom": item_details.stock_uom,
+				"conversion_factor": 1,
+				"expense_account": expense_account,
+				"cost_center": cost_center,
+				"serial_no": serial_no
+			})
+		
+		webnotes.bean(stock_entry).insert()
+		
+def get_warehosue_map():
+	return {
+		"MAHAPE": {
+			"current_asset_warehouse": "Mahape-New - NISL",
+			"fixed_asset_warehouse": ""
+		},
+		"DROP SHIPMENT": {
+			"current_asset_warehouse": "Drop Shipment-New - NISL",
+			"fixed_asset_warehouse": ""
+		},
+		"TRANSIT": {
+			"current_asset_warehouse": "Transit-New - NISL",
+			"fixed_asset_warehouse": ""
+		},
+		"ASSET - MAHAPE": {
+			"current_asset_warehouse": "",
+			"fixed_asset_warehouse": "Assets-New - NISL"
+		}
+	}
\ No newline at end of file
diff --git a/patches/october_2013/set_stock_value_diff_in_sle.py b/patches/october_2013/set_stock_value_diff_in_sle.py
new file mode 100644
index 0000000..25f95e0
--- /dev/null
+++ b/patches/october_2013/set_stock_value_diff_in_sle.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import webnotes
+from webnotes.utils import cint
+
+def execute():
+	from patches.september_2012 import repost_stock
+	repost_stock.execute()
\ No newline at end of file
diff --git a/patches/patch_list.py b/patches/patch_list.py
index a569385..92dd527 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -224,4 +224,5 @@
 	"patches.october_2013.p02_set_communication_status",
 	"patches.october_2013.p03_crm_update_status",
 	"execute:webnotes.delete_doc('DocType', 'Setup Control')",
+	"patches.october_2013.p04_wsgi_migration",
 ]
\ No newline at end of file
diff --git a/selling/doctype/lead/lead.py b/selling/doctype/lead/lead.py
index b42a380..3cc603f 100644
--- a/selling/doctype/lead/lead.py
+++ b/selling/doctype/lead/lead.py
@@ -121,4 +121,4 @@
 			}
 		}}, target_doclist)
 		
-	return [d.fields for d in doclist]
\ No newline at end of file
+	return [d if isinstance(d, dict) else d.fields for d in doclist]
diff --git a/selling/doctype/lead/lead.txt b/selling/doctype/lead/lead.txt
index 4f481b0..b700a2e 100644
--- a/selling/doctype/lead/lead.txt
+++ b/selling/doctype/lead/lead.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-04-10 11:45:37", 
   "docstatus": 0, 
-  "modified": "2013-10-03 17:24:33", 
+  "modified": "2013-10-09 15:27:54", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -159,8 +159,63 @@
   "doctype": "DocField", 
   "fieldname": "communication_history", 
   "fieldtype": "Section Break", 
-  "label": "Communication History", 
-  "options": "icon-comments"
+  "label": "Communication", 
+  "options": "icon-comments", 
+  "print_hide": 1
+ }, 
+ {
+  "default": "__user", 
+  "doctype": "DocField", 
+  "fieldname": "lead_owner", 
+  "fieldtype": "Link", 
+  "in_filter": 1, 
+  "label": "Lead Owner", 
+  "oldfieldname": "lead_owner", 
+  "oldfieldtype": "Link", 
+  "options": "Profile", 
+  "search_index": 1
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "col_break123", 
+  "fieldtype": "Column Break", 
+  "width": "50%"
+ }, 
+ {
+  "allow_on_submit": 0, 
+  "description": "Your sales person who will contact the lead in future", 
+  "doctype": "DocField", 
+  "fieldname": "contact_by", 
+  "fieldtype": "Link", 
+  "hidden": 0, 
+  "in_filter": 1, 
+  "label": "Next Contact By", 
+  "oldfieldname": "contact_by", 
+  "oldfieldtype": "Link", 
+  "options": "Profile", 
+  "print_hide": 0, 
+  "reqd": 0, 
+  "width": "100px"
+ }, 
+ {
+  "allow_on_submit": 0, 
+  "description": "Your sales person will get a reminder on this date to contact the lead", 
+  "doctype": "DocField", 
+  "fieldname": "contact_date", 
+  "fieldtype": "Date", 
+  "in_filter": 1, 
+  "label": "Next Contact Date", 
+  "no_copy": 1, 
+  "oldfieldname": "contact_date", 
+  "oldfieldtype": "Date", 
+  "reqd": 0, 
+  "width": "100px"
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "sec_break123", 
+  "fieldtype": "Section Break", 
+  "options": "Simple"
  }, 
  {
   "allow_on_submit": 0, 
@@ -274,18 +329,6 @@
   "options": "\nClient\nChannel Partner\nConsultant"
  }, 
  {
-  "default": "__user", 
-  "doctype": "DocField", 
-  "fieldname": "lead_owner", 
-  "fieldtype": "Link", 
-  "in_filter": 1, 
-  "label": "Lead Owner", 
-  "oldfieldname": "lead_owner", 
-  "oldfieldtype": "Link", 
-  "options": "Profile", 
-  "search_index": 1
- }, 
- {
   "doctype": "DocField", 
   "fieldname": "market_segment", 
   "fieldtype": "Select", 
@@ -335,49 +378,6 @@
   "width": "50%"
  }, 
  {
-  "allow_on_submit": 0, 
-  "description": "Your sales person who will contact the lead in future", 
-  "doctype": "DocField", 
-  "fieldname": "contact_by", 
-  "fieldtype": "Link", 
-  "hidden": 0, 
-  "in_filter": 1, 
-  "label": "Next Contact By", 
-  "oldfieldname": "contact_by", 
-  "oldfieldtype": "Link", 
-  "options": "Profile", 
-  "print_hide": 0, 
-  "reqd": 0, 
-  "width": "100px"
- }, 
- {
-  "allow_on_submit": 0, 
-  "description": "Your sales person will get a reminder on this date to contact the lead", 
-  "doctype": "DocField", 
-  "fieldname": "contact_date", 
-  "fieldtype": "Date", 
-  "in_filter": 1, 
-  "label": "Next Contact Date", 
-  "no_copy": 1, 
-  "oldfieldname": "contact_date", 
-  "oldfieldtype": "Date", 
-  "reqd": 0, 
-  "width": "100px"
- }, 
- {
-  "depends_on": "eval:!doc.__islocal", 
-  "description": "Date on which the lead was last contacted", 
-  "doctype": "DocField", 
-  "fieldname": "last_contact_date", 
-  "fieldtype": "Date", 
-  "label": "Last Contact Date", 
-  "no_copy": 1, 
-  "oldfieldname": "last_contact_date", 
-  "oldfieldtype": "Date", 
-  "print_hide": 1, 
-  "read_only": 1
- }, 
- {
   "doctype": "DocField", 
   "fieldname": "company", 
   "fieldtype": "Link", 
diff --git a/selling/doctype/opportunity/opportunity.py b/selling/doctype/opportunity/opportunity.py
index e63ce6b..37672f2 100644
--- a/selling/doctype/opportunity/opportunity.py
+++ b/selling/doctype/opportunity/opportunity.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import webnotes
 
-from webnotes.utils import cstr, getdate, cint
+from webnotes.utils import cstr, cint
 from webnotes.model.bean import getlist
 from webnotes import msgprint, _
 
@@ -17,7 +17,7 @@
 		self.doclist = doclist
 		self.fname = 'enq_details'
 		self.tname = 'Opportunity Item'
-
+		
 		self._prev = webnotes._dict({
 			"contact_date": webnotes.conn.get_value("Opportunity", self.doc.name, "contact_date") if \
 				(not cint(self.doc.fields.get("__islocal"))) else None,
@@ -70,10 +70,6 @@
 			
 	
 	def on_update(self):
-		# Add to calendar
-		if self.doc.contact_date and self.doc.contact_date_ref != self.doc.contact_date:
-			webnotes.conn.set(self.doc, 'contact_date_ref',self.doc.contact_date)
-
 		self.add_calendar_event()
 
 	def add_calendar_event(self, opts=None, force=False):
@@ -101,14 +97,6 @@
 		
 		super(DocType, self).add_calendar_event(opts, force)
 
-	def set_last_contact_date(self):
-		if self.doc.contact_date_ref and self.doc.contact_date_ref != self.doc.contact_date:
-			if getdate(self.doc.contact_date_ref) < getdate(self.doc.contact_date):
-				self.doc.last_contact_date=self.doc.contact_date_ref
-			else:
-				msgprint("Contact Date Cannot be before Last Contact Date")
-				raise Exception
-
 	def validate_item_details(self):
 		if not getlist(self.doclist, 'enquiry_details'):
 			msgprint("Please select items for which enquiry needs to be made")
@@ -122,7 +110,6 @@
 
 	def validate(self):
 		self.set_status()
-		self.set_last_contact_date()
 		self.validate_item_details()
 		self.validate_uom_is_integer("uom", "qty")
 		self.validate_lead_cust()
diff --git a/selling/doctype/opportunity/opportunity.txt b/selling/doctype/opportunity/opportunity.txt
index 02caea0..3c860ad 100644
--- a/selling/doctype/opportunity/opportunity.txt
+++ b/selling/doctype/opportunity/opportunity.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-03-07 18:50:30", 
   "docstatus": 0, 
-  "modified": "2013-10-03 16:30:58", 
+  "modified": "2013-10-09 15:26:29", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -405,20 +405,6 @@
   "read_only": 0
  }, 
  {
-  "allow_on_submit": 0, 
-  "depends_on": "eval:!doc.__islocal", 
-  "description": "Date on which the lead was last contacted", 
-  "doctype": "DocField", 
-  "fieldname": "last_contact_date", 
-  "fieldtype": "Date", 
-  "label": "Last Contact Date", 
-  "no_copy": 1, 
-  "oldfieldname": "last_contact_date", 
-  "oldfieldtype": "Date", 
-  "print_hide": 1, 
-  "read_only": 1
- }, 
- {
   "doctype": "DocField", 
   "fieldname": "to_discuss", 
   "fieldtype": "Small Text", 
diff --git a/selling/doctype/quotation/quotation.py b/selling/doctype/quotation/quotation.py
index 697f805..b6bc45d 100644
--- a/selling/doctype/quotation/quotation.py
+++ b/selling/doctype/quotation/quotation.py
@@ -4,7 +4,7 @@
 from __future__ import unicode_literals
 import webnotes
 
-from webnotes.utils import cstr, getdate
+from webnotes.utils import cstr
 from webnotes.model.bean import getlist
 from webnotes.model.code import get_obj
 from webnotes import _, msgprint
@@ -97,24 +97,9 @@
 					msgprint("You can not select non sales item "+d.item_code+" in Sales Quotation")
 					raise Exception
 	
-	#--------------Validation For Last Contact Date-----------------
-	# ====================================================================================================================
-	def set_last_contact_date(self):
-		#if not self.doc.contact_date_ref:
-			#self.doc.contact_date_ref=self.doc.contact_date
-			#self.doc.last_contact_date=self.doc.contact_date_ref
-		if self.doc.contact_date_ref and self.doc.contact_date_ref != self.doc.contact_date:
-			if getdate(self.doc.contact_date_ref) < getdate(self.doc.contact_date):
-				self.doc.last_contact_date=self.doc.contact_date_ref
-			else:
-				msgprint("Contact Date Cannot be before Last Contact Date")
-				raise Exception
-
 	def validate(self):
 		super(DocType, self).validate()
-		
 		self.set_status()
-		self.set_last_contact_date()
 		self.validate_order_type()
 		self.validate_for_items()
 
diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py
index d3ac7ad..0cdca58 100644
--- a/selling/doctype/sales_order/sales_order.py
+++ b/selling/doctype/sales_order/sales_order.py
@@ -126,7 +126,7 @@
 		self.validate_po()
 		self.validate_uom_is_integer("stock_uom", "qty")
 		self.validate_for_items()
-		self.validate_warehouse_user()
+		self.validate_warehouse()
 		sales_com_obj = get_obj(dt = 'Sales Common')
 		sales_com_obj.check_active_sales_items(self)
 		sales_com_obj.check_conversion_rate(self)
@@ -147,14 +147,15 @@
 		if not self.doc.delivery_status: self.doc.delivery_status = 'Not Delivered'
 		
 		
-	def validate_warehouse_user(self):
-		from stock.utils import validate_warehouse_user
+	def validate_warehouse(self):
+		from stock.utils import validate_warehouse_user, validate_warehouse_company
 		
 		warehouses = list(set([d.reserved_warehouse for d in 
 			self.doclist.get({"doctype": self.tname}) if d.reserved_warehouse]))
 				
 		for w in warehouses:
 			validate_warehouse_user(w)
+			validate_warehouse_company(w, self.doc.company)
 		
 	def validate_with_previous_doc(self):
 		super(DocType, self).validate_with_previous_doc(self.tname, {
@@ -202,7 +203,7 @@
 		
 	def check_nextdoc_docstatus(self):
 		# Checks Delivery Note
-		submit_dn = webnotes.conn.sql("select t1.name from `tabDelivery Note` t1,`tabDelivery Note Item` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % (self.doc.name))
+		submit_dn = webnotes.conn.sql("select t1.name from `tabDelivery Note` t1,`tabDelivery Note Item` t2 where t1.name = t2.parent and t2.against_sales_order = %s and t1.docstatus = 1", self.doc.name)
 		if submit_dn:
 			msgprint("Delivery Note : " + cstr(submit_dn[0][0]) + " has been submitted against " + cstr(self.doc.doctype) + ". Please cancel Delivery Note : " + cstr(submit_dn[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
 			
diff --git a/selling/utils/__init__.py b/selling/utils/__init__.py
index 801d82b..6e74ac4 100644
--- a/selling/utils/__init__.py
+++ b/selling/utils/__init__.py
@@ -74,7 +74,7 @@
 			out.update(apply_pos_settings(pos_settings, out))
 		
 	if args.doctype in ("Sales Invoice", "Delivery Note"):
-		if item_bean.doc.has_serial_no and not args.serial_no:
+		if item_bean.doc.has_serial_no == "Yes" and not args.serial_no:
 			out.serial_no = _get_serial_nos_by_fifo(args, item_bean)
 		
 	return out
diff --git a/setup/doctype/item_group/item_group.js b/setup/doctype/item_group/item_group.js
index 31edef2..0c18db0 100644
--- a/setup/doctype/item_group/item_group.js
+++ b/setup/doctype/item_group/item_group.js
@@ -7,6 +7,12 @@
 	cur_frm.add_custom_button("Item Group Tree", function() {
 		wn.set_route("Sales Browser", "Item Group");
 	})
+
+	if(!doc.__islocal && doc.show_in_website) {
+		cur_frm.add_custom_button("View In Website", function() {
+			window.open(doc.page_name);
+		}, "icon-globe");
+	}
 }
 
 cur_frm.cscript.set_root_readonly = function(doc) {
diff --git a/setup/page/setup_wizard/setup_wizard.py b/setup/page/setup_wizard/setup_wizard.py
index 1276763..d506d41 100644
--- a/setup/page/setup_wizard/setup_wizard.py
+++ b/setup/page/setup_wizard/setup_wizard.py
@@ -17,9 +17,8 @@
 		args = webnotes.local.form_dict
 	if isinstance(args, basestring):
 		args = json.loads(args)
-		
-	webnotes.conn.begin()
-
+	args = webnotes._dict(args)
+	
 	update_profile_name(args)
 	create_fiscal_year_and_company(args)
 	set_defaults(args)
diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py
index b27d034..b20e790 100644
--- a/stock/doctype/delivery_note/delivery_note.py
+++ b/stock/doctype/delivery_note/delivery_note.py
@@ -186,7 +186,6 @@
 		
 		# create stock ledger entry
 		self.update_stock_ledger()
-		self.update_serial_nos()
 
 		self.credit_limit()
 		
@@ -204,42 +203,12 @@
 		self.update_prevdoc_status()
 		
 		self.update_stock_ledger()
-		self.update_serial_nos(cancel=True)
 
 		webnotes.conn.set(self.doc, 'status', 'Cancelled')
 		self.cancel_packing_slips()
 		
 		self.make_cancel_gl_entries()
 
-	def update_serial_nos(self, cancel=False):
-		from stock.doctype.stock_ledger_entry.stock_ledger_entry import update_serial_nos_after_submit, get_serial_nos
-		update_serial_nos_after_submit(self, "Delivery Note", "delivery_note_details")
-		update_serial_nos_after_submit(self, "Delivery Note", "packing_details")
-
-		for table_fieldname in ("delivery_note_details", "packing_details"):
-			for d in self.doclist.get({"parentfield": table_fieldname}):
-				for serial_no in get_serial_nos(d.serial_no):
-					sr = webnotes.bean("Serial No", serial_no)
-					if cancel:
-						sr.doc.status = "Available"
-						for fieldname in ("warranty_expiry_date", "delivery_document_type", 
-							"delivery_document_no", "delivery_date", "delivery_time", "customer", 
-							"customer_name"):
-							sr.doc.fields[fieldname] = None
-					else:
-						sr.doc.delivery_document_type = "Delivery Note"
-						sr.doc.delivery_document_no = self.doc.name
-						sr.doc.delivery_date = self.doc.posting_date
-						sr.doc.delivery_time = self.doc.posting_time
-						sr.doc.customer = self.doc.customer
-						sr.doc.customer_name	= self.doc.customer_name
-						if sr.doc.warranty_period:
-							sr.doc.warranty_expiry_date	= add_days(cstr(self.doc.posting_date), 
-								cint(sr.doc.warranty_period))
-						sr.doc.status =	'Delivered'
-
-					sr.save()
-
 	def validate_packed_qty(self):
 		"""
 			Validate that if packed qty exists, it should be equal to qty
diff --git a/stock/doctype/item/item.js b/stock/doctype/item/item.js
index a83032e..d0b8492 100644
--- a/stock/doctype/item/item.js
+++ b/stock/doctype/item/item.js
@@ -11,14 +11,16 @@
 		&& doc.__islocal)
 	cur_frm.toggle_display("item_code", sys_defaults.item_naming_by!="Naming Series"
 		&& doc.__islocal)
+		
+	if(!doc.__islocal && doc.show_in_website) {
+		cur_frm.add_custom_button("View In Website", function() {
+			window.open(doc.page_name);
+		}, "icon-globe");
+	}
 
-
-	if ((!doc.__islocal) && (doc.is_stock_item == 'Yes')) {
-		var callback = function(r, rt) {
-			var enabled = (r.message == 'exists') ? false : true;
-			cur_frm.toggle_enable(['has_serial_no', 'is_stock_item', 'valuation_method'], enabled);
-		}
-		return $c_obj(make_doclist(doc.doctype, doc.name),'check_if_sle_exists','',callback);
+	if (!doc.__islocal && doc.is_stock_item == 'Yes') {
+		cur_frm.toggle_enable(['has_serial_no', 'is_stock_item', 'valuation_method'],
+			doc.__sle_exists=="exists" ? false : true);
 	}
 }
 
diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py
index aedb71c..595895f 100644
--- a/stock/doctype/item/item.py
+++ b/stock/doctype/item/item.py
@@ -14,6 +14,9 @@
 class WarehouseNotSet(Exception): pass
 
 class DocType(DocListController):
+	def onload(self):
+		self.doc.fields["__sle_exists"] = self.check_if_sle_exists()
+	
 	def autoname(self):
 		if webnotes.conn.get_default("item_naming_by")=="Naming Series":
 			from webnotes.model.doc import make_autoname
diff --git a/stock/doctype/landed_cost_wizard/landed_cost_wizard.py b/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
index f431537..89a3b81 100644
--- a/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
+++ b/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
@@ -85,7 +85,6 @@
 			pr_bean = webnotes.bean("Purchase Receipt", pr)
 			
 			pr_bean.run_method("update_ordered_qty", is_cancelled="Yes")
-			pr_bean.run_method("update_serial_nos", cancel=True)
 			
 			webnotes.conn.sql("""delete from `tabStock Ledger Entry` 
 				where voucher_type='Purchase Receipt' and voucher_no=%s""", pr)
@@ -97,5 +96,4 @@
 			pr_bean = webnotes.bean("Purchase Receipt", pr)
 			pr_bean.run_method("update_ordered_qty")
 			pr_bean.run_method("update_stock")
-			pr_bean.run_method("update_serial_nos")
-			pr_bean.run_method("make_gl_entries")
+			pr_bean.run_method("make_gl_entries")
\ No newline at end of file
diff --git a/stock/doctype/material_request/material_request.py b/stock/doctype/material_request/material_request.py
index 249062f..d1672ba 100644
--- a/stock/doctype/material_request/material_request.py
+++ b/stock/doctype/material_request/material_request.py
@@ -68,22 +68,14 @@
 			self.doc.status = "Draft"
 
 		import utilities
-		utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", 
-			"Cancelled"])
+		utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", "Cancelled"])
 		
-		# restrict material request type
 		self.validate_value("material_request_type", "in", ["Purchase", "Transfer"])
 
-		# Get Purchase Common Obj
 		pc_obj = get_obj(dt='Purchase Common')
-
-
-		# Validate for items
 		pc_obj.validate_for_items(self)
-		
-		# Validate qty against SO
-		self.validate_qty_against_so()
 
+		self.validate_qty_against_so()
 	
 	def update_bin(self, is_submit, is_stopped):
 		""" Update Quantity Requested for Purchase in Bin for Material Request of type 'Purchase'"""
diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py
index 7d663b8..6169b1d 100644
--- a/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -246,26 +246,12 @@
 		
 		self.update_stock()
 
-		self.update_serial_nos()
+		from stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
+		update_serial_nos_after_submit(self, "Purchase Receipt", "purchase_receipt_details")
 
 		purchase_controller.update_last_purchase_rate(self, 1)
 		
 		self.make_gl_entries()
-		
-	def update_serial_nos(self, cancel=False):
-		from stock.doctype.stock_ledger_entry.stock_ledger_entry import update_serial_nos_after_submit, get_serial_nos
-		update_serial_nos_after_submit(self, "Purchase Receipt", "purchase_receipt_details")
-
-		for d in self.doclist.get({"parentfield": "purchase_receipt_details"}):
-			for serial_no in get_serial_nos(d.serial_no):
-				sr = webnotes.bean("Serial No", serial_no)
-				if cancel:
-					sr.doc.supplier = None
-					sr.doc.supplier_name = None
-				else:
-					sr.doc.supplier = self.doc.supplier
-					sr.doc.supplier_name = self.doc.supplier_name
-				sr.save()
 
 	def check_next_docstatus(self):
 		submit_rv = webnotes.conn.sql("select t1.name from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 where t1.name = t2.parent and t2.purchase_receipt = '%s' and t1.docstatus = 1" % (self.doc.name))
@@ -292,7 +278,6 @@
 		self.update_ordered_qty()
 		
 		self.update_stock()
-		self.update_serial_nos(cancel=True)
 
 		self.update_prevdoc_status()
 		pc_obj.update_last_purchase_rate(self, 0)
@@ -308,7 +293,7 @@
 
 	def get_rate(self,arg):
 		return get_obj('Purchase Common').get_rate(arg,self)
-			
+		
 	def get_gl_entries_for_stock(self, warehouse_account=None):
 		against_stock_account = self.get_company_default("stock_received_but_not_billed")
 		
diff --git a/stock/doctype/serial_no/serial_no.py b/stock/doctype/serial_no/serial_no.py
index 1feab02..93836d6 100644
--- a/stock/doctype/serial_no/serial_no.py
+++ b/stock/doctype/serial_no/serial_no.py
@@ -4,30 +4,43 @@
 from __future__ import unicode_literals
 import webnotes
 
-from webnotes.utils import cint, getdate, nowdate
+from webnotes.utils import cint, getdate, nowdate, cstr, flt, add_days
 import datetime
-from webnotes import msgprint, _
+from webnotes import msgprint, _, ValidationError
 
 from controllers.stock_controller import StockController
 
-class SerialNoCannotCreateDirectError(webnotes.ValidationError): pass
-class SerialNoCannotCannotChangeError(webnotes.ValidationError): pass
+class SerialNoCannotCreateDirectError(ValidationError): pass
+class SerialNoCannotCannotChangeError(ValidationError): pass
+class SerialNoNotRequiredError(ValidationError): pass
+class SerialNoRequiredError(ValidationError): pass
+class SerialNoQtyError(ValidationError): pass
+class SerialNoItemError(ValidationError): pass
+class SerialNoWarehouseError(ValidationError): pass
+class SerialNoStatusError(ValidationError): pass
+class SerialNoNotExistsError(ValidationError): pass
+class SerialNoDuplicateError(ValidationError): pass
 
 class DocType(StockController):
-	def __init__(self, doc, doclist=[]):
+	def __init__(self, doc, doclist=None):
 		self.doc = doc
-		self.doclist = doclist
+		self.doclist = doclist or []
 		self.via_stock_ledger = False
 
 	def validate(self):
 		if self.doc.fields.get("__islocal") and self.doc.warehouse:
-			webnotes.throw(_("New Serial No cannot have Warehouse. Warehouse must be set by Stock Entry or Purchase Receipt"), 
-				SerialNoCannotCreateDirectError)
+			webnotes.throw(_("New Serial No cannot have Warehouse. Warehouse must be \
+				set by Stock Entry or Purchase Receipt"), SerialNoCannotCreateDirectError)
 			
 		self.validate_warranty_status()
 		self.validate_amc_status()
 		self.validate_warehouse()
 		self.validate_item()
+		
+		if self.via_stock_ledger:
+			self.set_status()
+			self.set_purchase_details()
+			self.set_sales_details()
 
 	def validate_amc_status(self):
 		"""
@@ -41,7 +54,8 @@
 			validate warranty status	
 		"""
 		if (self.doc.maintenance_status == 'Out of Warranty' and self.doc.warranty_expiry_date and getdate(self.doc.warranty_expiry_date) >= datetime.date.today()) or (self.doc.maintenance_status == 'Under Warranty' and (not self.doc.warranty_expiry_date or getdate(self.doc.warranty_expiry_date) < datetime.date.today())):
-			msgprint("Warranty expiry date and maintenance status mismatch. Please verify", raise_exception=1)
+			msgprint("Warranty expiry date and maintenance status mismatch. Please verify", 
+				raise_exception=1)
 
 
 	def validate_warehouse(self):
@@ -49,10 +63,11 @@
 			item_code, warehouse = webnotes.conn.get_value("Serial No", 
 				self.doc.name, ["item_code", "warehouse"])
 			if item_code != self.doc.item_code:
-				webnotes.throw(_("Item Code cannot be changed for Serial No."), SerialNoCannotCannotChangeError)
+				webnotes.throw(_("Item Code cannot be changed for Serial No."), 
+					SerialNoCannotCannotChangeError)
 			if not self.via_stock_ledger and warehouse != self.doc.warehouse:
-				webnotes.throw(_("Warehouse cannot be changed for Serial No."), SerialNoCannotCannotChangeError)
-	
+				webnotes.throw(_("Warehouse cannot be changed for Serial No."), 
+					SerialNoCannotCannotChangeError)
 
 	def validate_item(self):
 		"""
@@ -67,16 +82,89 @@
 		self.doc.item_name = item.item_name
 		self.doc.brand = item.brand
 		self.doc.warranty_period = item.warranty_period
-			
+				
+	def set_status(self):
+		last_sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry` 
+			where (serial_no like %s or serial_no like %s or serial_no=%s) 
+			and item_code=%s and ifnull(is_cancelled, 'No')='No' 
+			order by name desc limit 1""", 
+			("%%%s%%" % (self.doc.name+"\n"), "%%%s%%" % ("\n"+self.doc.name), self.doc.name, 
+				self.doc.item_code), as_dict=1)
+		
+		if last_sle:
+			if last_sle[0].voucher_type == "Stock Entry":
+				document_type = webnotes.conn.get_value("Stock Entry", last_sle[0].voucher_no, 
+					"purpose")
+			else:
+				document_type = last_sle[0].voucher_type
+
+			if last_sle[0].actual_qty > 0:
+				if document_type == "Sales Return":
+					self.doc.status = "Sales Returned"
+				else:
+					self.doc.status = "Available"
+			else:
+				if document_type == "Purchase Return":
+					self.doc.status = "Purchase Returned"
+				elif last_sle[0].voucher_type in ("Delivery Note", "Sales Invoice"):
+					self.doc.status = "Delivered"
+				else:
+					self.doc.status = "Not Available"
+		
+	def set_purchase_details(self):
+		purchase_sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry` 
+			where (serial_no like %s or serial_no like %s or serial_no=%s) 
+			and item_code=%s and actual_qty > 0 
+			and ifnull(is_cancelled, 'No')='No' order by name asc limit 1""", 
+			("%%%s%%" % (self.doc.name+"\n"), "%%%s%%" % ("\n"+self.doc.name), self.doc.name, 
+				 self.doc.item_code), as_dict=1)
+
+		if purchase_sle:
+			self.doc.purchase_document_type = purchase_sle[0].voucher_type
+			self.doc.purchase_document_no = purchase_sle[0].voucher_no
+			self.doc.purchase_date = purchase_sle[0].posting_date
+			self.doc.purchase_time = purchase_sle[0].posting_time
+			self.doc.purchase_rate = purchase_sle[0].incoming_rate
+			if purchase_sle[0].voucher_type == "Purchase Receipt":
+				self.doc.supplier, self.doc.supplier_name = \
+					webnotes.conn.get_value("Purchase Receipt", purchase_sle[0].voucher_no, 
+						["supplier", "supplier_name"])
+		else:
+			for fieldname in ("purchase_document_type", "purchase_document_no", 
+				"purchase_date", "purchase_time", "purchase_rate", "supplier", "supplier_name"):
+					self.doc.fields[fieldname] = None
+				
+	def set_sales_details(self):
+		delivery_sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry` 
+			where (serial_no like %s or serial_no like %s or serial_no=%s)
+			and item_code=%s and actual_qty<0 
+			and voucher_type in ('Delivery Note', 'Sales Invoice')
+			and ifnull(is_cancelled, 'No')='No' order by name desc limit 1""", 
+			("%%%s%%" % (self.doc.name+"\n"), "%%%s%%" % ("\n"+self.doc.name), self.doc.name, 
+				 self.doc.item_code), as_dict=1)
+		if delivery_sle:
+			self.doc.delivery_document_type = delivery_sle[0].voucher_type
+			self.doc.delivery_document_no = delivery_sle[0].voucher_no
+			self.doc.delivery_date = delivery_sle[0].posting_date
+			self.doc.delivery_time = delivery_sle[0].posting_time
+			self.doc.customer, self.doc.customer_name = \
+				webnotes.conn.get_value(delivery_sle[0].voucher_type, delivery_sle[0].voucher_no, 
+					["customer", "customer_name"])
+			if self.doc.warranty_period:
+				self.doc.warranty_expiry_date	= add_days(cstr(delivery_sle[0].posting_date), 
+					cint(self.doc.warranty_period))
+		else:
+			for fieldname in ("delivery_document_type", "delivery_document_no", 
+				"delivery_date", "delivery_time", "customer", "customer_name", 
+				"warranty_expiry_date"):
+					self.doc.fields[fieldname] = None		
+		
 	def on_trash(self):
 		if self.doc.status == 'Delivered':
-			msgprint("Cannot trash Serial No : %s as it is already Delivered" % (self.doc.name), raise_exception = 1)
+			webnotes.throw(_("Delivered Serial No ") + self.doc.name + _(" can not be deleted"))
 		if self.doc.warehouse:
-			webnotes.throw(_("Cannot delete Serial No in warehouse. First remove from warehouse, then delete.") + \
-				": " + self.doc.name)
-
-	def on_cancel(self):
-		self.on_trash()
+			webnotes.throw(_("Cannot delete Serial No in warehouse. \
+				First remove from warehouse, then delete.") + ": " + self.doc.name)
 	
 	def on_rename(self, new, old, merge=False):
 		"""rename serial_no text fields"""
@@ -93,3 +181,106 @@
 				webnotes.conn.sql("""update `tab%s` set serial_no = %s 
 					where name=%s""" % (dt[0], '%s', '%s'),
 					('\n'.join(serial_nos), item[0]))
+
+def process_serial_no(sle):
+	item_det = get_item_details(sle.item_code)
+	validate_serial_no(sle, item_det)
+	update_serial_nos(sle, item_det)
+					
+def validate_serial_no(sle, item_det):
+	if item_det.has_serial_no=="No":
+		if sle.serial_no:
+			webnotes.throw(_("Serial Number should be blank for Non Serialized Item" + ": " 
+				+ sle.item_code), SerialNoNotRequiredError)
+	else:
+		if sle.serial_no:
+			serial_nos = get_serial_nos(sle.serial_no)
+			if cint(sle.actual_qty) != flt(sle.actual_qty):
+				webnotes.throw(_("Serial No qty cannot be a fraction") + \
+					(": %s (%s)" % (sle.item_code, sle.actual_qty)))
+			if len(serial_nos) and len(serial_nos) != abs(cint(sle.actual_qty)):
+				webnotes.throw(_("Serial Nos do not match with qty") + \
+					(": %s (%s)" % (sle.item_code, sle.actual_qty)), SerialNoQtyError)
+			
+			for serial_no in serial_nos:
+				if webnotes.conn.exists("Serial No", serial_no):
+					sr = webnotes.bean("Serial No", serial_no)
+					
+					if sr.doc.item_code!=sle.item_code:
+						webnotes.throw(_("Serial No does not belong to Item") + 
+							(": %s (%s)" % (sle.item_code, serial_no)), SerialNoItemError)
+							
+					if sr.doc.warehouse and sle.actual_qty > 0:
+						webnotes.throw(_("Same Serial No") + ": " + sr.doc.name + 
+							_(" can not be received twice"), SerialNoDuplicateError)
+					
+					if sle.actual_qty < 0:
+						if sr.doc.warehouse!=sle.warehouse:
+							webnotes.throw(_("Serial No") + ": " + serial_no + 
+								_(" does not belong to Warehouse") + ": " + sle.warehouse, 
+								SerialNoWarehouseError)
+					
+						if sle.voucher_type in ("Delivery Note", "Sales Invoice") \
+							and sr.doc.status != "Available":
+							webnotes.throw(_("Serial No status must be 'Available' to Deliver") 
+								+ ": " + serial_no, SerialNoStatusError)
+				elif sle.actual_qty < 0:
+					# transfer out
+					webnotes.throw(_("Serial No must exist to transfer out.") + \
+						": " + serial_no, SerialNoNotExistsError)
+		elif not item_det.serial_no_series:
+			webnotes.throw(_("Serial Number Required for Serialized Item" + ": " 
+				+ sle.item_code), SerialNoRequiredError)
+				
+def update_serial_nos(sle, item_det):
+	if sle.serial_no:
+		serial_nos = get_serial_nos(sle.serial_no)
+		for serial_no in serial_nos:
+			if webnotes.conn.exists("Serial No", serial_no):
+				sr = webnotes.bean("Serial No", serial_no)
+				sr.make_controller().via_stock_ledger = True
+				sr.doc.warehouse = sle.warehouse if sle.actual_qty > 0 else None
+				sr.save()
+			elif sle.actual_qty > 0:
+				make_serial_no(serial_no, sle)
+	elif sle.actual_qty > 0 and item_det.serial_no_series:
+		from webnotes.model.doc import make_autoname
+		serial_nos = []
+		for i in xrange(cint(sle.actual_qty)):
+			serial_nos.append(make_serial_no(make_autoname(item_det.serial_no_series), sle))
+		sle.serial_no = "\n".join(serial_nos)
+
+def get_item_details(item_code):
+	return webnotes.conn.sql("""select name, has_batch_no, docstatus, 
+		is_stock_item, has_serial_no, serial_no_series 
+		from tabItem where name=%s""", item_code, as_dict=True)[0]
+		
+def get_serial_nos(serial_no):
+	return [s.strip() for s in cstr(serial_no).strip().replace(',', '\n').split('\n') if s.strip()]
+
+def make_serial_no(serial_no, sle):
+	sr = webnotes.new_bean("Serial No")
+	sr.doc.serial_no = serial_no
+	sr.doc.item_code = sle.item_code
+	sr.make_controller().via_stock_ledger = True
+	sr.insert()
+	sr.doc.warehouse = sle.warehouse
+	sr.doc.status = "Available"
+	sr.save()
+	webnotes.msgprint(_("Serial No created") + ": " + sr.doc.name)
+	return sr.doc.name
+	
+def update_serial_nos_after_submit(controller, parenttype, parentfield):
+	if not hasattr(webnotes, "new_stock_ledger_entries"):
+		return
+		
+	for d in controller.doclist.get({"parentfield": parentfield}):
+		serial_no = None
+		for sle in webnotes.new_stock_ledger_entries:
+			if sle.voucher_detail_no==d.name:
+				serial_no = sle.serial_no
+				break
+
+		if d.serial_no != serial_no:
+			d.serial_no = serial_no
+			webnotes.conn.set_value(d.doctype, d.name, "serial_no", serial_no)
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index 535d4c8..0117864 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -51,13 +51,15 @@
 		
 	def on_submit(self):
 		self.update_stock_ledger()
-		self.update_serial_no(1)
+
+		from stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
+		update_serial_nos_after_submit(self, "Stock Entry", "mtn_details")
+		
 		self.update_production_order(1)
 		self.make_gl_entries()
 
 	def on_cancel(self):
 		self.update_stock_ledger()
-		self.update_serial_no(0)
 		self.update_production_order(0)
 		self.make_cancel_gl_entries()
 		
@@ -293,24 +295,6 @@
 			from `tabStock Entry Detail` where parent in (
 				select name from `tabStock Entry` where `%s`=%s and docstatus=1)
 			group by item_code""" % (ref_fieldname, "%s"), (self.doc.fields.get(ref_fieldname),)))
-		
-	def update_serial_no(self, is_submit):
-		"""Create / Update Serial No"""
-
-		from stock.doctype.stock_ledger_entry.stock_ledger_entry import update_serial_nos_after_submit, get_serial_nos
-		update_serial_nos_after_submit(self, "Stock Entry", "mtn_details")
-		
-		for d in getlist(self.doclist, 'mtn_details'):
-			for serial_no in get_serial_nos(d.serial_no):
-				if self.doc.purpose == 'Purchase Return':
-					sr = webnotes.bean("Serial No", serial_no)
-					sr.doc.status = "Purchase Returned" if is_submit else "Available"
-					sr.save()
-				
-				if self.doc.purpose == "Sales Return":
-					sr = webnotes.bean("Serial No", serial_no)
-					sr.doc.status = "Sales Returned" if is_submit else "Delivered"
-					sr.save()
 						
 	def update_stock_ledger(self):
 		sl_entries = []			
diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py
index e2358eb..b41a626 100644
--- a/stock/doctype/stock_entry/test_stock_entry.py
+++ b/stock/doctype/stock_entry/test_stock_entry.py
@@ -7,7 +7,7 @@
 from __future__ import unicode_literals
 import webnotes, unittest
 from webnotes.utils import flt
-from stock.doctype.stock_ledger_entry.stock_ledger_entry import *
+from stock.doctype.serial_no.serial_no import *
 from stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
 
 
@@ -48,7 +48,7 @@
 		webnotes.bean("Profile", "test2@example.com").get_controller()\
 			.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
 
-		from stock.doctype.stock_ledger_entry.stock_ledger_entry import InvalidWarehouseCompany
+		from stock.utils import InvalidWarehouseCompany
 		st1 = webnotes.bean(copy=test_records[0])
 		st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1"
 		st1.insert()
@@ -721,6 +721,18 @@
 		se.insert()
 		self.assertRaises(SerialNoNotExistsError, se.submit)
 		
+	def test_serial_duplicate(self):
+		self._clear_stock_account_balance()
+		self.test_serial_by_series()
+		
+		se = webnotes.bean(copy=test_records[0])
+		se.doclist[1].item_code = "_Test Serialized Item With Series"
+		se.doclist[1].qty = 1
+		se.doclist[1].serial_no = "ABCD00001"
+		se.doclist[1].transfer_qty = 1
+		se.insert()
+		self.assertRaises(SerialNoDuplicateError, se.submit)
+		
 	def test_serial_by_series(self):
 		self._clear_stock_account_balance()
 		se = make_serialized_item()
diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index 1c3d3e1..8fef889 100644
--- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -3,29 +3,17 @@
 
 from __future__ import unicode_literals
 import webnotes
-from webnotes import _, msgprint, ValidationError
+from webnotes import _, msgprint
 from webnotes.utils import cint, flt, getdate, cstr
 from webnotes.model.controller import DocListController
 
-class InvalidWarehouseCompany(ValidationError): pass
-class SerialNoNotRequiredError(ValidationError): pass
-class SerialNoRequiredError(ValidationError): pass
-class SerialNoQtyError(ValidationError): pass
-class SerialNoItemError(ValidationError): pass
-class SerialNoWarehouseError(ValidationError): pass
-class SerialNoStatusError(ValidationError): pass
-class SerialNoNotExistsError(ValidationError): pass
-
-def get_serial_nos(serial_no):
-	return [s.strip() for s in cstr(serial_no).strip().replace(',', '\n').split('\n') if s.strip()]
-
 class DocType(DocListController):
 	def __init__(self, doc, doclist=[]):
 		self.doc = doc
 		self.doclist = doclist
 
 	def validate(self):
-		from stock.utils import validate_warehouse_user
+		from stock.utils import validate_warehouse_user, validate_warehouse_company
 		if not hasattr(webnotes, "new_stock_ledger_entries"):
 			webnotes.new_stock_ledger_entries = []
 			
@@ -33,7 +21,7 @@
 		self.validate_mandatory()
 		self.validate_item()
 		validate_warehouse_user(self.doc.warehouse)
-		self.validate_warehouse_company()
+		validate_warehouse_company(self.doc.warehouse, self.doc.company)
 		self.scrub_posting_time()
 		
 		from accounts.utils import validate_fiscal_year
@@ -42,7 +30,9 @@
 	def on_submit(self):
 		self.check_stock_frozen_date()
 		self.actual_amt_check()
-		self.validate_serial_no()
+		
+		from stock.doctype.serial_no.serial_no import process_serial_no
+		process_serial_no(self.doc)
 		
 	#check for item quantity available in stock
 	def actual_amt_check(self):
@@ -63,13 +53,6 @@
 					as on %(posting_date)s %(posting_time)s""" % self.doc.fields)
 
 				sself.doc.fields.pop('batch_bal')
-			 
-	def validate_warehouse_company(self):
-		warehouse_company = webnotes.conn.get_value("Warehouse", self.doc.warehouse, "company")
-		if warehouse_company and warehouse_company != self.doc.company:
-			webnotes.msgprint(_("Warehouse does not belong to company.") + " (" + \
-				self.doc.warehouse + ", " + self.doc.company +")", 
-				raise_exception=InvalidWarehouseCompany)
 
 	def validate_mandatory(self):
 		mandatory = ['warehouse','posting_date','voucher_type','voucher_no','actual_qty','company']
@@ -81,7 +64,10 @@
 					msgprint("Warehouse: '%s' does not exist in the system. Please check." % self.doc.fields.get(k), raise_exception = 1)
 
 	def validate_item(self):
-		item_det = self.get_item_details()
+		item_det = webnotes.conn.sql("""select name, has_batch_no, docstatus, 
+			is_stock_item, has_serial_no, serial_no_series 
+			from tabItem where name=%s""", 
+			self.doc.item_code, as_dict=True)[0]
 
 		if item_det.is_stock_item != 'Yes':
 			webnotes.throw("""Item: "%s" is not a Stock Item.""" % self.doc.item_code)
@@ -99,95 +85,6 @@
 		if not self.doc.stock_uom:
 			self.doc.stock_uom = item_det.stock_uom
 					
-	def get_item_details(self):
-		return webnotes.conn.sql("""select name, has_batch_no, docstatus, 
-			is_stock_item, has_serial_no, serial_no_series 
-			from tabItem where name=%s""", 
-			self.doc.item_code, as_dict=True)[0]
-	
-	def validate_serial_no(self):
-		item_det = self.get_item_details()
-
-		if item_det.has_serial_no=="No":
-			if self.doc.serial_no:
-				webnotes.throw(_("Serial Number should be blank for Non Serialized Item" + ": " + self.doc.item), 
-					SerialNoNotRequiredError)
-		else:
-			if self.doc.serial_no:
-				serial_nos = get_serial_nos(self.doc.serial_no)
-				if cint(self.doc.actual_qty) != flt(self.doc.actual_qty):
-					webnotes.throw(_("Serial No qty cannot be a fraction") + \
-						(": %s (%s)" % (self.doc.item_code, self.doc.actual_qty)))
-				if len(serial_nos) and len(serial_nos) != abs(cint(self.doc.actual_qty)):
-					webnotes.throw(_("Serial Nos do not match with qty") + \
-						(": %s (%s)" % (self.doc.item_code, self.doc.actual_qty)), SerialNoQtyError)
-
-				# check serial no exists, if yes then source
-				for serial_no in serial_nos:
-					if webnotes.conn.exists("Serial No", serial_no):
-						sr = webnotes.bean("Serial No", serial_no)
-
-						if sr.doc.item_code!=self.doc.item_code:
-							webnotes.throw(_("Serial No does not belong to Item") + \
-								(": %s (%s)" % (self.doc.item_code, serial_no)), SerialNoItemError)
-
-						sr.make_controller().via_stock_ledger = True
-
-						if self.doc.actual_qty < 0:
-							if sr.doc.warehouse!=self.doc.warehouse:
-								webnotes.throw(_("Serial No") + ": " + serial_no + 
-									_(" does not belong to Warehouse") + ": " + self.doc.warehouse, 
-									SerialNoWarehouseError)
-								
-							if self.doc.voucher_type in ("Delivery Note", "Sales Invoice") \
-								and sr.doc.status != "Available":
-								webnotes.throw(_("Serial No status must be 'Available' to Deliver") 
-									+ ": " + serial_no, SerialNoStatusError)
-								
-									
-							sr.doc.warehouse = None
-							sr.save()
-						else:
-							sr.doc.warehouse = self.doc.warehouse
-							sr.save()
-					else:
-						if self.doc.actual_qty < 0:
-							# transfer out
-							webnotes.throw(_("Serial No must exist to transfer out.") + \
-								": " + serial_no, SerialNoNotExistsError)
-						else:
-							# transfer in
-							self.make_serial_no(serial_no)
-			else:
-				if item_det.serial_no_series:
-					from webnotes.model.doc import make_autoname
-					serial_nos = []
-					for i in xrange(cint(self.doc.actual_qty)):
-						serial_nos.append(self.make_serial_no(make_autoname(item_det.serial_no_series)))
-					self.doc.serial_no = "\n".join(serial_nos)
-				else:
-					webnotes.throw(_("Serial Number Required for Serialized Item" + ": " + self.doc.item),
-						SerialNoRequiredError)
-	
-	def make_serial_no(self, serial_no):
-		sr = webnotes.new_bean("Serial No")
-		sr.doc.serial_no = serial_no
-		sr.doc.item_code = self.doc.item_code
-		sr.doc.purchase_rate = self.doc.incoming_rate
-		sr.doc.purchase_document_type = self.doc.voucher_type
-		sr.doc.purchase_document_no = self.doc.voucher_no
-		sr.doc.purchase_date = self.doc.posting_date
-		sr.doc.purchase_time = self.doc.posting_time
-		sr.make_controller().via_stock_ledger = True
-		sr.insert()
-		
-		# set warehouse
-		sr.doc.warehouse = self.doc.warehouse
-		sr.doc.status = "Available"
-		sr.save()
-		webnotes.msgprint(_("Serial No created") + ": " + sr.doc.name)
-		return sr.doc.name
-		
 	def check_stock_frozen_date(self):
 		stock_frozen_upto = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto') or ''
 		if stock_frozen_upto:
@@ -199,21 +96,6 @@
 		if not self.doc.posting_time or self.doc.posting_time == '00:0':
 			self.doc.posting_time = '00:00'
 
-def update_serial_nos_after_submit(controller, parenttype, parentfield):
-	if not hasattr(webnotes, "new_stock_ledger_entries"):
-		return
-		
-	for d in controller.doclist.get({"parentfield": parentfield}):
-		serial_no = None
-		for sle in webnotes.new_stock_ledger_entries:
-			if sle.voucher_detail_no==d.name:
-				serial_no = sle.serial_no
-				break
-
-		if d.serial_no != serial_no:
-			d.serial_no = serial_no
-			webnotes.conn.set_value(d.doctype, d.name, "serial_no", serial_no)
-
 def on_doctype_update():
 	if not webnotes.conn.sql("""show index from `tabStock Ledger Entry` 
 		where Key_name="posting_sort_index" """):
diff --git a/stock/utils.py b/stock/utils.py
index 8836c6c..1f50164 100644
--- a/stock/utils.py
+++ b/stock/utils.py
@@ -9,6 +9,7 @@
 from webnotes.utils.email_lib import sendmail
 
 class UserNotAllowedForWarehouse(webnotes.ValidationError): pass
+class InvalidWarehouseCompany(webnotes.ValidationError): pass
 	
 def get_stock_balance_on(warehouse, posting_date=None):
 	if not posting_date: posting_date = nowdate()
@@ -216,6 +217,12 @@
 	if warehouse_users and not (webnotes.session.user in warehouse_users):
 		webnotes.throw(_("Not allowed entry in Warehouse") \
 			+ ": " + warehouse, UserNotAllowedForWarehouse)
+			
+def validate_warehouse_company(warehouse, company):
+	warehouse_company = webnotes.conn.get_value("Warehouse", warehouse, "company")
+	if warehouse_company and warehouse_company != company:
+		webnotes.msgprint(_("Warehouse does not belong to company.") + " (" + \
+			warehouse + ", " + company +")", raise_exception=InvalidWarehouseCompany)
 
 def get_sales_bom_buying_amount(item_code, warehouse, voucher_type, voucher_no, voucher_detail_no, 
 		stock_ledger_entries, item_sales_bom):
diff --git a/support/report/maintenance_schedules/maintenance_schedules.txt b/support/report/maintenance_schedules/maintenance_schedules.txt
index 525f483..766eb20 100644
--- a/support/report/maintenance_schedules/maintenance_schedules.txt
+++ b/support/report/maintenance_schedules/maintenance_schedules.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-05-06 14:25:21", 
   "docstatus": 0, 
-  "modified": "2013-05-06 14:32:47", 
+  "modified": "2013-10-09 12:23:27", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -10,7 +10,7 @@
   "doctype": "Report", 
   "is_standard": "Yes", 
   "name": "__common__", 
-  "query": "SELECT\n    ms_item.scheduled_date as \"Schedule Date:Date:120\",\n\tms_item.item_code as \"Item Code:Link/Item:120\",\n\tms_item.item_name as \"Item Name::120\",\n\tms_item.serial_no as \"Serial No::120\",\n\tms_item.incharge_name as \"Incharge::120\",\n\tms.customer_name as \"Customer:Link/Customer:120\",\n\tms.address_display as \"Customer Address::120\",\n\tms.sales_order_no as \"Sales Order:Link/Sales Order:120\",\n\tms.company as \"Company:Link/Company:120\"\n\t\nFROM\n\t`tabMaintenance Schedule` ms, `tabMaintenance Schedule Detail` ms_item\nWHERE\n\tms.name = ms_item.parent and ms.docstatus = 1\nORDER BY\n\tms_item.scheduled_date asc, ms_item.item_code asc", 
+  "query": "SELECT\n    ms_sch.scheduled_date as \"Schedule Date:Date:120\",\n\tms_sch.item_code as \"Item Code:Link/Item:120\",\n\tms_sch.item_name as \"Item Name::120\",\n\tms_sch.serial_no as \"Serial No::120\",\n\tms_sch.incharge_name as \"Incharge::120\",\n\tms.customer_name as \"Customer:Link/Customer:120\",\n\tms.address_display as \"Customer Address::120\",\n\tms_item.prevdoc_docname as \"Sales Order:Link/Sales Order:120\",\n\tms.company as \"Company:Link/Company:120\"\n\t\nFROM\n\t`tabMaintenance Schedule` ms, \n    `tabMaintenance Schedule Detail` ms_sch, \n    `tabMaintenance Schedule Item` ms_item\nWHERE\n\tms.name = ms_sch.parent and ms.name = ms_item.parent and ms.docstatus = 1\nORDER BY\n\tms_sch.scheduled_date asc, ms_sch.item_code asc", 
   "ref_doctype": "Maintenance Schedule", 
   "report_name": "Maintenance Schedules", 
   "report_type": "Query Report"
diff --git a/utilities/demo/make_demo.py b/utilities/demo/make_demo.py
index d335528..219ce86 100644
--- a/utilities/demo/make_demo.py
+++ b/utilities/demo/make_demo.py
@@ -75,7 +75,7 @@
 	
 	for i in xrange(runs_for):		
 		print current_date.strftime("%Y-%m-%d")
-		webnotes.utils.current_date = current_date
+		webnotes.local.current_date = current_date
 		
 		if current_date.weekday() in (5, 6):
 			current_date = webnotes.utils.add_days(current_date, 1)
diff --git a/utilities/demo/make_erpnext_demo.py b/utilities/demo/make_erpnext_demo.py
index d67fb5e..262a759 100644
--- a/utilities/demo/make_erpnext_demo.py
+++ b/utilities/demo/make_erpnext_demo.py
@@ -6,8 +6,8 @@
 import utilities.demo.make_demo
 
 def make_demo_app(site=None):
-	webnotes.flags.mute_emails = 1
 	webnotes.init(site=site)
+	webnotes.flags.mute_emails = 1
 
 	utilities.demo.make_demo.make(reset=True, simulate=False)
 	# setup demo user etc so that the site it up faster, while the data loads
@@ -15,6 +15,7 @@
 	make_demo_login_page()
 	make_demo_on_login_script()
 	utilities.demo.make_demo.make(reset=False, simulate=True)
+	webnotes.destroy()
 
 def make_demo_user():
 	from webnotes.auth import _update_password