feat: implement bi-directional synchronization of company access between employees and res.users
This commit is contained in:
parent
e5998791e9
commit
dfe249a1f0
@ -1,2 +1,3 @@
|
||||
from . import hr_employee
|
||||
from . import pos_config
|
||||
from . import res_users
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -27,6 +27,29 @@ class HrEmployee(models.Model):
|
||||
domain="[('share', '=', False), ('company_ids', 'in', company_ids)]"
|
||||
)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
employees = super().create(vals_list)
|
||||
employees.sudo()._sync_user_company_ids()
|
||||
return employees
|
||||
|
||||
def write(self, vals):
|
||||
res = super().write(vals)
|
||||
if any(f in vals for f in ['company_ids', 'company_id', 'user_id']):
|
||||
self.sudo()._sync_user_company_ids()
|
||||
return res
|
||||
|
||||
def _sync_user_company_ids(self):
|
||||
for employee in self:
|
||||
if employee.user_id:
|
||||
user = employee.user_id
|
||||
employee_companies = employee.company_ids | employee.company_id
|
||||
companies_to_add = employee_companies - user.company_ids
|
||||
if companies_to_add:
|
||||
user.write({
|
||||
'company_ids': [(4, cid.id) for cid in companies_to_add]
|
||||
})
|
||||
|
||||
@api.depends('company_ids')
|
||||
def _compute_company_id(self):
|
||||
for employee in self:
|
||||
@ -110,6 +133,13 @@ class HrEmployee(models.Model):
|
||||
if rule_product.domain_force != new_domain_product:
|
||||
rule_product.sudo().write({'domain_force': new_domain_product})
|
||||
|
||||
# Proactively synchronize company_ids for all existing employees to cure current mismatches
|
||||
try:
|
||||
mismatched_employees = self.sudo().search([('user_id', '!=', False)])
|
||||
mismatched_employees._sync_user_company_ids()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class HrEmployeePublic(models.Model):
|
||||
|
||||
77
models/res_users.py
Normal file
77
models/res_users.py
Normal file
@ -0,0 +1,77 @@
|
||||
from odoo import models, api
|
||||
|
||||
class ResUsers(models.Model):
|
||||
_inherit = 'res.users'
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
# Pre-process vals to ensure primary company_id is always in allowed company_ids
|
||||
# This prevents Odoo's _check_user_company ValidationError when template users have different company_ids
|
||||
for vals in vals_list:
|
||||
company_id = vals.get('company_id')
|
||||
if company_id:
|
||||
if 'company_ids' in vals:
|
||||
company_ids_commands = vals['company_ids']
|
||||
existing_ids = set()
|
||||
has_six = False
|
||||
six_index = -1
|
||||
for idx, cmd in enumerate(company_ids_commands):
|
||||
if isinstance(cmd, (list, tuple)) and len(cmd) >= 3:
|
||||
if cmd[0] == 6:
|
||||
existing_ids.update(cmd[2])
|
||||
has_six = True
|
||||
six_index = idx
|
||||
elif cmd[0] == 4:
|
||||
existing_ids.add(cmd[1])
|
||||
|
||||
if company_id not in existing_ids:
|
||||
if has_six and six_index != -1:
|
||||
cmd = list(company_ids_commands[six_index])
|
||||
cmd[2] = list(cmd[2]) + [company_id]
|
||||
company_ids_commands[six_index] = tuple(cmd)
|
||||
else:
|
||||
company_ids_commands.append((4, company_id))
|
||||
else:
|
||||
vals['company_ids'] = [(6, 0, [company_id])]
|
||||
|
||||
users = super().create(vals_list)
|
||||
users.sudo()._sync_employee_company_ids()
|
||||
return users
|
||||
|
||||
def write(self, vals):
|
||||
# Pre-process vals to ensure primary company_id is always in allowed company_ids
|
||||
company_id = vals.get('company_id')
|
||||
if company_id:
|
||||
has_company_ids = 'company_ids' in vals
|
||||
existing_ids = set()
|
||||
if has_company_ids:
|
||||
for cmd in vals['company_ids']:
|
||||
if isinstance(cmd, (list, tuple)) and len(cmd) >= 3:
|
||||
if cmd[0] == 6:
|
||||
existing_ids.update(cmd[2])
|
||||
elif cmd[0] == 4:
|
||||
existing_ids.add(cmd[1])
|
||||
|
||||
for user in self:
|
||||
user_allowed = set(user.company_ids.ids)
|
||||
if has_company_ids:
|
||||
if company_id not in existing_ids:
|
||||
vals['company_ids'] = list(vals['company_ids']) + [(4, company_id)]
|
||||
else:
|
||||
if company_id not in user_allowed:
|
||||
vals['company_ids'] = [(4, company_id)]
|
||||
|
||||
res = super().write(vals)
|
||||
if any(f in vals for f in ['company_id', 'company_ids']):
|
||||
self.sudo()._sync_employee_company_ids()
|
||||
return res
|
||||
|
||||
def _sync_employee_company_ids(self):
|
||||
for user in self:
|
||||
employee_companies = user.employee_ids.mapped('company_ids')
|
||||
employee_primary_companies = user.employee_ids.mapped('company_id')
|
||||
companies_to_add = (employee_companies | employee_primary_companies | user.company_id) - user.company_ids
|
||||
if companies_to_add:
|
||||
user.write({
|
||||
'company_ids': [(4, cid.id) for cid in companies_to_add]
|
||||
})
|
||||
Loading…
Reference in New Issue
Block a user