Odoo18-Base/addons/sale_async_emails/models/sale_order.py

46 lines
2.1 KiB
Python
Raw Permalink Normal View History

2025-01-06 10:57:38 +07:00
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
from odoo.tools.misc import str2bool
class SaleOrder(models.Model):
_inherit = 'sale.order'
pending_email_template_id = fields.Many2one(
string="Pending Email Template",
help="The template of the pending email that must be sent asynchronously.",
comodel_name='mail.template',
ondelete='set null',
readonly=True,
)
def _send_order_notification_mail(self, mail_template):
""" Override of `sale` to reschedule order status emails to be sent asynchronously. """
async_send = str2bool(self.env['ir.config_parameter'].sudo().get_param('sale.async_emails'))
cron = async_send and self.env.ref('sale_async_emails.cron', raise_if_not_found=False)
if async_send and cron and not self.env.context.get('is_async_email', False):
# Schedule the email to be sent asynchronously.
self.pending_email_template_id = mail_template
cron._trigger()
else: # We are in the cron job, or the user has disabled async emails.
super()._send_order_notification_mail(mail_template) # Send the email synchronously.
@api.model
def _cron_send_pending_emails(self, auto_commit=True):
""" Find and send pending order status emails asynchronously.
:param bool auto_commit: Whether the database cursor should be committed as soon as an email
is sent. Set to False in unit tests.
:return: None
"""
pending_email_orders = self.search([('pending_email_template_id', '!=', False)])
for order in pending_email_orders:
order = order[0] # Avoid pre-fetching after each cache invalidation due to committing.
order.with_context(is_async_email=True)._send_order_notification_mail(
order.pending_email_template_id
) # Asynchronously resume the email sending.
order.pending_email_template_id = None
if auto_commit:
self.env.cr.commit() # Save progress in case the cron is killed.