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 hr_employee
|
||||||
from . import pos_config
|
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)]"
|
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')
|
@api.depends('company_ids')
|
||||||
def _compute_company_id(self):
|
def _compute_company_id(self):
|
||||||
for employee in self:
|
for employee in self:
|
||||||
@ -110,6 +133,13 @@ class HrEmployee(models.Model):
|
|||||||
if rule_product.domain_force != new_domain_product:
|
if rule_product.domain_force != new_domain_product:
|
||||||
rule_product.sudo().write({'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):
|
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