first commit
This commit is contained in:
commit
6601b57833
38
README.md
Normal file
38
README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Access Restriction By User
|
||||
|
||||
This module allows administrators to restrict user access to specific records in Inventory, Manufacturing, and Approvals without using complex Record Rules.
|
||||
|
||||
## Features
|
||||
|
||||
Restrict visibility of the following records based on User configuration:
|
||||
* **Warehouses** (`stock.warehouse`)
|
||||
* **Picking Types** (`stock.picking.type`)
|
||||
* **Locations** (`stock.location`)
|
||||
* **Work Centers** (`mrp.workcenter`)
|
||||
* **Approval Categories** (`approval.category`)
|
||||
|
||||
## Configuration
|
||||
|
||||
1. Navigate to **Settings > Users & Companies > Users**.
|
||||
2. Select the user you want to restrict.
|
||||
3. Go to the **Access Restrictions** tab.
|
||||
4. Add records to the following fields:
|
||||
* **Allowed Warehouses**
|
||||
* **Allowed Picking Types**
|
||||
* **Allowed Locations**
|
||||
* **Allowed Work Centers**
|
||||
* **Allowed Approvals**
|
||||
|
||||
## Important Usage Notes
|
||||
|
||||
* **Empty List = Unrestricted**: If an "Allowed" field is left empty for a user, they will have access to **ALL** records of that type.
|
||||
* **Populated List = Restricted**: If one or more records are added, the user will **ONLY** see those specific records.
|
||||
* **Superuser**: The Superuser (OdooBot) and administrators bypassing access rights are not affected by these restrictions.
|
||||
|
||||
## Technical Details
|
||||
|
||||
This module overrides the `_search` method on the target models to apply a domain filter based on the current user's allowed list. This ensures consistency across views (list, kanban, many2one dropdowns) and avoids common issues associated with Record Rules.
|
||||
|
||||
## Author
|
||||
|
||||
Suherdy Yacob
|
||||
1
__init__.py
Normal file
1
__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from . import models
|
||||
26
__manifest__.py
Normal file
26
__manifest__.py
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
'name': 'Access Restriction By User',
|
||||
'version': '18.0.1.0.0',
|
||||
'summary': 'Restrict access to Warehouses, Picking Types, Locations, Work Centers, and Approvals by User',
|
||||
'description': """
|
||||
Restricts visibility of:
|
||||
- Warehouses
|
||||
- Picking Types
|
||||
- Locations
|
||||
- Work Centers
|
||||
- Approval Categories
|
||||
|
||||
Files are filtered based on "Allowed" lists in the User Settings.
|
||||
If the allowed list is empty, the user sees all records (default behavior).
|
||||
Does NOT use Record Rules.
|
||||
""",
|
||||
'category': 'Extra Tools',
|
||||
'author': 'Suherdy Yacob',
|
||||
'depends': ['base', 'stock', 'mrp', 'approvals'],
|
||||
'data': [
|
||||
'views/res_users_views.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'application': False,
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
BIN
__pycache__/__init__.cpython-312.pyc
Normal file
BIN
__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
2
models/__init__.py
Normal file
2
models/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
from . import res_users
|
||||
from . import restricted_models
|
||||
BIN
models/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
models/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/res_users.cpython-312.pyc
Normal file
BIN
models/__pycache__/res_users.cpython-312.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/restricted_models.cpython-312.pyc
Normal file
BIN
models/__pycache__/restricted_models.cpython-312.pyc
Normal file
Binary file not shown.
49
models/res_users.py
Normal file
49
models/res_users.py
Normal file
@ -0,0 +1,49 @@
|
||||
from odoo import models, fields
|
||||
|
||||
class ResUsers(models.Model):
|
||||
_inherit = 'res.users'
|
||||
|
||||
allowed_warehouse_ids = fields.Many2many(
|
||||
'stock.warehouse',
|
||||
'res_users_stock_warehouse_rel',
|
||||
'user_id',
|
||||
'warehouse_id',
|
||||
string="Allowed Warehouses",
|
||||
help="Warehouses this user is allowed to access. Leave empty to allow all."
|
||||
)
|
||||
|
||||
allowed_picking_type_ids = fields.Many2many(
|
||||
'stock.picking.type',
|
||||
'res_users_stock_picking_type_rel',
|
||||
'user_id',
|
||||
'picking_type_id',
|
||||
string="Allowed Picking Types",
|
||||
help="Picking Types this user is allowed to access. Leave empty to allow all."
|
||||
)
|
||||
|
||||
allowed_location_ids = fields.Many2many(
|
||||
'stock.location',
|
||||
'res_users_stock_location_rel',
|
||||
'user_id',
|
||||
'location_id',
|
||||
string="Allowed Locations",
|
||||
help="Locations this user is allowed to access. Leave empty to allow all."
|
||||
)
|
||||
|
||||
allowed_workcenter_ids = fields.Many2many(
|
||||
'mrp.workcenter',
|
||||
'res_users_mrp_workcenter_rel',
|
||||
'user_id',
|
||||
'workcenter_id',
|
||||
string="Allowed Work Centers",
|
||||
help="Work Centers this user is allowed to access. Leave empty to allow all."
|
||||
)
|
||||
|
||||
allowed_approval_category_ids = fields.Many2many(
|
||||
'approval.category',
|
||||
'res_users_approval_category_rel',
|
||||
'user_id',
|
||||
'category_id',
|
||||
string="Allowed Approvals",
|
||||
help="Approval Categories this user is allowed to access. Leave empty to allow all."
|
||||
)
|
||||
47
models/restricted_models.py
Normal file
47
models/restricted_models.py
Normal file
@ -0,0 +1,47 @@
|
||||
from odoo import models, api
|
||||
from odoo.osv import expression
|
||||
|
||||
class StockWarehouse(models.Model):
|
||||
_inherit = 'stock.warehouse'
|
||||
|
||||
@api.model
|
||||
def _search(self, domain, offset=0, limit=None, order=None):
|
||||
if not self.env.su and self.env.user.allowed_warehouse_ids:
|
||||
domain = expression.AND([domain or [], [('id', 'in', self.env.user.allowed_warehouse_ids.ids)]])
|
||||
return super()._search(domain, offset=offset, limit=limit, order=order)
|
||||
|
||||
class StockPickingType(models.Model):
|
||||
_inherit = 'stock.picking.type'
|
||||
|
||||
@api.model
|
||||
def _search(self, domain, offset=0, limit=None, order=None):
|
||||
if not self.env.su and self.env.user.allowed_picking_type_ids:
|
||||
domain = expression.AND([domain or [], [('id', 'in', self.env.user.allowed_picking_type_ids.ids)]])
|
||||
return super()._search(domain, offset=offset, limit=limit, order=order)
|
||||
|
||||
class StockLocation(models.Model):
|
||||
_inherit = 'stock.location'
|
||||
|
||||
@api.model
|
||||
def _search(self, domain, offset=0, limit=None, order=None):
|
||||
if not self.env.su and self.env.user.allowed_location_ids:
|
||||
domain = expression.AND([domain or [], [('id', 'in', self.env.user.allowed_location_ids.ids)]])
|
||||
return super()._search(domain, offset=offset, limit=limit, order=order)
|
||||
|
||||
class MrpWorkcenter(models.Model):
|
||||
_inherit = 'mrp.workcenter'
|
||||
|
||||
@api.model
|
||||
def _search(self, domain, offset=0, limit=None, order=None):
|
||||
if not self.env.su and self.env.user.allowed_workcenter_ids:
|
||||
domain = expression.AND([domain or [], [('id', 'in', self.env.user.allowed_workcenter_ids.ids)]])
|
||||
return super()._search(domain, offset=offset, limit=limit, order=order)
|
||||
|
||||
class ApprovalCategory(models.Model):
|
||||
_inherit = 'approval.category'
|
||||
|
||||
@api.model
|
||||
def _search(self, domain, offset=0, limit=None, order=None):
|
||||
if not self.env.su and self.env.user.allowed_approval_category_ids:
|
||||
domain = expression.AND([domain or [], [('id', 'in', self.env.user.allowed_approval_category_ids.ids)]])
|
||||
return super()._search(domain, offset=offset, limit=limit, order=order)
|
||||
25
views/res_users_views.xml
Normal file
25
views/res_users_views.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_users_form_inherit_access_restriction" model="ir.ui.view">
|
||||
<field name="name">res.users.form.inherit.access.restriction</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="inherit_id" ref="base.view_users_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<notebook position="inside">
|
||||
<page string="Access Restrictions" name="access_restrictions">
|
||||
<group>
|
||||
<group string="Inventory">
|
||||
<field name="allowed_warehouse_ids" widget="many2many_tags"/>
|
||||
<field name="allowed_picking_type_ids" widget="many2many_tags"/>
|
||||
<field name="allowed_location_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
<group string="Manufacturing & others">
|
||||
<field name="allowed_workcenter_ids" widget="many2many_tags"/>
|
||||
<field name="allowed_approval_category_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Loading…
Reference in New Issue
Block a user