[stock] [minor] Added Warehouse User check in Sales Order
diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py
index a9bb7a2..ec2406f 100644
--- a/selling/doctype/sales_order/sales_order.py
+++ b/selling/doctype/sales_order/sales_order.py
@@ -126,8 +126,9 @@
 		self.validate_mandatory()
 		self.validate_proj_cust()
 		self.validate_po()
-		self.validate_uom_is_integer("stock_uom", "qty")		
+		self.validate_uom_is_integer("stock_uom", "qty")
 		self.validate_for_items()
+		self.validate_warehouse_user()
 		sales_com_obj = get_obj(dt = 'Sales Common')
 		sales_com_obj.check_active_sales_items(self)
 		sales_com_obj.check_conversion_rate(self)
@@ -147,6 +148,15 @@
 		if not self.doc.billing_status: self.doc.billing_status = 'Not Billed'
 		if not self.doc.delivery_status: self.doc.delivery_status = 'Not Delivered'
 		
+		
+	def validate_warehouse_user(self):
+		from stock.utils import validate_warehouse_user
+		
+		warehouses = list(set([d.reserved_warehouse for d in self.doclist.get({"doctype": self.tname})]))
+				
+		for w in warehouses:
+			validate_warehouse_user(w)
+		
 	def validate_with_previous_doc(self):
 		super(DocType, self).validate_with_previous_doc(self.tname, {
 			"Quotation": {
diff --git a/selling/doctype/sales_order/test_sales_order.py b/selling/doctype/sales_order/test_sales_order.py
index 9fd16e8..7b72271 100644
--- a/selling/doctype/sales_order/test_sales_order.py
+++ b/selling/doctype/sales_order/test_sales_order.py
@@ -272,6 +272,29 @@
 		self.check_reserved_qty(sbom_test_records[0][2]["item_code"], 
 			so.doclist[1].reserved_warehouse, 20.0)
 
+	def test_warehouse_user(self):
+		webnotes.session.user = "test@example.com"
+
+		webnotes.bean("Profile", "test@example.com").get_controller()\
+			.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
+			
+		webnotes.bean("Profile", "test2@example.com").get_controller()\
+			.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
+
+
+		from stock.utils import UserNotAllowedForWarehouse
+		so = webnotes.bean(copy = test_records[0])
+		so.doc.company = "_Test Company 1"
+		so.doc.conversion_rate = 0.02
+		so.doc.plc_conversion_rate = 0.02
+		so.doclist[1].reserved_warehouse = "_Test Warehouse 2 - _TC1"
+		self.assertRaises(UserNotAllowedForWarehouse, so.insert)
+
+		webnotes.session.user = "test2@example.com"
+		so.insert()
+
+		webnotes.session.user = "Administrator"
+
 test_dependencies = ["Sales BOM"]
 	
 test_records = [
diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py
index f33cfa3..b9b3230 100644
--- a/stock/doctype/stock_entry/test_stock_entry.py
+++ b/stock/doctype/stock_entry/test_stock_entry.py
@@ -41,11 +41,42 @@
 		webnotes.conn.set_default("company", self.old_default_company)
 
 	def test_warehouse_company_validation(self):
+		webnotes.session.user = "test2@example.com"
+		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
 		st1 = webnotes.bean(copy=test_records[0])
 		st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1"
 		st1.insert()
 		self.assertRaises(InvalidWarehouseCompany, st1.submit)
+		
+		webnotes.session.user = "Administrator"
+
+	def test_warehouse_user(self):
+		from stock.utils import UserNotAllowedForWarehouse
+
+		webnotes.session.user = "test@example.com"
+		webnotes.bean("Profile", "test@example.com").get_controller()\
+			.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
+
+		webnotes.bean("Profile", "test2@example.com").get_controller()\
+			.add_roles("Sales User", "Sales Manager", "Material User", "Material Manager")
+
+		st1 = webnotes.bean(copy=test_records[0])
+		st1.doc.company = "_Test Company 1"
+		st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1"
+		st1.insert()
+		self.assertRaises(UserNotAllowedForWarehouse, st1.submit)
+
+		webnotes.session.user = "test2@example.com"
+		st1 = webnotes.bean(copy=test_records[0])
+		st1.doc.company = "_Test Company 1"
+		st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1"
+		st1.insert()
+		st1.submit()
+		
+		webnotes.session.user = "Administrator"
 
 	def test_material_receipt_gl_entry(self):
 		webnotes.conn.sql("delete from `tabStock Ledger Entry`")
diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index 71d426f..58fc828 100644
--- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -25,12 +25,14 @@
 		self.doclist = doclist
 
 	def validate(self):
+		from stock.utils import validate_warehouse_user
 		if not hasattr(webnotes, "new_stock_ledger_entries"):
 			webnotes.new_stock_ledger_entries = []
+			
 		webnotes.new_stock_ledger_entries.append(self.doc)
 		self.validate_mandatory()
 		self.validate_item()
-		self.validate_warehouse_user()
+		validate_warehouse_user(self.doc.warehouse)
 		self.validate_warehouse_company()
 		self.actual_amt_check()
 		self.check_stock_frozen_date()
@@ -52,16 +54,6 @@
 
 			self.doc.fields.pop('batch_bal')
 			 
-	def validate_warehouse_user(self):
-		if webnotes.session.user=="Administrator":
-			return
-		warehouse_users = [p[0] for p in webnotes.conn.sql("""select user from `tabWarehouse User`
-			where parent=%s""", self.doc.warehouse)]
-			
-		if warehouse_users and not webnotes.session.user in warehouse_users:
-			webnotes.msgprint(_("User not allowed entry in the Warehouse") \
-				+ ": " + webnotes.session.user + " / " + self.doc.warehouse, raise_exception = 1)
-
 	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:
diff --git a/stock/doctype/warehouse/test_warehouse.py b/stock/doctype/warehouse/test_warehouse.py
index 4e47d56..ed72562 100644
--- a/stock/doctype/warehouse/test_warehouse.py
+++ b/stock/doctype/warehouse/test_warehouse.py
@@ -16,5 +16,9 @@
 		"doctype": "Warehouse",
 		"warehouse_name": "_Test Warehouse 2",
 		"company": "_Test Company 1"
+	}, {
+		"doctype": "Warehouse User",
+		"parentfield": "warehouse_users",
+		"user": "test2@example.com"
 	}]	
 ]
diff --git a/stock/utils.py b/stock/utils.py
index 5376342..f04b663 100644
--- a/stock/utils.py
+++ b/stock/utils.py
@@ -8,6 +8,8 @@
 from webnotes.defaults import get_global_default
 from webnotes.utils.email_lib import sendmail
 
+class UserNotAllowedForWarehouse(webnotes.ValidationError): pass
+
 def validate_end_of_life(item_code, end_of_life=None, verbose=1):
 	if not end_of_life:
 		end_of_life = webnotes.conn.get_value("Item", item_code, "end_of_life")
@@ -152,6 +154,16 @@
 				wlist.append([w])
 	return wlist
 
+def validate_warehouse_user(warehouse):
+	if webnotes.session.user=="Administrator":
+		return
+	warehouse_users = [p[0] for p in webnotes.conn.sql("""select user from `tabWarehouse User`
+		where parent=%s""", warehouse)]
+				
+	if warehouse_users and not (webnotes.session.user in warehouse_users):
+		webnotes.throw(_("Not allowed entry in Warehouse") \
+			+ ": " + warehouse, UserNotAllowedForWarehouse)
+
 def get_buying_amount(item_code, voucher_type, voucher_no, voucher_detail_no, 
 		stock_ledger_entries, item_sales_bom=None):
 	if item_sales_bom and item_sales_bom.get(item_code):