Merge branch 'master' of github.com:webnotes/erpnext
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index 906de23..de3ee95 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -540,8 +540,7 @@
 		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
+				msgprint("To make POS entry, please create POS Setting from Accounts --> POS Setting page and refresh the system.", raise_exception=True)
 			elif not ps[0][1]:
 				msgprint("Please enter warehouse in POS Setting")
 			else:
diff --git a/buying/doctype/purchase_common/purchase_common.js b/buying/doctype/purchase_common/purchase_common.js
index 05b7bcb..dacee80 100644
--- a/buying/doctype/purchase_common/purchase_common.js
+++ b/buying/doctype/purchase_common/purchase_common.js
@@ -21,7 +21,7 @@
 
 wn.provide("erpnext.buying");
 
-erpnext.buying.BuyingController = erpnext.utils.Controller.extend({
+erpnext.buying.BuyingController = wn.ui.form.Controller.extend({
 	setup: function() {
 		var me = this;
 		
@@ -68,15 +68,15 @@
 					callback: function(r) {
 						if(!r.exc) {
 							me.price_list_currency();
-							if (callback_fn) callback_fn(me.frm.doc, me.frm.doc.doctype, 
-									me.frm.doc.name);
+							if (typeof callback_fn === "function") 
+								callback_fn(me.frm.doc, me.frm.doc.doctype, me.frm.doc.name);
 						}
 					}
 				});
 			} else {
 				me.price_list_currency();
-				if (callback_fn) callback_fn(me.frm.doc, me.frm.doc.doctype, 
-						me.frm.doc.name);
+				if (typeof callback_fn === "function") 
+					callback_fn(me.frm.doc, me.frm.doc.doctype, me.frm.doc.name);
 			}
 		} 
 	},
diff --git a/buying/doctype/purchase_order/purchase_order.py b/buying/doctype/purchase_order/purchase_order.py
index 438442c..218d4bf 100644
--- a/buying/doctype/purchase_order/purchase_order.py
+++ b/buying/doctype/purchase_order/purchase_order.py
@@ -132,6 +132,10 @@
 		for d in getlist(self.doclist, 'po_details'):
 			#1. Check if is_stock_item == 'Yes'
 			if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes":
+				# this happens when item is changed from non-stock to stock item
+				if not d.warehouse:
+					continue
+				
 				ind_qty, po_qty = 0, flt(d.qty) * flt(d.conversion_factor)
 				if is_stopped:
 					po_qty = flt(d.qty) > flt(d.received_qty) and \
diff --git a/hr/doctype/employee/employee.py b/hr/doctype/employee/employee.py
index 2bd7998..d98c8a7 100644
--- a/hr/doctype/employee/employee.py
+++ b/hr/doctype/employee/employee.py
@@ -17,7 +17,7 @@
 from __future__ import unicode_literals
 import webnotes
 
-from webnotes.utils import getdate, validate_email_add
+from webnotes.utils import getdate, validate_email_add, cstr
 from webnotes.model.doc import make_autoname
 from webnotes import msgprint, _
 
@@ -104,7 +104,7 @@
 				fname, fid = file_args.split(",")
 				if self.doc.image == fname:
 					new_file_args = fname + "," + fid
-					file_list = profile_wrapper.doc.file_list.split("\n")
+					file_list = cstr(profile_wrapper.doc.file_list).split("\n")
 					if new_file_args not in file_list:
 						file_list += [new_file_args]
 					profile_wrapper.doc.file_list = "\n".join(file_list)
diff --git a/hr/doctype/upload_attendance/upload_attendance.js b/hr/doctype/upload_attendance/upload_attendance.js
index 008e1cd..0c1d7b2 100644
--- a/hr/doctype/upload_attendance/upload_attendance.js
+++ b/hr/doctype/upload_attendance/upload_attendance.js
@@ -18,7 +18,7 @@
 wn.require("public/app/js/utils.js");
 wn.provide("erpnext.hr");
 
-erpnext.hr.AttendanceControlPanel = erpnext.utils.Controller.extend({
+erpnext.hr.AttendanceControlPanel = wn.ui.form.Controller.extend({
 	onload: function() {
 		this.frm.set_value("att_fr_date", get_today());
 		this.frm.set_value("att_to_date", get_today());
diff --git a/patches/march_2013/p03_rename_blog_to_blog_post.py b/patches/march_2013/p03_rename_blog_to_blog_post.py
index 7520f9c..69902f34 100644
--- a/patches/march_2013/p03_rename_blog_to_blog_post.py
+++ b/patches/march_2013/p03_rename_blog_to_blog_post.py
@@ -6,4 +6,4 @@
 	webnotes.reload_doc('website', 'doctype', 'blog_post')
 	webnotes.conn.sql('''update tabBlogger set posts=(select count(*) 
 		from `tabBlog Post` where ifnull(blogger,"")=tabBlogger.name)''')
-	webnotes.conn.sql("""update `tabBlog Post` set published_on=creation""")
+	webnotes.conn.sql("""update `tabBlog Post` set published_on=date(creation)""")
diff --git a/projects/doctype/task/task.js b/projects/doctype/task/task.js
index 472ca6b..8493920 100644
--- a/projects/doctype/task/task.js
+++ b/projects/doctype/task/task.js
@@ -18,7 +18,7 @@
 
 cur_frm.add_fetch("project", "company", "company");
 
-erpnext.projects.Task = erpnext.utils.Controller.extend({
+erpnext.projects.Task = wn.ui.form.Controller.extend({
 	setup: function() {
 		this.frm.fields_dict.project.get_query = function() {
 			return "select name from `tabProject` \
@@ -29,7 +29,8 @@
 
 	project: function() {
 		if(this.frm.doc.project) {
-			get_server_fields('get_project_details', '','', doc, cdt, cdn, 1);
+			get_server_fields('get_project_details', '','', this.frm.doc, this.frm.doc.doctype, 
+				this.frm.doc.name, 1);
 		}
 	},
 
diff --git a/public/js/controllers/stock_controller.js b/public/js/controllers/stock_controller.js
index d3511e1..15d34e0 100644
--- a/public/js/controllers/stock_controller.js
+++ b/public/js/controllers/stock_controller.js
@@ -16,7 +16,7 @@
 
 wn.provide("erpnext.stock");
 
-erpnext.stock.StockController = erpnext.utils.Controller.extend({
+erpnext.stock.StockController = wn.ui.form.Controller.extend({
 	show_stock_ledger: function() {
 		var me = this;
 		this.frm.add_custom_button("Show Stock Ledger", function() {
diff --git a/public/js/utils.js b/public/js/utils.js
index 0f78705..4df9555 100644
--- a/public/js/utils.js
+++ b/public/js/utils.js
@@ -23,35 +23,4 @@
 		return wn.model.get(":Company", company).default_currency || wn.boot.sysdefaults.currency;
 	else
 		return wn.boot.sysdefaults.currency;
-}
-
-// TODO
-erpnext.utils.Controller = Class.extend({
-	init: function(opts) {
-		$.extend(this, opts);
-		this.setup && this.setup();
-	},
-	
-	onload_post_render: function() {
-		if(this.frm.doc.__islocal) {
-			this.setup_defaults();
-		}
-	},
-	
-	setup_defaults: function() {
-		var me = this;
-		
-		var defaults = {
-			posting_date: wn.datetime.get_today(),
-			posting_time: wn.datetime.now_time()
-		}
-		
-		$.each(defaults, function(k, v) {
-			if(!me.frm.doc[k]) me.frm.set_value(k, v);
-		});
-	},
-	
-	refresh: function() {
-		erpnext.hide_naming_series();
-	}
-});
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py
index 8205afb..5009c4e 100644
--- a/selling/doctype/sales_order/sales_order.py
+++ b/selling/doctype/sales_order/sales_order.py
@@ -156,9 +156,13 @@
 			f = [d.item_code, d.description]
 
 			#check item is stock item
-			st_itm = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code)
+			st_itm = sql("select is_stock_item from `tabItem` where name = %s", d.item_code)
 
 			if st_itm and st_itm[0][0] == 'Yes':
+				if not d.reserved_warehouse:
+					msgprint("""Please enter Reserved Warehouse for item %s 
+						as it is stock Item""" % d.item_code, raise_exception=1)
+				
 				if e in check_list:
 					msgprint("Item %s has been entered twice." % d.item_code)
 				else:
@@ -333,10 +337,6 @@
 	def update_stock_ledger(self, update_stock, is_stopped = 0):
 		for d in self.get_item_list(is_stopped):
 			if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes":
-				if not d['reserved_warehouse']:
-					msgprint("""Please enter Reserved Warehouse for item %s 
-						as it is stock Item""" % d['item_code'], raise_exception=1)
-				
 				args = {
 					"item_code": d['item_code'],
 					"reserved_qty": flt(update_stock) * flt(d['reserved_qty']),
diff --git a/selling/doctype/sales_order/test_sales_order.py b/selling/doctype/sales_order/test_sales_order.py
index 5d820fe..40a10b4 100644
--- a/selling/doctype/sales_order/test_sales_order.py
+++ b/selling/doctype/sales_order/test_sales_order.py
@@ -65,7 +65,7 @@
 		# submit dn
 		dn = self.create_dn_against_so(so)
 		
-		self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 6.0)
+		self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 5.0)
 		
 		# stop so
 		so.load_from_db()
@@ -75,7 +75,7 @@
 		# unstop so
 		so.load_from_db()
 		so.obj.unstop_sales_order()
-		self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 6.0)
+		self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 5.0)
 		
 		# cancel dn
 		dn.cancel()
@@ -151,9 +151,9 @@
 		dn = self.create_dn_against_so(so)
 		
 		self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 
-			so.doclist[1].reserved_warehouse, 30.0)
+			so.doclist[1].reserved_warehouse, 25.0)
 		self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 
-			so.doclist[1].reserved_warehouse, 12.0)
+			so.doclist[1].reserved_warehouse, 10.0)
 				
 		# stop so
 		so.load_from_db()
@@ -168,9 +168,9 @@
 		so.load_from_db()
 		so.obj.unstop_sales_order()
 		self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 
-			so.doclist[1].reserved_warehouse, 30.0)
+			so.doclist[1].reserved_warehouse, 25.0)
 		self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 
-			so.doclist[1].reserved_warehouse, 12.0)
+			so.doclist[1].reserved_warehouse, 10.0)
 		
 		# cancel dn
 		dn.cancel()
@@ -234,8 +234,8 @@
 			"price_list_name": "_Test Price List", 
 			"territory": "_Test Territory", 
 			"transaction_date": "2013-02-21",
-			"grand_total": 500.0, 
-			"grand_total_export": 500.0, 
+			"grand_total": 1000.0, 
+			"grand_total_export": 1000.0, 
 		}, 
 		{
 			"description": "CPU", 
@@ -244,9 +244,9 @@
 			"item_name": "CPU", 
 			"parentfield": "sales_order_details", 
 			"qty": 10.0,
-			"basic_rate": 50.0,
-			"export_rate": 50.0,
-			"amount": 500.0,
+			"basic_rate": 100.0,
+			"export_rate": 100.0,
+			"amount": 1000.0,
 			"reserved_warehouse": "_Test Warehouse",
 		}
 	],	
diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py
index 3d799c4..229ec40 100644
--- a/stock/doctype/delivery_note/delivery_note.py
+++ b/stock/doctype/delivery_note/delivery_note.py
@@ -156,7 +156,7 @@
 		if not self.doc.billing_status: self.doc.billing_status = 'Not Billed'
 		if not self.doc.installation_status: self.doc.installation_status = 'Not Installed'
 
-
+		
 	def validate_mandatory(self):
 		if self.doc.amended_from and not self.doc.amendment_date:
 			msgprint("Please Enter Amendment Date")
@@ -338,10 +338,10 @@
 		self.values = []
 		for d in self.get_item_list():
 			if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes":
-				if not d['warehouse']:
-					msgprint("Please enter Warehouse for item %s as it is stock item"
-						% d['item_code'], raise_exception=1)
-						
+				# this happens when item is changed from non-stock to stock item
+				if not d["warehouse"]:
+					continue
+				
 				if d['reserved_qty'] < 0 :
 					# Reduce reserved qty from reserved warehouse mentioned in so
 					args = {
@@ -407,6 +407,15 @@
 				webnotes.conn.set_value("Delivery Note Item", item.name, "buying_amount", 
 					item.buying_amount)
 		
+		self.validate_warehouse()
+		
+	def validate_warehouse(self):
+		for d in self.get_item_list():
+			if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes":
+				if not d['warehouse']:
+					msgprint("Please enter Warehouse for item %s as it is stock item"
+						% d['item_code'], raise_exception=1)
+		
 	def make_gl_entries(self):
 		if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
 			return
@@ -440,4 +449,4 @@
 	def get_total_buying_amount(self):
 		total_buying_amount = sum([item.buying_amount for item in 
 			self.doclist.get({"parentfield": "delivery_note_details"})])
-		return total_buying_amount
\ No newline at end of file
+		return total_buying_amount
diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py
index 334af298..74bf3f3 100644
--- a/stock/doctype/item/item.py
+++ b/stock/doctype/item/item.py
@@ -20,15 +20,12 @@
 from webnotes.utils import cstr, flt
 from webnotes.model.doc import addchild
 from webnotes.model.bean import getlist
-from webnotes import msgprint
+from webnotes import msgprint, _
 
 sql = webnotes.conn.sql
 
-class DocType:
-	def __init__(self, doc, doclist=[]):
-		self.doc = doc
-		self.doclist = doclist
-
+from webnotes.model.controller import DocListController
+class DocType(DocListController):
 	def get_tax_rate(self, tax_type):
 		rate = sql("select tax_rate from tabAccount where name = %s", tax_type)
 		ret = {
@@ -196,6 +193,8 @@
 
 		if self.doc.name:
 			self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name')
+			
+		self.validate_is_stock_item()
 					
 	def check_non_asset_warehouse(self):
 		if self.doc.is_asset_item == "Yes":
@@ -215,6 +214,15 @@
 			'description'	:	file and file[0]['description'] or ''
 		}
 		return ret
+		
+	def validate_is_stock_item(self):
+		if not self.doc.fields.get("__islocal"):
+			if webnotes.conn.get_value("Item", self.doc.name, "is_stock_item")=="Yes" and \
+				((not self.doc.is_stock_item) or self.doc.is_stock_item == "No"):
+					if self.check_if_sle_exists() == "exists":
+						webnotes.msgprint(self.meta.get_label("is_stock_item") + ": " 
+							+ _("""Cannot change to Yes. Reason: Stock Ledger Entries exist for""")
+							+ """ "%s" """ % self.doc.name, raise_exception=True)
 
 	def check_if_sle_exists(self):
 		sle = sql("select name from `tabStock Ledger Entry` where item_code = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name)
diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py
index 12da0a6..cce1493 100644
--- a/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -125,7 +125,7 @@
 		self.update_raw_materials_supplied("pr_raw_material_details")
 		
 		self.update_valuation_rate("purchase_receipt_details")
-
+		
 	def on_update(self):
 		if self.doc.rejected_warehouse:
 			for d in getlist(self.doclist,'purchase_receipt_details'):
@@ -146,6 +146,9 @@
 		self.values = []
 		for d in getlist(self.doclist, 'purchase_receipt_details'):
 			if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes":
+				if not d.warehouse:
+					continue
+				
 				ord_qty = 0
 				pr_qty = flt(d.qty) * flt(d.conversion_factor)
 
diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js
index 55a86a3..ba1f648 100644
--- a/stock/doctype/stock_entry/stock_entry.js
+++ b/stock/doctype/stock_entry/stock_entry.js
@@ -19,7 +19,6 @@
 
 erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
 	onload_post_render: function() {
-		this._super();
 		if(this.frm.doc.__islocal && (this.frm.doc.production_order || this.frm.doc.bom_no) 
 			&& !getchildren('Stock Entry Detail', this.frm.doc.name, 'mtn_details').length) {
 				// if production order / bom is mentioned, get items
@@ -28,7 +27,7 @@
 	},
 	
 	refresh: function() {
-		this._super();
+		erpnext.hide_naming_series();
 		this.toggle_related_fields(this.frm.doc);
 		this.toggle_enable_bom();
 		if (this.frm.doc.docstatus==1) {
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index 278c283..74b71d9 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -29,9 +29,9 @@
 
 sql = webnotes.conn.sql
 	
-from utilities.transaction_base import TransactionBase
+from controllers.accounts_controller import AccountsController
 
-class DocType(TransactionBase):
+class DocType(AccountsController):
 	def __init__(self, doc, doclist=[]):
 		self.doc = doc
 		self.doclist = doclist
@@ -44,12 +44,14 @@
 		pro_obj = self.doc.production_order and \
 			get_obj('Production Order', self.doc.production_order) or None
 
+		self.validate_item()
 		self.validate_warehouse(pro_obj)
 		self.validate_production_order(pro_obj)
 		self.get_stock_and_rate()
 		self.validate_incoming_rate()
 		self.validate_bom()
 		self.validate_finished_goods()
+
 		self.validate_return_reference_doc()
 		
 		self.validate_with_material_request()
@@ -78,6 +80,12 @@
 		sl_obj.scrub_serial_nos(self)
 		sl_obj.validate_serial_no(self, 'mtn_details')
 		
+	def validate_item(self):
+		for item in self.doclist.get({"parentfield": "mtn_details"}):
+			if item.item_code not in self.stock_items:
+				msgprint(_("""Only Stock Items are allowed for Stock Entry"""),
+					raise_exception=True)
+		
 	def validate_warehouse(self, pro_obj):
 		"""perform various (sometimes conditional) validations on warehouse"""
 		
diff --git a/stock/utils.py b/stock/utils.py
index bc6054f..20d08ea 100644
--- a/stock/utils.py
+++ b/stock/utils.py
@@ -181,11 +181,13 @@
 def _get_buying_amount(voucher_type, voucher_no, item_row, item_code, warehouse, qty, 
 		stock_ledger_entries):
 	for i, sle in enumerate(stock_ledger_entries):
-		if sle.voucher_type == voucher_type and sle.voucher_no == voucher_no:
+		if sle.voucher_type == voucher_type and sle.voucher_no == voucher_no and \
+				len(stock_ledger_entries) > i+1:
 			if (sle.voucher_detail_no == item_row) or \
 				(sle.item_code == item_code and sle.warehouse == warehouse and \
 				abs(flt(sle.qty)) == qty):
-					buying_amount = flt(stock_ledger_entries[i+1].stock_value) - flt(sle.stock_value)
+					buying_amount = flt(stock_ledger_entries[i+1].stock_value) - \
+						flt(sle.stock_value)
 
 					return buying_amount