diff --git a/model_access_rights/__manifest__.py b/model_access_rights/__manifest__.py index 339615461..d9952bc8a 100644 --- a/model_access_rights/__manifest__.py +++ b/model_access_rights/__manifest__.py @@ -21,7 +21,7 @@ ############################################################################# { 'name': 'Hide Create|Delete|Archive|Export Options - Model Wise', - 'version': '17.0.1.0.0', + 'version': '17.0.2.0.0', 'category': 'Extra Tools, Productivity', 'summary': """ Can hide options from user """, 'description': """ By using this module we can hide the options like create, diff --git a/model_access_rights/doc/RELEASE_NOTES.md b/model_access_rights/doc/RELEASE_NOTES.md index f615a83b4..163cf448f 100644 --- a/model_access_rights/doc/RELEASE_NOTES.md +++ b/model_access_rights/doc/RELEASE_NOTES.md @@ -3,3 +3,10 @@ #### Version 17.0.1.0.0 ##### ADD - Initial Commit for Hide Create|Delete|Archive|Export Options - Model Wise + + +#### 13.07.2025 +#### Version 17.0.2.0.0 +#### UPDT + +- Added a new option to restrict model access rights for certain user. \ No newline at end of file diff --git a/model_access_rights/models/access_right.py b/model_access_rights/models/access_right.py index 062400fbb..c72b632cf 100644 --- a/model_access_rights/models/access_right.py +++ b/model_access_rights/models/access_right.py @@ -32,9 +32,10 @@ class ModelAccessRights(models.Model): _description = 'Manage Modules Access Control' _rec_name = 'model_id' - model_id = fields.Many2one('ir.model', ondelete='cascade', required=True, + model_id = fields.Many2one('ir.model', ondelete='cascade', + required=True, help="select the model") - groups_id = fields.Many2one('res.groups', required=True, + groups_id = fields.Many2one('res.groups', help="select the group") is_delete = fields.Boolean(string="Delete", help="hide the delete option") is_export = fields.Boolean(string="Export", @@ -45,6 +46,12 @@ class ModelAccessRights(models.Model): " as well as form view") is_archive = fields.Boolean(string="Archive/UnArchive", help="hide the archive option") + restriction_type = fields.Selection([ + ('user', 'User Wise'), + ('group', 'Group Wise') + ], 'Restriction Type',required=True,default="group") + user_id = fields.Many2one('res.users', + help="select the user") @api.model def hide_buttons(self): @@ -54,21 +61,29 @@ class ModelAccessRights(models.Model): 'is_export', 'is_create_or_update', 'is_archive', + 'restriction_type', + 'user_id', 'groups_id']) for dic in access_right_rec: model = self.env['ir.model'].sudo().browse(dic['model_id'][0]).model - group_name = self.env['ir.model.data'].sudo().search([ - ('model', '=', 'res.groups'), - ('res_id', '=', dic['groups_id'][0]) - ]).name + if dic['restriction_type'] == "group": + group_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', dic['groups_id'][0]) + ]).name - module_name = self.env['ir.model.data'].sudo().search([ - ('model', '=', 'res.groups'), - ('res_id', '=', dic['groups_id'][0]) - ]).module + module_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', dic['groups_id'][0]) + ]).module + else: + group_name=False + module_name=False dic.update({ 'model': model, 'group_name': group_name, - 'module': module_name + 'module': module_name, + 'restriction_type': dic['restriction_type'], + 'user': dic['user_id'] }) return access_right_rec diff --git a/model_access_rights/models/models.py b/model_access_rights/models/models.py index 9cc2247ac..c8a5e3e31 100644 --- a/model_access_rights/models/models.py +++ b/model_access_rights/models/models.py @@ -153,24 +153,33 @@ def _create(self, data_list): [('model', '=', self._name)]).id access_right_rec = self.env['access.right'].sudo().search_read( [('model_id', '=', current_model_id)], - ['model_id', 'is_create_or_update', + ['model_id', 'is_create_or_update','restriction_type','user_id', 'groups_id']) if access_right_rec and not self.env.is_admin(): for rec in access_right_rec: - group_name = self.env['ir.model.data'].sudo().search([ - ('model', '=', 'res.groups'), - ('res_id', '=', rec['groups_id'][0]) - ]).name - module_name = self.env['ir.model.data'].sudo().search([ - ('model', '=', 'res.groups'), - ('res_id', '=', rec['groups_id'][0]) - ]).module - group = module_name + "." + group_name - if self.env.user.has_group(group): - if rec['is_create_or_update']: - raise UserError('You are restricted from performing this' - ' operation. Please contact the' - ' administrator.') + if rec['restriction_type']=='group': + group_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', rec['groups_id'][0]) + ]).name + module_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', rec['groups_id'][0]) + ]).module + group = module_name + "." + group_name + if self.env.user.has_group(group): + if rec['is_create_or_update']: + raise UserError( + 'You are restricted from performing this' + ' operation. Please contact the' + ' administrator.') + if rec['restriction_type']=='user': + if self.env.user.id == rec['user_id'][0]: + if rec['is_create_or_update']: + raise UserError( + 'You are restricted from performing this' + ' operation. Please contact the' + ' administrator.') return records @@ -283,25 +292,34 @@ def unlink(self): [('model', '=', self._name)]).id access_right_rec = self.env['access.right'].sudo().search_read( [('model_id', '=', current_model_id)], ['model_id', 'is_delete', + 'restriction_type','user_id', 'groups_id']) if access_right_rec and not self.env.is_admin(): for rec in access_right_rec: - group_name = self.env['ir.model.data'].sudo().search([ - ('model', '=', 'res.groups'), - ('res_id', '=', rec['groups_id'][0]) - ]).name - module_name = self.env['ir.model.data'].sudo().search([ - ('model', '=', 'res.groups'), - ('res_id', '=', rec['groups_id'][0]) - ]).module - group = module_name + "." + group_name - if self.env.user.has_group(group): - if rec['is_delete']: - raise UserError(_('You are restricted from performing this' - ' operation. Please contact the' - ' administrator.')) + if rec['restriction_type'] == 'group': + group_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', rec['groups_id'][0]) + ]).name + module_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', rec['groups_id'][0]) + ]).module + group = module_name + "." + group_name + if self.env.user.has_group(group): + if rec['is_delete']: + raise UserError( + _('You are restricted from performing this' + ' operation. Please contact the' + ' administrator.')) + if rec['restriction_type']=='user': + if self.env.user.id == rec['user_id'][0]: + if rec['is_delete']: + raise UserError( + 'You are restricted from performing this' + ' operation. Please contact the' + ' administrator.') return True - BaseModel._create = _create BaseModel.unlink = unlink diff --git a/model_access_rights/static/src/views/form_controller.js b/model_access_rights/static/src/views/form_controller.js index 3156c362b..3439bc245 100644 --- a/model_access_rights/static/src/views/form_controller.js +++ b/model_access_rights/static/src/views/form_controller.js @@ -4,6 +4,7 @@ */ import { FormController} from "@web/views/form/form_controller"; import { patch} from "@web/core/utils/patch"; +import {useService} from "@web/core/utils/hooks"; const { onWillStart} = owl; patch(FormController.prototype,{ /** @@ -11,7 +12,8 @@ patch(FormController.prototype,{ */ setup() { super.setup(...arguments); - this.rpc = this.env.services.rpc + this.rpc = useService("rpc") + this.user = useService("user"); onWillStart(async () => { var self = this var result; @@ -22,16 +24,30 @@ patch(FormController.prototype,{ for (var i = 0; i < result.length; i++) { var group = result[i].module + "." + result[i].group_name if (self.props.resModel == result[i].model) { - if (await self.user.hasGroup(group)) { - if (!this.user.isAdmin) { - if (result[i].is_create_or_update) { - self.canCreate = false + if (result[i].restriction_type == "group") { + if (await self.user.hasGroup(group)) { + if (!this.user.isAdmin) { + if (result[i].is_create_or_update) { + self.canCreate = false + } + if (result[i].is_delete) { + this.archInfo.activeActions.delete = false + } } - if (result[i].is_delete) { - this.archInfo.activeActions.delete = false + } + } else { + if (await self.user.userId == result[i].user[0]) { + if (!this.user.isAdmin) { + if (result[i].is_create_or_update) { + self.canCreate = false + } + if (result[i].is_delete) { + this.archInfo.activeActions.delete = false + } } } } + } } }); diff --git a/model_access_rights/static/src/views/kanban_controller.js b/model_access_rights/static/src/views/kanban_controller.js index de65ac2a8..a7e81c9bf 100644 --- a/model_access_rights/static/src/views/kanban_controller.js +++ b/model_access_rights/static/src/views/kanban_controller.js @@ -4,6 +4,7 @@ */ import { KanbanController } from '@web/views/kanban/kanban_controller'; import { patch} from "@web/core/utils/patch"; +import {useService} from "@web/core/utils/hooks"; const {onWillStart} = owl; patch(KanbanController.prototype,{ /** @@ -11,7 +12,8 @@ patch(KanbanController.prototype,{ */ setup() { super.setup(...arguments); - this.rpc = this.env.services.rpc + this.rpc = useService("rpc") + this.user = useService("user"); onWillStart(async () => { var self = this var result; @@ -22,17 +24,32 @@ patch(KanbanController.prototype,{ for (var i = 0; i < result.length; i++) { var group = result[i].module + "." + result[i].group_name if (self.props.resModel == result[i].model) { - if (await self.model.user.hasGroup(group)) { - if (!self.model.user.isAdmin) { - if (result[i].is_create_or_update) { - self.props.archInfo.activeActions.create=false - self.props.archInfo.activeActions.edit=false + if (result[i].restriction_type == "group") { + if (await self.user.hasGroup(group)) { + if (!self.user.isAdmin) { + if (result[i].is_create_or_update) { + self.props.archInfo.activeActions.create = false + self.props.archInfo.activeActions.edit = false + } + if (result[i].is_delete) { + self.props.archInfo.activeActions.delete = false + } } - if (result[i].is_delete) { - self.props.archInfo.activeActions.delete=false + } + } else { + if (await self.user.userId == result[i].user[0]) { + if (!self.user.isAdmin) { + if (result[i].is_create_or_update) { + self.props.archInfo.activeActions.create = false + self.props.archInfo.activeActions.edit = false + } + if (result[i].is_delete) { + self.props.archInfo.activeActions.delete = false + } } } } + } } }); diff --git a/model_access_rights/static/src/views/list_controller.js b/model_access_rights/static/src/views/list_controller.js index 095f27f15..c8ded861e 100644 --- a/model_access_rights/static/src/views/list_controller.js +++ b/model_access_rights/static/src/views/list_controller.js @@ -4,6 +4,7 @@ */ import { ListController} from '@web/views/list/list_controller'; import { patch} from "@web/core/utils/patch"; +import { useService } from "@web/core/utils/hooks"; const {onWillStart} = owl; patch(ListController.prototype, { /** @@ -11,7 +12,8 @@ patch(ListController.prototype, { */ setup() { super.setup(...arguments); - this.rpc = this.env.services.rpc + this.rpc = useService("rpc") + this.user = useService("user"); onWillStart(async () => { var self = this var result; @@ -22,17 +24,34 @@ patch(ListController.prototype, { for (var i = 0; i < result.length; i++) { var group = result[i].module + "." + result[i].group_name if (self.props.resModel == result[i].model) { - if (await self.userService.hasGroup(group)) { - if (!this.userService.isAdmin) { - if (result[i].is_create_or_update) { - self.activeActions.create = false; + if (result[i].restriction_type == "group") { + if (await self.user.hasGroup(group)) { + if (!this.user.isAdmin) { + if (result[i].is_create_or_update) { + self.activeActions.create = false; + } + if (result[i].is_export) { + self.isExportEnable = false + self.isExportEnable = false + } + if (result[i].is_delete) { + self.activeActions.delete = false; + } } - if (result[i].is_export) { - self.isExportEnable = false - self.isExportEnable = false - } - if (result[i].is_delete) { - self.activeActions.delete = false; + } + } else { + if (await self.user.userId == result[i].user[0]) { + if (!this.user.isAdmin) { + if (result[i].is_create_or_update) { + self.activeActions.create = false; + } + if (result[i].is_export) { + self.isExportEnable = false + self.isExportEnable = false + } + if (result[i].is_delete) { + self.activeActions.delete = false; + } } } } diff --git a/model_access_rights/views/access_right_views.xml b/model_access_rights/views/access_right_views.xml index 945acf1af..6da800bb2 100644 --- a/model_access_rights/views/access_right_views.xml +++ b/model_access_rights/views/access_right_views.xml @@ -30,8 +30,14 @@ - - + + + +