hr_multi_company_employee/models/pos_session.py

85 lines
3.4 KiB
Python

from odoo import models, _
from odoo.tools import plaintext2html
class PosSession(models.Model):
_inherit = 'pos.session'
def _get_message_author(self):
"""Read employee partner with sudo() to avoid res.partner access errors
for cashier users whose allowed companies don't include the partner's company_id.
"""
if not self.employee_id:
return None
employee = self.employee_id.sudo()
related_partners = employee._get_related_partners()
if related_partners:
return related_partners[0]
return self.sudo().user_id.partner_id
def _set_opening_control_data(self, cashbox_value: int, notes: str):
"""Override pos_hr's _set_opening_control_data to use sudo for message_post.
pos_hr does:
super()._set_opening_control_data(...)
if author_id := self._get_message_author():
self.message_post(body=..., author_id=author_id.id)
The problem: message_post internally reads the author res.partner in the
cashier's restricted context, causing an AccessError.
Fix: we call the SAME logic but with self.sudo().message_post().
"""
# Step 1: call the pos_hr super chain but stop before message_post.
# We do this by walking MRO to find the base pos.session method
# (skipping pos_hr's override) and calling it directly.
base_method = None
found_pos_hr = False
for cls in type(self).__mro__:
if found_pos_hr:
if '_set_opening_control_data' in cls.__dict__:
base_method = cls._set_opening_control_data
break
elif (cls.__name__ == 'PosSession'
and getattr(cls, '__module__', '').endswith('pos_hr.models.pos_session')):
found_pos_hr = True
if base_method:
base_method(self, cashbox_value, notes)
else:
# pos_hr not in MRO or already at base — call normal super
super()._set_opening_control_data(cashbox_value, notes)
# Step 2: re-implement pos_hr's message posting with sudo
author = self._get_message_author()
if author:
self.sudo().message_post(
body=plaintext2html(_('Opened register')),
author_id=author.id,
)
def post_close_register_message(self):
"""Override pos_hr's post_close_register_message to use sudo for message_post."""
author = self._get_message_author()
if author:
self.sudo().message_post(
body=plaintext2html(_('Closed Register')),
author_id=author.id,
)
else:
# No employee — call the base pos.session fallback
base_method = None
found_pos_hr = False
for cls in type(self).__mro__:
if found_pos_hr:
if 'post_close_register_message' in cls.__dict__:
base_method = cls.post_close_register_message
break
elif (cls.__name__ == 'PosSession'
and getattr(cls, '__module__', '').endswith('pos_hr.models.pos_session')):
found_pos_hr = True
if base_method:
base_method(self)
else:
super().post_close_register_message()