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
-
-