feat: add multi-company access support for POS sessions and employees by overriding partner security rules and load methods
This commit is contained in:
parent
fc3bb1bfef
commit
c70ce3d70e
@ -1,3 +1,4 @@
|
|||||||
from . import hr_employee
|
from . import hr_employee
|
||||||
from . import pos_config
|
from . import pos_config
|
||||||
|
from . import pos_session
|
||||||
from . import res_users
|
from . import res_users
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -1,3 +1,4 @@
|
|||||||
|
import hashlib
|
||||||
from odoo import models, fields, api, _
|
from odoo import models, fields, api, _
|
||||||
|
|
||||||
class HrEmployee(models.Model):
|
class HrEmployee(models.Model):
|
||||||
@ -91,7 +92,40 @@ class HrEmployee(models.Model):
|
|||||||
return super()._search(domain, offset=offset, limit=limit, order=order, **kwargs)
|
return super()._search(domain, offset=offset, limit=limit, order=order, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def _load_pos_data_read(self, records, config):
|
||||||
|
"""Override to read employee data (including work_contact_id / res.partner)
|
||||||
|
with sudo() so cashier users whose user.company_ids doesn't include the
|
||||||
|
employee partner's company_id don't get a read access error on session open.
|
||||||
|
The employee records are already filtered by _load_pos_data_domain before
|
||||||
|
arriving here, so sudo() is safe — we're only relaxing the partner rule.
|
||||||
|
"""
|
||||||
|
fields = self._load_pos_data_fields(config)
|
||||||
|
# Read with sudo to bypass res.partner multi-company rule for work_contact_id
|
||||||
|
read_records = records.sudo().read(fields, load=False)
|
||||||
|
manager_ids = records.filtered(
|
||||||
|
lambda emp: config.group_pos_manager_id.id in emp.user_id.all_group_ids.ids
|
||||||
|
).ids
|
||||||
|
|
||||||
|
employees_barcode_pin = records.get_barcodes_and_pin_hashed()
|
||||||
|
bp_per_employee_id = {bp_e['id']: bp_e for bp_e in employees_barcode_pin}
|
||||||
|
|
||||||
|
for employee in read_records:
|
||||||
|
if employee['id'] in manager_ids:
|
||||||
|
role = 'manager'
|
||||||
|
employee['_user_role'] = 'admin'
|
||||||
|
elif employee['id'] in config.advanced_employee_ids.ids:
|
||||||
|
role = 'manager'
|
||||||
|
elif employee['id'] in config.minimal_employee_ids.ids:
|
||||||
|
role = 'minimal'
|
||||||
|
else:
|
||||||
|
role = 'cashier'
|
||||||
|
|
||||||
|
employee['_role'] = role
|
||||||
|
employee['_barcode'] = bp_per_employee_id[employee['id']]['barcode']
|
||||||
|
employee['_pin'] = bp_per_employee_id[employee['id']]['pin']
|
||||||
|
|
||||||
|
return read_records
|
||||||
|
|
||||||
|
|
||||||
class HrEmployeePublic(models.Model):
|
class HrEmployeePublic(models.Model):
|
||||||
|
|||||||
22
models/pos_session.py
Normal file
22
models/pos_session.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from odoo import models
|
||||||
|
|
||||||
|
|
||||||
|
class PosSession(models.Model):
|
||||||
|
_inherit = 'pos.session'
|
||||||
|
|
||||||
|
def _get_message_author(self):
|
||||||
|
"""Override to read employee partner with sudo() to avoid res.partner
|
||||||
|
access errors when the cashier's allowed companies don't include the
|
||||||
|
company_id set on work_contact_id (caused by hr_multi_company_employee
|
||||||
|
assigning employees to branch companies).
|
||||||
|
"""
|
||||||
|
if not self.employee_id:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Use sudo() to bypass multi-company partner rule when reading
|
||||||
|
# the employee's work_contact_id or user partner for message posting.
|
||||||
|
employee = self.employee_id.sudo()
|
||||||
|
if related_partners := employee._get_related_partners():
|
||||||
|
return related_partners[0]
|
||||||
|
|
||||||
|
return self.sudo().user_id.partner_id
|
||||||
@ -16,7 +16,11 @@
|
|||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="base.res_partner_rule" model="ir.rule">
|
<record id="base.res_partner_rule" model="ir.rule">
|
||||||
<field name="domain_force">['|', '|', ('partner_share', '=', False), ('company_id', 'parent_of', company_ids), ('company_id', '=', False)]</field>
|
<!-- Override: allow access if company_id is in ANY of the user's allowed companies
|
||||||
|
(user.company_ids), not only the currently active session companies (company_ids).
|
||||||
|
This fixes the "read access to res.partner" error when viewing employees whose
|
||||||
|
partner belongs to a non-active but permitted company. -->
|
||||||
|
<field name="domain_force">['|', '|', '|', ('partner_share', '=', False), ('company_id', 'parent_of', company_ids), ('company_id', 'in', user.company_ids.ids), ('company_id', '=', False)]</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="base.res_company_rule_employee" model="ir.rule">
|
<record id="base.res_company_rule_employee" model="ir.rule">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user