diff --git a/model_access_rights/__manifest__.py b/model_access_rights/__manifest__.py index 5f4729d9c..436be8c47 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': '16.0.1.0.0', + 'version': '16.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 28c2ff2aa..41b1c1629 100644 --- a/model_access_rights/doc/RELEASE_NOTES.md +++ b/model_access_rights/doc/RELEASE_NOTES.md @@ -3,3 +3,10 @@ #### Version 16.0.1.0.0 ##### ADD - Initial Commit for Hide Create|Delete|Archive|Export Options - Model Wise + + +#### 14.07.2025 +#### Version 16.0.2.0.0 +#### UPDT + +- Added a new option to restrict model access rights for certain user. diff --git a/model_access_rights/models/model_access_rights.py b/model_access_rights/models/model_access_rights.py index 57924f7b6..3e82f425d 100644 --- a/model_access_rights/models/model_access_rights.py +++ b/model_access_rights/models/model_access_rights.py @@ -21,7 +21,7 @@ # If not, see . # ############################################################################# -from odoo import api, fields, models, _ +from odoo import api, fields, models class ModelAccessRights(models.Model): @@ -34,7 +34,7 @@ class ModelAccessRights(models.Model): 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 +45,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 +60,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 e2de02967..bff549c28 100644 --- a/model_access_rights/models/models.py +++ b/model_access_rights/models/models.py @@ -166,24 +166,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 @@ -291,23 +300,33 @@ 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 diff --git a/model_access_rights/static/description/assets/screenshots/model_access_right_03.png b/model_access_rights/static/description/assets/screenshots/model_access_right_03.png index ee165e8f7..ffed6bbb1 100644 Binary files a/model_access_rights/static/description/assets/screenshots/model_access_right_03.png and b/model_access_rights/static/description/assets/screenshots/model_access_right_03.png differ diff --git a/model_access_rights/static/description/assets/screenshots/model_access_right_07.png b/model_access_rights/static/description/assets/screenshots/model_access_right_07.png index 3bd2812d6..2d8e07333 100644 Binary files a/model_access_rights/static/description/assets/screenshots/model_access_right_07.png and b/model_access_rights/static/description/assets/screenshots/model_access_right_07.png differ diff --git a/model_access_rights/static/description/index.html b/model_access_rights/static/description/index.html index 3d68168a1..2f60b5f4b 100644 --- a/model_access_rights/static/description/index.html +++ b/model_access_rights/static/description/index.html @@ -109,7 +109,7 @@
By using this module we can hide the options like create,delete,export,and archive/un archive in the model - which we want. Here we are also able to select the user groups except Administrator which we want to apply the + which we want. Here we are also able to select the user groups or user except Administrator which we want to apply the above hiding functionality
@@ -137,6 +137,10 @@ Can hide the options for specific user group +
+ + Can hide the options for specific user +
No additional configuration needed @@ -169,7 +173,7 @@
-

Select the Model, Groups and the options which we want to hide

+

Select the Model, Restriction Type, Groups or user and the options which we want to hide

diff --git a/model_access_rights/static/src/js/form_controller.js b/model_access_rights/static/src/js/form_controller.js index a4ccd3964..b153b3904 100644 --- a/model_access_rights/static/src/js/form_controller.js +++ b/model_access_rights/static/src/js/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"; var rpc = require('web.rpc'); const { onWillStart} = owl; patch(FormController.prototype, 'model_access_rights/static/src/js/form_controller.js.FormController', { @@ -12,6 +13,7 @@ patch(FormController.prototype, 'model_access_rights/static/src/js/form_controll */ setup() { this._super(); + this.user = useService("user"); onWillStart(async () => { var self = this var result; @@ -24,18 +26,26 @@ patch(FormController.prototype, 'model_access_rights/static/src/js/form_controll 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 - } - if (result[i].is_archive) { - self.archiveEnabled = false - } else { - self.archiveEnabled = true; + } + } 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/js/kanban_controller.js b/model_access_rights/static/src/js/kanban_controller.js index 72f3a29e7..728a56645 100644 --- a/model_access_rights/static/src/js/kanban_controller.js +++ b/model_access_rights/static/src/js/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"; var rpc = require('web.rpc'); const {onWillStart} = owl; patch(KanbanController.prototype, 'model_access_rights/static/src/js/list_controller.js.KanbanController', { @@ -12,6 +13,7 @@ patch(KanbanController.prototype, 'model_access_rights/static/src/js/list_contro */ setup() { this._super(); + this.user = useService("user"); onWillStart(async () => { var self = this var result; @@ -24,14 +26,28 @@ patch(KanbanController.prototype, 'model_access_rights/static/src/js/list_contro 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/js/list_controller.js b/model_access_rights/static/src/js/list_controller.js index c09ae9182..20ac586b4 100644 --- a/model_access_rights/static/src/js/list_controller.js +++ b/model_access_rights/static/src/js/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"; var rpc = require('web.rpc'); const {onWillStart} = owl; patch(ListController.prototype, 'model_access_rights/static/src/js/list_controller.js.ListController', { @@ -12,6 +13,7 @@ patch(ListController.prototype, 'model_access_rights/static/src/js/list_controll */ setup() { this._super(); + this.user = useService("user"); onWillStart(async () => { var self = this var result; @@ -24,22 +26,34 @@ patch(ListController.prototype, 'model_access_rights/static/src/js/list_controll 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; - } - if (result[i].is_archive) { - self.archiveEnabled = false; - } else { - self.archiveEnabled = true; + } + } 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/model_access_rights_views.xml b/model_access_rights/views/model_access_rights_views.xml index 945acf1af..d84d3b73e 100644 --- a/model_access_rights/views/model_access_rights_views.xml +++ b/model_access_rights/views/model_access_rights_views.xml @@ -1,58 +1,65 @@ - + Restrict Access Rights access.right tree,form - - - access.right.view.tree - access.right - - - - - - - - - - - - - - access.right.view.form - access.right - -
- + + + access.right.view.tree + access.right + + + + + + + + + + + + + + access.right.view.form + access.right + + + - - + + + + + - - - - + + + + - -
+ +
- - - - - + + + + +