base_tier_validation: blocking notifications cron, a.k.a. should it block sudo writes?
Module
base_tier_validation
Describe the bug
We have a database where base_tier_validation is installed along with other addons from its family.
The cron mail.ir_cron_send_scheduled_message is blocked in loop because of that addon.
To Reproduce
Affected versions: 16.0 and probably others.
Steps to reproduce the behavior:
- Have some record that:
- Needs to notify a customer.
- Has no portal token.
- Is pending tier validation.
- Run the cron (you can do it manually)
Actual behavior
Cron enters fail loop. Traceback:
2024-05-06 12:30:04,883 42 INFO odoo odoo.addons.base.models.ir_cron: Starting job `Notification: Send scheduled message notifications`.
2024-05-06 12:30:04,889 42 INFO odoo odoo.addons.mail.models.mail_message_schedule: Send 1 scheduled messages
2024-05-06 12:30:04,921 42 ERROR odoo odoo.addons.base.models.ir_cron: Call from cron Notification: Send scheduled message notifications for server action #115 failed in Job #6
Traceback (most recent call last):
File "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_cron.py", line 391, in _callback
self.env['ir.actions.server'].browse(server_action_id).run()
File "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_actions.py", line 674, in run
res = runner(run_self, eval_context=eval_context)
File "/opt/odoo/auto/addons/website/models/ir_actions_server.py", line 61, in _run_action_code_multi
res = super(ServerAction, self)._run_action_code_multi(eval_context)
File "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_actions.py", line 544, in _run_action_code_multi
safe_eval(self.code.strip(), eval_context, mode="exec", nocopy=True, filename=str(self)) # nocopy allows to return 'action'
File "/opt/odoo/custom/src/odoo/odoo/tools/safe_eval.py", line 383, in safe_eval
return unsafe_eval(c, globals_dict, locals_dict)
File "ir.actions.server(115,)", line 1, in <module>
File "/opt/odoo/auto/addons/mail/models/mail_message_schedule.py", line 51, in _send_notifications_cron
messages_scheduled._send_notifications()
File "/opt/odoo/auto/addons/mail/models/mail_message_schedule.py", line 80, in _send_notifications
record._notify_thread(schedule.mail_message_id, msg_vals=False, **notify_kwargs)
File "/opt/odoo/auto/addons/sms/models/mail_thread.py", line 240, in _notify_thread
recipients_data = super(MailThread, self)._notify_thread(message, msg_vals=msg_vals, **kwargs)
File "/opt/odoo/auto/addons/mail_mobile/models/mail_thread.py", line 25, in _notify_thread
recipients_data = super(MailThread, self)._notify_thread(message, msg_vals=msg_vals, **kwargs)
File "/opt/odoo/auto/addons/mail_post_defer/models/mail_thread.py", line 33, in _notify_thread
return super()._notify_thread(message, msg_vals=msg_vals, **kwargs)
File "/opt/odoo/auto/addons/mail/models/mail_thread.py", line 2471, in _notify_thread
self._notify_thread_by_email(message, recipients_data, msg_vals=msg_vals, **kwargs)
File "/opt/odoo/auto/addons/mail/models/mail_thread.py", line 2557, in _notify_thread_by_email
recipients_groups_data = self._notify_get_recipients_classify(partners_data, model_name, msg_vals=msg_vals)
File "/opt/odoo/auto/addons/mail/models/mail_thread.py", line 2957, in _notify_get_recipients_classify
groups = self._notify_get_recipients_groups(msg_vals=local_msg_vals)
File "/opt/odoo/auto/addons/sale/models/sale_order.py", line 1236, in _notify_get_recipients_groups
groups = super()._notify_get_recipients_groups(msg_vals=msg_vals)
File "/opt/odoo/auto/addons/portal/models/mail_thread.py", line 30, in _notify_get_recipients_groups
access_token = self._portal_ensure_token()
File "/opt/odoo/auto/addons/portal/models/portal_mixin.py", line 32, in _portal_ensure_token
self.sudo().write({'access_token': str(uuid.uuid4())})
File "/opt/odoo/auto/addons/delivery_auto_refresh/models/sale_order.py", line 92, in write
)._auto_refresh_delivery()
File "/opt/odoo/auto/addons/delivery_auto_refresh/models/sale_order.py", line 65, in _auto_refresh_delivery
self.with_context(auto_refresh_delivery=True)._remove_delivery_line()
File "/opt/odoo/auto/addons/delivery_auto_refresh/models/sale_order.py", line 112, in _remove_delivery_line
res = super()._remove_delivery_line()
File "/opt/odoo/auto/addons/delivery/models/sale_order.py", line 56, in _remove_delivery_line
to_delete.unlink()
File "/opt/odoo/auto/addons/delivery/models/sale_order.py", line 193, in unlink
self.filtered('is_delivery').order_id.filtered('carrier_id').carrier_id = False
File "/opt/odoo/custom/src/odoo/odoo/fields.py", line 1325, in __set__
records.write({self.name: write_value})
File "/opt/odoo/auto/addons/delivery_auto_refresh/models/sale_order.py", line 84, in write
res = super().write(vals)
File "/opt/odoo/auto/addons/sale_stock/models/sale_order.py", line 121, in write
res = super(SaleOrder, self).write(values)
File "/opt/odoo/auto/addons/mail/models/mail_thread.py", line 315, in write
result = super(MailThread, self).write(values)
File "/opt/odoo/auto/addons/mail/models/mail_activity_mixin.py", line 241, in write
return super(MailActivityMixin, self).write(vals)
File "/opt/odoo/auto/addons/base_tier_validation/models/tier_validation.py", line 282, in write
raise ValidationError(_("The operation is under validation."))
odoo.exceptions.ValidationError: Esta operación está en proceso de validación.
Expected behavior Cron should work. Notifications should be sent, no matter the validation status.
Additional context
A possibility to fix the problem would be:
- Add
portalto the dependencies ofbase_tier_validation - Override
_portal_ensure_token(). - Call super
with_context(skip_validation_check=True)
However, pay attention to this part of the traceback:
File "/opt/odoo/auto/addons/portal/models/portal_mixin.py", line 32, in _portal_ensure_token
self.sudo().write({'access_token': str(uuid.uuid4())})
As you can see, the token is being written with sudo. I think it's a bug to block writes in sudo.
@moduon MT-5997
I think the block is not happening when writting access_token because when performing a validation, this functions must be called and access_token is allowed to be written
Ah good catch! Then the problem must be around these lines:
File "/opt/odoo/auto/addons/delivery_auto_refresh/models/sale_order.py", line 92, in write
)._auto_refresh_delivery()
File "/opt/odoo/auto/addons/delivery_auto_refresh/models/sale_order.py", line 65, in _auto_refresh_delivery
self.with_context(auto_refresh_delivery=True)._remove_delivery_line()
File "/opt/odoo/auto/addons/delivery_auto_refresh/models/sale_order.py", line 112, in _remove_delivery_line
res = super()._remove_delivery_line()
File "/opt/odoo/auto/addons/delivery/models/sale_order.py", line 56, in _remove_delivery_line
to_delete.unlink()
File "/opt/odoo/auto/addons/delivery/models/sale_order.py", line 193, in unlink
self.filtered('is_delivery').order_id.filtered('carrier_id').carrier_id = False
Then this should be the real fix: https://github.com/OCA/delivery-carrier/pull/815
Fixed by https://github.com/OCA/delivery-carrier/pull/799.