From 03406aaea5a30bcbe926a50f0dfa34a6d15472c3 Mon Sep 17 00:00:00 2001 From: eLBati Date: Thu, 2 Jul 2020 17:13:14 +0200 Subject: [PATCH 1/2] ADD stock_picking_type_user_restriction --- .../stock_picking_type_user_restriction | 1 + .../setup.py | 6 +++ .../__init__.py | 1 + .../__manifest__.py | 28 ++++++++++ .../i18n/it.po | 42 +++++++++++++++ .../models/__init__.py | 1 + .../models/stock_picking_type.py | 10 ++++ .../readme/CONFIGURE.rst | 3 ++ .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 1 + .../security/ir.model.access.csv | 21 ++++++++ .../security/stock_security.xml | 40 ++++++++++++++ .../tests/__init__.py | 1 + .../test_picking_type_user_restriction.py | 54 +++++++++++++++++++ .../views/product_views.xml | 47 ++++++++++++++++ .../views/stock_inventory_views.xml | 16 ++++++ .../views/stock_menu_views.xml | 6 +++ .../views/stock_picking_type_views.xml | 14 +++++ .../views/stock_picking_views.xml | 22 ++++++++ .../views/stock_warehouse_views.xml | 6 +++ 20 files changed, 321 insertions(+) create mode 120000 setup/stock_picking_type_user_restriction/odoo/addons/stock_picking_type_user_restriction create mode 100644 setup/stock_picking_type_user_restriction/setup.py create mode 100644 stock_picking_type_user_restriction/__init__.py create mode 100644 stock_picking_type_user_restriction/__manifest__.py create mode 100644 stock_picking_type_user_restriction/i18n/it.po create mode 100644 stock_picking_type_user_restriction/models/__init__.py create mode 100644 stock_picking_type_user_restriction/models/stock_picking_type.py create mode 100644 stock_picking_type_user_restriction/readme/CONFIGURE.rst create mode 100644 stock_picking_type_user_restriction/readme/CONTRIBUTORS.rst create mode 100644 stock_picking_type_user_restriction/readme/DESCRIPTION.rst create mode 100644 stock_picking_type_user_restriction/security/ir.model.access.csv create mode 100644 stock_picking_type_user_restriction/security/stock_security.xml create mode 100644 stock_picking_type_user_restriction/tests/__init__.py create mode 100644 stock_picking_type_user_restriction/tests/test_picking_type_user_restriction.py create mode 100644 stock_picking_type_user_restriction/views/product_views.xml create mode 100644 stock_picking_type_user_restriction/views/stock_inventory_views.xml create mode 100644 stock_picking_type_user_restriction/views/stock_menu_views.xml create mode 100644 stock_picking_type_user_restriction/views/stock_picking_type_views.xml create mode 100644 stock_picking_type_user_restriction/views/stock_picking_views.xml create mode 100644 stock_picking_type_user_restriction/views/stock_warehouse_views.xml diff --git a/setup/stock_picking_type_user_restriction/odoo/addons/stock_picking_type_user_restriction b/setup/stock_picking_type_user_restriction/odoo/addons/stock_picking_type_user_restriction new file mode 120000 index 000000000..69237dfa0 --- /dev/null +++ b/setup/stock_picking_type_user_restriction/odoo/addons/stock_picking_type_user_restriction @@ -0,0 +1 @@ +../../../../stock_picking_type_user_restriction \ No newline at end of file diff --git a/setup/stock_picking_type_user_restriction/setup.py b/setup/stock_picking_type_user_restriction/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/stock_picking_type_user_restriction/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_picking_type_user_restriction/__init__.py b/stock_picking_type_user_restriction/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/stock_picking_type_user_restriction/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_picking_type_user_restriction/__manifest__.py b/stock_picking_type_user_restriction/__manifest__.py new file mode 100644 index 000000000..c9bada267 --- /dev/null +++ b/stock_picking_type_user_restriction/__manifest__.py @@ -0,0 +1,28 @@ +# Copyright 2020 Lorenzo Battistini @ TAKOBI +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). +{ + "name": "Stock picking type - Restrict users", + "summary": "Restrict some users to see and use only certain picking types", + "version": "12.0.1.0.0", + "development_status": "Beta", + "category": "Warehouse", + "website": "https://github.com/OCA/stock-logistics-warehouse", + "author": "TAKOBI, Odoo Community Association (OCA)", + "maintainers": ["eLBati"], + "license": "LGPL-3", + "application": False, + "installable": True, + "depends": [ + "stock", + ], + "data": [ + "security/stock_security.xml", + "views/stock_picking_type_views.xml", + "security/ir.model.access.csv", + "views/stock_menu_views.xml", + "views/product_views.xml", + "views/stock_inventory_views.xml", + "views/stock_picking_views.xml", + "views/stock_warehouse_views.xml", + ], +} diff --git a/stock_picking_type_user_restriction/i18n/it.po b/stock_picking_type_user_restriction/i18n/it.po new file mode 100644 index 000000000..7073e1a90 --- /dev/null +++ b/stock_picking_type_user_restriction/i18n/it.po @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_picking_type_user_restriction +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-07-07 04:53+0000\n" +"PO-Revision-Date: 2020-07-07 04:53+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: stock_picking_type_user_restriction +#: model:ir.model.fields,field_description:stock_picking_type_user_restriction.field_stock_picking_type__assigned_user_ids +msgid "Assigned users" +msgstr "Utenti assegnati" + +#. module: stock_picking_type_user_restriction +#: model:ir.model,name:stock_picking_type_user_restriction.model_stock_picking_type +msgid "Picking Type" +msgstr "Tipo di prelievo" + +#. module: stock_picking_type_user_restriction +#: model:ir.model.fields,help:stock_picking_type_user_restriction.field_stock_picking_type__assigned_user_ids +msgid "Restrict some users to only access their assigned operation types. In order to apply the restriction, the user needs the 'User: Assigned Operation Types Only' group" +msgstr "Limitare alcuni utenti ad accedere solamente ai loro tipi di operazioni assegnati. Per applicare la restrizione, l'utente necessita il gruppo 'Utente: solamente tipi di operazioni assegnati'" + +#. module: stock_picking_type_user_restriction +#: model:res.groups,comment:stock_picking_type_user_restriction.group_assigned_picking_types_user +msgid "The user will have access to her assigned operation types." +msgstr "L'utente avrà accesso ai propri tipi di operazioni assegnati." + +#. module: stock_picking_type_user_restriction +#: model:res.groups,name:stock_picking_type_user_restriction.group_assigned_picking_types_user +msgid "User: Assigned Operation Types Only" +msgstr "Utente: solamente tipi di operazioni assegnati" + diff --git a/stock_picking_type_user_restriction/models/__init__.py b/stock_picking_type_user_restriction/models/__init__.py new file mode 100644 index 000000000..576c033a6 --- /dev/null +++ b/stock_picking_type_user_restriction/models/__init__.py @@ -0,0 +1 @@ +from . import stock_picking_type diff --git a/stock_picking_type_user_restriction/models/stock_picking_type.py b/stock_picking_type_user_restriction/models/stock_picking_type.py new file mode 100644 index 000000000..1db96f4ec --- /dev/null +++ b/stock_picking_type_user_restriction/models/stock_picking_type.py @@ -0,0 +1,10 @@ +from odoo import models, fields + + +class PickingType(models.Model): + _inherit = 'stock.picking.type' + assigned_user_ids = fields.Many2many( + "res.users", string="Assigned users", + help="Restrict some users to only access their assigned operation types. " + "In order to apply the restriction, the user needs the " + "'User: Assigned Operation Types Only' group") diff --git a/stock_picking_type_user_restriction/readme/CONFIGURE.rst b/stock_picking_type_user_restriction/readme/CONFIGURE.rst new file mode 100644 index 000000000..db8a7267f --- /dev/null +++ b/stock_picking_type_user_restriction/readme/CONFIGURE.rst @@ -0,0 +1,3 @@ +With a Stock Manager, open an operation type (picking type) and set "Assigned users" field. + +Then, assign "User: Assigned Operation Types Only" group to users who should be able to access to their assigned operation types only. diff --git a/stock_picking_type_user_restriction/readme/CONTRIBUTORS.rst b/stock_picking_type_user_restriction/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..b27b50b50 --- /dev/null +++ b/stock_picking_type_user_restriction/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Lorenzo Battistini (https://takobi.online) diff --git a/stock_picking_type_user_restriction/readme/DESCRIPTION.rst b/stock_picking_type_user_restriction/readme/DESCRIPTION.rst new file mode 100644 index 000000000..04c2bc7c6 --- /dev/null +++ b/stock_picking_type_user_restriction/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Restrict some users to only access their assigned operation types. diff --git a/stock_picking_type_user_restriction/security/ir.model.access.csv b/stock_picking_type_user_restriction/security/ir.model.access.csv new file mode 100644 index 000000000..3d9ab7c5d --- /dev/null +++ b/stock_picking_type_user_restriction/security/ir.model.access.csv @@ -0,0 +1,21 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_stock_picking_user,stock.picking user,stock.model_stock_picking,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,1,1,1 +access_stock_picking_type_user,stock.picking.type user,stock.model_stock_picking_type,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,0,0,0 +access_stock_production_lot_user,stock.production.lot user,stock.model_stock_production_lot,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,1,1,1 +access_stock_move_user,stock.move user,stock.model_stock_move,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,1,1,0 +access_stock_inventory_user,stock.inventory user,stock.model_stock_inventory,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,1,1,0 +access_stock_inventory_line_user,stock.inventory.line user,stock.model_stock_inventory_line,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,1,1,0 +access_product_product_stock_user,product_product_stock_user,product.model_product_product,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,0,0,0 +access_product_template_stock_user,product.template stock user,product.model_product_template,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,0,0,0 +access_stock_warehouse_orderpoint,stock.warehouse.orderpoint,stock.model_stock_warehouse_orderpoint,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,0,0,0 +access_stock_quant_user,stock.quant user,stock.model_stock_quant,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,0,0,0 +access_stock_quant_package_stock_user,stock.quant.package stock user,stock.model_stock_quant_package,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,1,1,1 +access_stock_package_level_stock_user,stock.package_level stock user,stock.model_stock_package_level,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,1,1,1 +access_stock_rule_user,stock_rule user,stock.model_stock_rule,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,0,0,0 +access_stock_move_line_user,stock.move.line user,stock.model_stock_move_line,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,1,1,1 +access_stock_fixed_putaway_user,stock_fixed_putaway_strat user,stock.model_stock_fixed_putaway_strat,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,0,0,0 +access_product_price_history_stock_user,prices.history stock user,product.model_product_price_history,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,0,0,0 +access_barcode_nomenclature_stock_user,barcode.nomenclature.stock.user,barcodes.model_barcode_nomenclature,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,0,0,0 +access_barcode_rule_stock_user,barcode.rule.stock.user,barcodes.model_barcode_rule,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,0,0,0 +access_stock_forecast_user,report.stock.forecast.user,stock.model_report_stock_forecast,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,0,0,0 +access_stock_scrap_user,stock.scrap.user,stock.model_stock_scrap,stock_picking_type_user_restriction.group_assigned_picking_types_user,1,1,1,0 diff --git a/stock_picking_type_user_restriction/security/stock_security.xml b/stock_picking_type_user_restriction/security/stock_security.xml new file mode 100644 index 000000000..f182b9ae3 --- /dev/null +++ b/stock_picking_type_user_restriction/security/stock_security.xml @@ -0,0 +1,40 @@ + + + + User: Assigned Operation Types Only + + The user will have access to her assigned operation types. + + + + + + + + Assigned picking types + + ['|',('assigned_user_ids','in',user.id),('assigned_user_ids','=',False)] + + + + Assigned pickings + + ['|',('picking_type_id.assigned_user_ids','in',user.id),('picking_type_id.assigned_user_ids','=',False)] + + + + + All picking types + + [(1,'=',1)] + + + + All pickings + + [(1,'=',1)] + + + + + diff --git a/stock_picking_type_user_restriction/tests/__init__.py b/stock_picking_type_user_restriction/tests/__init__.py new file mode 100644 index 000000000..c387ebd40 --- /dev/null +++ b/stock_picking_type_user_restriction/tests/__init__.py @@ -0,0 +1 @@ +from . import test_picking_type_user_restriction diff --git a/stock_picking_type_user_restriction/tests/test_picking_type_user_restriction.py b/stock_picking_type_user_restriction/tests/test_picking_type_user_restriction.py new file mode 100644 index 000000000..14dabe8a4 --- /dev/null +++ b/stock_picking_type_user_restriction/tests/test_picking_type_user_restriction.py @@ -0,0 +1,54 @@ +from odoo.tests.common import TransactionCase + + +class TestUserRestriction(TransactionCase): + + def setUp(self): + super(TestUserRestriction, self).setUp() + self.stock_user = self.env['res.users'].create({ + 'login': 'stock_user', + 'name': 'stock_user', + 'groups_id': [(6, 0, [self.env.ref('stock.group_stock_user').id])] + }) + self.stock_user_assigned_type = self.env['res.users'].create({ + 'login': 'stock_user_assigned_type', + 'name': 'stock_user_assigned_type', + 'groups_id': [(6, 0, [self.env.ref( + 'stock_picking_type_user_restriction.' + 'group_assigned_picking_types_user' + ).id])] + }) + self.picking_type_out = self.env.ref('stock.picking_type_out') + self.picking_type_model = self.env['stock.picking.type'] + + def test_access_picking_type(self): + # assigned_user_ids is not set: both users can read + pick_types = self.picking_type_model.sudo(self.stock_user.id).search([ + ('name', '=', 'Delivery Orders')]) + self.assertTrue(self.picking_type_out in pick_types) + pick_types = self.picking_type_model.sudo( + self.stock_user_assigned_type.id).search([ + ('name', '=', 'Delivery Orders')]) + self.assertTrue(self.picking_type_out in pick_types) + + self.picking_type_out.assigned_user_ids = [ + (6, 0, [self.stock_user_assigned_type.id])] + # assigned_user_ids is set with stock_user_assigned_type: both users can read + pick_types = self.picking_type_model.sudo(self.stock_user.id).search([ + ('name', '=', 'Delivery Orders')]) + self.assertTrue(self.picking_type_out in pick_types) + pick_types = self.picking_type_model.sudo( + self.stock_user_assigned_type.id).search([ + ('name', '=', 'Delivery Orders')]) + self.assertTrue(self.picking_type_out in pick_types) + + self.picking_type_out.assigned_user_ids = [ + (6, 0, [self.stock_user.id])] + # assigned_user_ids is set with stock_user: only stock_user can read + pick_types = self.picking_type_model.sudo(self.stock_user.id).search([ + ('name', '=', 'Delivery Orders')]) + self.assertTrue(self.picking_type_out in pick_types) + pick_types = self.picking_type_model.sudo( + self.stock_user_assigned_type.id).search([ + ('name', '=', 'Delivery Orders')]) + self.assertFalse(self.picking_type_out in pick_types) diff --git a/stock_picking_type_user_restriction/views/product_views.xml b/stock_picking_type_user_restriction/views/product_views.xml new file mode 100644 index 000000000..0415d7afc --- /dev/null +++ b/stock_picking_type_user_restriction/views/product_views.xml @@ -0,0 +1,47 @@ + + + + view_template_property_form_assigned_users + product.template + + + + stock.group_stock_user,product.group_stock_packaging,stock_picking_type_user_restriction.group_assigned_picking_types_user + + + + + + + + + product_form_view_procurement_button_assigned_users + product.product + + + + stock.group_stock_user,stock_picking_type_user_restriction.group_assigned_picking_types_user + + + stock.group_stock_user,stock_picking_type_user_restriction.group_assigned_picking_types_user + + + + + + + + + product_template_form_view_procurement_button_assigned_users + product.product + + + + stock.group_stock_user,stock_picking_type_user_restriction.group_assigned_picking_types_user + + + stock.group_stock_user,stock_picking_type_user_restriction.group_assigned_picking_types_user + + + + diff --git a/stock_picking_type_user_restriction/views/stock_inventory_views.xml b/stock_picking_type_user_restriction/views/stock_inventory_views.xml new file mode 100644 index 000000000..38cba6f8c --- /dev/null +++ b/stock_picking_type_user_restriction/views/stock_inventory_views.xml @@ -0,0 +1,16 @@ + + + + view_inventory_form_assigned_users + stock.inventory + + + + stock.group_stock_user,stock_picking_type_user_restriction.group_assigned_picking_types_user + + + stock.group_stock_user,stock_picking_type_user_restriction.group_assigned_picking_types_user + + + + diff --git a/stock_picking_type_user_restriction/views/stock_menu_views.xml b/stock_picking_type_user_restriction/views/stock_menu_views.xml new file mode 100644 index 000000000..0541649c7 --- /dev/null +++ b/stock_picking_type_user_restriction/views/stock_menu_views.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/stock_picking_type_user_restriction/views/stock_picking_type_views.xml b/stock_picking_type_user_restriction/views/stock_picking_type_views.xml new file mode 100644 index 000000000..1ae4f43f9 --- /dev/null +++ b/stock_picking_type_user_restriction/views/stock_picking_type_views.xml @@ -0,0 +1,14 @@ + + + + view_picking_type_form_assigned_users + stock.picking.type + + + + + + + + diff --git a/stock_picking_type_user_restriction/views/stock_picking_views.xml b/stock_picking_type_user_restriction/views/stock_picking_views.xml new file mode 100644 index 000000000..9700a7c46 --- /dev/null +++ b/stock_picking_type_user_restriction/views/stock_picking_views.xml @@ -0,0 +1,22 @@ + + + + view_picking_form_assigned_users + stock.picking + + + + stock.group_stock_user,stock_picking_type_user_restriction.group_assigned_picking_types_user + + + stock.group_stock_user,stock_picking_type_user_restriction.group_assigned_picking_types_user + + + stock.group_stock_user,stock_picking_type_user_restriction.group_assigned_picking_types_user + + + + + + + diff --git a/stock_picking_type_user_restriction/views/stock_warehouse_views.xml b/stock_picking_type_user_restriction/views/stock_warehouse_views.xml new file mode 100644 index 000000000..a0f984c81 --- /dev/null +++ b/stock_picking_type_user_restriction/views/stock_warehouse_views.xml @@ -0,0 +1,6 @@ + + + + + + From db5e69cc8d97357b65be01dfa326f15ebb69328a Mon Sep 17 00:00:00 2001 From: Lorenzo Battistini Date: Mon, 20 Jul 2020 06:40:17 +0200 Subject: [PATCH 2/2] never create users in tests w/out no_reset_password (it generates emails for pwd!) and when possible use tracking_disable and SavepointCase Co-authored-by: Simone Orsi --- .../test_picking_type_user_restriction.py | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/stock_picking_type_user_restriction/tests/test_picking_type_user_restriction.py b/stock_picking_type_user_restriction/tests/test_picking_type_user_restriction.py index 14dabe8a4..f296d7dbc 100644 --- a/stock_picking_type_user_restriction/tests/test_picking_type_user_restriction.py +++ b/stock_picking_type_user_restriction/tests/test_picking_type_user_restriction.py @@ -1,25 +1,31 @@ -from odoo.tests.common import TransactionCase +from odoo.tests.common import SavepointCase -class TestUserRestriction(TransactionCase): +class TestUserRestriction(SavepointCase): - def setUp(self): - super(TestUserRestriction, self).setUp() - self.stock_user = self.env['res.users'].create({ + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict( + cls.env.context, + tracking_disable=True, + no_reset_password=True, + )) + cls.stock_user = cls.env['res.users'].create({ 'login': 'stock_user', 'name': 'stock_user', - 'groups_id': [(6, 0, [self.env.ref('stock.group_stock_user').id])] + 'groups_id': [(6, 0, [cls.env.ref('stock.group_stock_user').id])] }) - self.stock_user_assigned_type = self.env['res.users'].create({ + cls.stock_user_assigned_type = cls.env['res.users'].create({ 'login': 'stock_user_assigned_type', 'name': 'stock_user_assigned_type', - 'groups_id': [(6, 0, [self.env.ref( + 'groups_id': [(6, 0, [cls.env.ref( 'stock_picking_type_user_restriction.' 'group_assigned_picking_types_user' ).id])] }) - self.picking_type_out = self.env.ref('stock.picking_type_out') - self.picking_type_model = self.env['stock.picking.type'] + cls.picking_type_out = cls.env.ref('stock.picking_type_out') + cls.picking_type_model = cls.env['stock.picking.type'] def test_access_picking_type(self): # assigned_user_ids is not set: both users can read