CybroOdoo / CybroAddons

276 stars 623 forks source link

hide_menu_user singleton error #312

Open digizilla-tohamy opened 4 months ago

digizilla-tohamy commented 4 months ago

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)
Paulius11 commented 3 months ago

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

digizilla-tohamy commented 3 months ago

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.

Paulius11 commented 3 months ago

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.

digizilla-tohamy commented 3 months ago

Thank you for sharing 🙏