Source code for odoo.addons.g2p_programs.models.managers.eligibility_manager

# Part of OpenG2P. See LICENSE file for full copyright and licensing details.
import logging

from odoo import _, api, fields, models

from odoo.addons.queue_job.delay import group

_logger = logging.getLogger(__name__)


class EligibilityManager(models.Model):
    _name = "g2p.eligibility.manager"
    _description = "Eligibility Manager"
    _inherit = "g2p.manager.mixin"

    program_id = fields.Many2one("g2p.program", "Program")

    @api.model
    def _selection_manager_ref_id(self):
        selection = super()._selection_manager_ref_id()
        new_manager = ("g2p.program_membership.manager.default", "Default Eligibility")
        if new_manager not in selection:
            selection.append(new_manager)
        return selection


[docs]class BaseEligibilityManager(models.AbstractModel): _name = "g2p.program_membership.manager" _inherit = "base.programs.manager" _description = "Base Eligibility" name = fields.Char("Manager Name", required=True) program_id = fields.Many2one("g2p.program", string="Program", required=True)
[docs] def enroll_eligible_registrants(self, program_memberships): """ This method is used to validate if a user match the criteria needed to be enrolled in a program. Args: program_membership: Returns: bool: True if the user match the criterias, False otherwise. """ raise NotImplementedError()
[docs] def verify_cycle_eligibility(self, cycle, membership): """ This method is used to validate if a beneficiary match the criteria needed to be enrolled in a cycle. Args: cycle: membership: Returns: bool: True if the cycle match the criterias, False otherwise. """ raise NotImplementedError()
[docs] def import_eligible_registrants(self): """ This method is used to import the beneficiaries in a program. Returns: """ raise NotImplementedError()
class DefaultEligibilityManager(models.Model): _name = "g2p.program_membership.manager.default" _inherit = ["g2p.program_membership.manager", "g2p.manager.source.mixin"] _description = "Simple Eligibility" # TODO: rename to allow_ # support_individual = fields.Boolean(string="Support Individual", default=False) # support_group = fields.Boolean(string="Support Group", default=False) # TODO: cache the parsed domain eligibility_domain = fields.Text(string="Domain", default="[]") def _prepare_eligible_domain(self, membership=None): domain = [] if membership is not None: ids = membership.mapped("partner_id.id") domain += [("id", "in", ids)] # Do not include disabled registrants domain += [("disabled", "=", False)] # TODO: use the config of the program if self.program_id.target_type == "group": domain += [("is_group", "=", True)] if self.program_id.target_type == "individual": domain += [("is_group", "=", False)] domain += self._safe_eval(self.eligibility_domain) # _logger.debug("DOMAIN: %s" % domain) return domain def enroll_eligible_registrants(self, program_memberships): # TODO: check if the beneficiary still match the criterias _logger.debug("-" * 100) _logger.debug("Checking eligibility for %s", program_memberships) for rec in self: beneficiaries = rec._verify_eligibility(program_memberships) return self.env["g2p.program_membership"].search( [ ("partner_id", "in", beneficiaries), ("program_id", "=", self.program_id.id), ] ) def verify_cycle_eligibility(self, cycle, membership): for rec in self: beneficiaries = rec._verify_eligibility(membership) return self.env["g2p.cycle.membership"].search( [("partner_id", "in", beneficiaries)] ) def _verify_eligibility(self, membership): domain = self._prepare_eligible_domain(membership) _logger.debug("Eligibility domain: %s", domain) beneficiaries = self.env["res.partner"].search(domain).ids _logger.debug("Beneficiaries: %s", beneficiaries) return beneficiaries def import_eligible_registrants(self): # TODO: this only take the first eligibility manager, no the others # TODO: move this code to the program manager and use the eligibility manager # like done for enroll_eligible_registrants for rec in self: domain = rec._prepare_eligible_domain() new_beneficiaries = self.env["res.partner"].search(domain) # logging.debug("Found %s beneficiaries", len(new_beneficiaries)) # Exclude already added beneficiaries beneficiary_ids = rec.program_id.get_beneficiaries().mapped("partner_id") # logging.debug("Excluding %s beneficiaries", len(beneficiary_ids)) new_beneficiaries = new_beneficiaries - beneficiary_ids # logging.debug("Finally %s beneficiaries", len(new_beneficiaries)) if len(new_beneficiaries) < 1000: rec._import_registrants(new_beneficiaries) else: rec._import_registrants_async(new_beneficiaries) def _import_registrants_async(self, new_beneficiaries): self.ensure_one() program = self.program_id program.message_post( body="Import of %s beneficiaries started." % len(new_beneficiaries) ) program.write({"locked": True, "locked_reason": "Importing beneficiaries"}) jobs = [] for i in range(0, len(new_beneficiaries), 10000): jobs.append( self.delayable()._import_registrants(new_beneficiaries[i : i + 10000]) ) main_job = group(*jobs) main_job.on_done(self.delayable().mark_import_as_done()) main_job.delay() def mark_import_as_done(self): self.ensure_one() self.program_id.locked = False self.program_id.locked_reason = None self.program_id.message_post(body=_("Import finished.")) def _import_registrants(self, new_beneficiaries): logging.info("Importing %s beneficiaries", len(new_beneficiaries)) beneficiaries_val = [] for beneficiary in new_beneficiaries: beneficiaries_val.append((0, 0, {"partner_id": beneficiary.id})) self.program_id.update({"program_membership_ids": beneficiaries_val})