Odoo18-Base/addons/event_crm/models/event_lead_request.py
2025-01-06 10:57:38 +07:00

80 lines
3.4 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import threading
from odoo import api, fields, models
class EventLeadRequest(models.Model):
""" Technical model created when a user requests 'leads generation' on an event based on all
existing event.lead.rules (see event#action_generate_leads).
As an event can hold a lot of registrations, we use a batch approach with a separate model that
contains the batching logic method and the field to retain progress.
To benefit from a background processing, we use a CRON that calls itself with a CRON trigger
until the batch is completed, which unlinks this technical generation record. """
_name = "event.lead.request"
_description = "Event Lead Request"
_log_access = False
_rec_name = "event_id"
_order = "id asc"
_REGISTRATIONS_BATCH_SIZE = 200
event_id = fields.Many2one('event.event', required=True, string="Event", ondelete="cascade")
processed_registration_id = fields.Integer("Processed Registration",
help="The ID of the last processed event.registration, used to know where to resume.")
_sql_constraints = [
('uniq_event', 'unique(event_id)', 'You can only have one generation request per event at a time.'),
]
@api.model
def _cron_generate_leads(self, job_limit=100, registrations_batch_size=None):
""" See class docstring for details.
:param job_limit: The maximum amount of 'event.lead.request' to process
Defaults to 100.
:param registrations_batch_size: The amount of attendees processed at once.
Defaults to event.lead.request._REGISTRATIONS_BATCH_SIZE """
# auto-commit except in testing mode
auto_commit = not getattr(threading.current_thread(), 'testing', False)
registrations_batch_size = registrations_batch_size or self._REGISTRATIONS_BATCH_SIZE
generate_requests = self.env['event.lead.request'].search([], limit=job_limit)
fulfilled_requests = self.env['event.lead.request']
for generate_request in generate_requests:
registrations_to_process = self.env['event.registration'].search([
('event_id', '=', generate_request.event_id.id),
('state', 'not in', ['draft', 'cancel']),
('id', '>', generate_request.processed_registration_id)],
limit=registrations_batch_size,
order='id asc'
)
registrations_to_process._apply_lead_generation_rules()
if len(registrations_to_process) < registrations_batch_size:
# done processing
fulfilled_requests += generate_request
else:
# not complete yet, update last processed registration
generate_request.processed_registration_id = registrations_to_process[-1].id
if auto_commit:
# commit after each completed batch/completed request
# avoids to re-process everything if an issue with one of the requests
# important as the lead creation process can typically send emails
# that should not be duped
self.env.cr.commit()
if generate_requests - fulfilled_requests:
# we still have unfinished requests: run the CRON again
self.env.ref('event_crm.ir_cron_generate_leads')._trigger()
if fulfilled_requests:
fulfilled_requests.unlink()