CybroOdoo / CybroAddons

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

hide_menu_user singleton error

digizilla-tohamy opened this issue · comments

hide_menu_user raises the following error when activating new addons
the issue is in the overriden write method in ResUsers Class

RPC_ERROR
Odoo Server Error
Traceback (most recent call last):
  File "/home/odoo/src/odoo/odoo/tools/[convert.py](https://convert.py/)", line 556, in _tag_root
    f(rec)
  File "/home/odoo/src/odoo/odoo/tools/[convert.py](https://convert.py/)", line 456, in _tag_record
    record = model._load_records([data], self.mode == 'update')
  File "/home/odoo/src/odoo/odoo/[models.py](https://models.py/)", line 5040, in _load_records
    data['record']._load_records_write(data['values'])
  File "/home/odoo/src/odoo/odoo/[models.py](https://models.py/)", line 4971, in _load_records_write
    self.write(values)
  File "/home/odoo/src/odoo/addons/auth_totp_mail/models/res_users.py", line 11, in write
    res = super().write(vals)
  File "/home/odoo/src/odoo/addons/mail/models/discuss/res_users.py", line 17, in write
    res = super().write(vals)
  File "/home/odoo/src/odoo/addons/mail/models/res_users.py", line 105, in write
    write_res = super(Users, self).write(vals)
  File "/home/odoo/src/odoo/addons/resource/models/res_users.py", line 17, in write
    rslt = super().write(vals)
  File "/home/odoo/src/user/hide_menu_user/models/res_users.py", line 38, in write
    res = super(ResUsers, self).write(vals)
  File "/home/odoo/src/odoo/odoo/addons/base/models/res_users.py", line 1675, in write
    res = super(UsersView, self).write(values)
  File "/home/odoo/src/odoo/odoo/addons/base/models/res_users.py", line 1376, in write
    res = super(UsersImplied, self).write(values)
  File "/home/odoo/src/odoo/odoo/addons/base/models/res_users.py", line 666, in write
    internal_users.write({'groups_id': [[Command.link](https://command.link/)(gid) for gid in added_groups.ids]})
  File "/home/odoo/src/odoo/addons/auth_totp_mail/models/res_users.py", line 11, in write
    res = super().write(vals)
  File "/home/odoo/src/odoo/addons/mail/models/discuss/res_users.py", line 17, in write
    res = super().write(vals)
  File "/home/odoo/src/odoo/addons/mail/models/res_users.py", line 105, in write
    write_res = super(Users, self).write(vals)
  File "/home/odoo/src/odoo/addons/resource/models/res_users.py", line 17, in write
    rslt = super().write(vals)
  File "/home/odoo/src/user/hide_menu_user/models/res_users.py", line 37, in write
    menu.restrict_user_ids = [[fields.Command.link](https://fields.command.link/)([self.id](https://self.id/))]
  File "/home/odoo/src/odoo/odoo/[fields.py](https://fields.py/)", line 5142, in get
    raise ValueError("Expected singleton: %s" % record)
ValueError: Expected singleton: res.users(6, 2, 7, 8)

I'm encountering an issue with installing hr_ modules in Odoo v17. Do you have any ideas why this exception is being raised?

From my humble debugging, I found that the issue is
in hide_menu_user/models/res_users.py
in class ResUsers:

def write(self, vals):
        """
        Write method for the ResUsers model.
        Ensure the menu will not remain hidden after removing it from the list.
        """
        for menu in self.hide_menu_ids:
            menu.restrict_user_ids = [fields.Command.link(self.id)]
        res = super(ResUsers, self).write(vals)
        return res

if you add a break point in this write method, when you install the addon,
the self object will have multiple users, somthing like this
self= res.user(2,3,4,5)
Therefore, when the super write method res = super(ResUsers, self).write(vals) is called
the expected singleton error is raised. as it expects only one user

My work arround was to to loop over each user and call the super write method for each one.
So my write method now looks like this

def write(self, vals):
        """
        Write method for the ResUsers model.
        Ensure the menu will not remain hidden after removing it from the list.
        """
        # Updated : looping over each record in self
        for rec in self:
            for menu in rec.hide_menu_ids:
                menu.restrict_user_ids = [fields.Command.link(rec.id)]
            res = super(ResUsers, rec).write(vals)
        return res

This will dodge you the singleton error, and completes your addon installation.
But I am not sure if this is the right way to do it, or if this causes any bugs.

I solved it by changing write method:

def write(self, vals):
        """
        Write method for the ResUsers model.
        Ensure the menu will not remain hidden after removing it from the list.
        """
        res = super(ResUsers, self).write(vals)
        for record in self:
            for menu in record.hide_menu_ids:
                menu.write({
                'restrict_user_ids': [Command.set([record.id] + [user.id for user in menu.restrict_user_ids])]
                })
        return res

I'm also not sure which approach is best suitable in this case.

Thank you for sharing 🙏