From a65253b5d5b9a16815b1d3d2175436ba15ec6b3f Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 27 Aug 2013 10:32:56 +0530 Subject: [PATCH] [stock] [minor] Added Warehouse User check in Sales Order --- selling/doctype/sales_order/sales_order.py | 12 ++++++- .../doctype/sales_order/test_sales_order.py | 23 ++++++++++++++ stock/doctype/stock_entry/test_stock_entry.py | 31 +++++++++++++++++++ .../stock_ledger_entry/stock_ledger_entry.py | 14 ++------- stock/doctype/warehouse/test_warehouse.py | 4 +++ stock/utils.py | 12 +++++++ 6 files changed, 84 insertions(+), 12 deletions(-) diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py index a9bb7a2140..ec2406f051 100644 --- a/selling/doctype/sales_order/sales_order.py +++ b/selling/doctype/sales_order/sales_order.py @@ -126,8 +126,9 @@ class DocType(SellingController): 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 @@ class DocType(SellingController): 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 9fd16e8c29..7b72271bec 100644 --- a/selling/doctype/sales_order/test_sales_order.py +++ b/selling/doctype/sales_order/test_sales_order.py @@ -272,6 +272,29 @@ class TestSalesOrder(unittest.TestCase): 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 f33cfa35d3..b9b32306d8 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -41,11 +41,42 @@ class TestStockEntry(unittest.TestCase): 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 71d426f48e..58fc828f2d 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 @@ class DocType(DocListController): 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 @@ class DocType(DocListController): 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 4e47d5636b..ed72562078 100644 --- a/stock/doctype/warehouse/test_warehouse.py +++ b/stock/doctype/warehouse/test_warehouse.py @@ -16,5 +16,9 @@ test_records = [ "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 5376342979..f04b663236 100644 --- a/stock/utils.py +++ b/stock/utils.py @@ -8,6 +8,8 @@ from webnotes.utils import flt, cstr, nowdate, add_days, cint 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 @@ def get_warehouse_list(doctype, txt, searchfield, start, page_len, filters): 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):