Files
Thibault DelavalléeandJeremy Hennecart 643df62f12 [REF] event: merge phone and mobile fields on registration
RATIONALE

Merge two phone-related field on registration as they overlap. Having only
one is sufficient for contact-oriented model like registration.

SPECIFICATIONS

Registration model currently holds two phone field, phone and mobile. This
leads to having records with sometimes phone, sometimes mobile being filled.
This makes phone flows not easy: we have to define fallbacks (use phone or
mobile), data is not always synchronized, ... in the end what event users
need is one phone field to be able to communicate with attendees. Having
only one field is sufficient and simplifies the model.

Keep only one phone field, instead of two. Merge phone and mobile into a single
one, keeping phone as first value when having both available e.g. when
synchronizing with the partner.

Task-3366899

Part-of: odoo/odoo#128232
Co-authored-by: "Jeremy Hennecart" <jeh@odoo.com>
2023-09-27 17:40:55 +00:00

90 lines
4.4 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
from odoo.osv import expression
class WebsiteVisitor(models.Model):
_name = 'website.visitor'
_inherit = ['website.visitor']
event_registration_ids = fields.One2many(
'event.registration', 'visitor_id', string='Event Registrations',
groups="event.group_event_registration_desk")
event_registration_count = fields.Integer(
'# Registrations', compute='_compute_event_registration_count',
groups="event.group_event_registration_desk")
event_registered_ids = fields.Many2many(
'event.event', string="Registered Events",
compute="_compute_event_registered_ids", compute_sudo=True,
search="_search_event_registered_ids",
groups="event.group_event_registration_desk")
@api.depends('partner_id', 'event_registration_ids.name')
def _compute_display_name(self):
""" If there is an event registration for an anonymous visitor, use that
registered attendee name as visitor name. """
super()._compute_display_name()
# sudo is needed for `event_registration_ids`
for visitor in self.sudo().filtered(lambda v: not v.partner_id and v.event_registration_ids):
visitor.display_name = visitor.event_registration_ids[-1].name
@api.depends('event_registration_ids')
def _compute_event_registration_count(self):
read_group_res = self.env['event.registration']._read_group(
[('visitor_id', 'in', self.ids)],
['visitor_id'], ['__count'])
visitor_mapping = {visitor.id: count for visitor, count in read_group_res}
for visitor in self:
visitor.event_registration_count = visitor_mapping.get(visitor.id, 0)
@api.depends('event_registration_ids.email', 'event_registration_ids.phone')
def _compute_email_phone(self):
super(WebsiteVisitor, self)._compute_email_phone()
for visitor in self.filtered(lambda visitor: not visitor.email or not visitor.mobile):
linked_registrations = visitor.event_registration_ids.sorted(lambda reg: (reg.create_date, reg.id), reverse=False)
if not visitor.email:
visitor.email = next((reg.email for reg in linked_registrations if reg.email), False)
if not visitor.mobile:
visitor.mobile = next((reg.phone for reg in linked_registrations if reg.phone), False)
@api.depends('event_registration_ids')
def _compute_event_registered_ids(self):
# include parent's registrations in a visitor o2m field. We don't add
# child one as child should not have registrations (moved to the parent)
for visitor in self:
all_registrations = visitor.event_registration_ids
visitor.event_registered_ids = all_registrations.mapped('event_id')
def _search_event_registered_ids(self, operator, operand):
""" Search visitors with terms on events within their event registrations. E.g. [('event_registered_ids',
'in', [1, 2])] should return visitors having a registration on events 1, 2 as
well as their children for notification purpose. """
if operator == "not in":
raise NotImplementedError("Unsupported 'Not In' operation on visitors registrations")
all_registrations = self.env['event.registration'].sudo().search([
('event_id', operator, operand)
])
if all_registrations:
visitor_ids = all_registrations.with_context(active_test=False).visitor_id.ids
else:
visitor_ids = []
return [('id', 'in', visitor_ids)]
def _inactive_visitors_domain(self):
""" Visitors registered to events are considered always active and should not be deleted. """
domain = super()._inactive_visitors_domain()
return expression.AND([domain, [('event_registration_ids', '=', False)]])
def _merge_visitor(self, target):
""" Override linking process to link registrations to the final visitor. """
self.event_registration_ids.visitor_id = target.id
registration_wo_partner = self.event_registration_ids.filtered(lambda registration: not registration.partner_id)
if registration_wo_partner:
registration_wo_partner.partner_id = target.partner_id
return super()._merge_visitor(target)