fix: resolve AccessError in POS session message posting by using sudo for partner access and message notification
This commit is contained in:
parent
c70ce3d70e
commit
07125cdc43
@ -1,22 +1,84 @@
|
|||||||
from odoo import models
|
from odoo import models, _
|
||||||
|
from odoo.tools import plaintext2html
|
||||||
|
|
||||||
|
|
||||||
class PosSession(models.Model):
|
class PosSession(models.Model):
|
||||||
_inherit = 'pos.session'
|
_inherit = 'pos.session'
|
||||||
|
|
||||||
def _get_message_author(self):
|
def _get_message_author(self):
|
||||||
"""Override to read employee partner with sudo() to avoid res.partner
|
"""Read employee partner with sudo() to avoid res.partner access errors
|
||||||
access errors when the cashier's allowed companies don't include the
|
for cashier users whose allowed companies don't include the partner's company_id.
|
||||||
company_id set on work_contact_id (caused by hr_multi_company_employee
|
|
||||||
assigning employees to branch companies).
|
|
||||||
"""
|
"""
|
||||||
if not self.employee_id:
|
if not self.employee_id:
|
||||||
return None
|
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()
|
employee = self.employee_id.sudo()
|
||||||
if related_partners := employee._get_related_partners():
|
related_partners = employee._get_related_partners()
|
||||||
|
if related_partners:
|
||||||
return related_partners[0]
|
return related_partners[0]
|
||||||
|
|
||||||
return self.sudo().user_id.partner_id
|
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()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user