[FIX] event: split stored editable computed fields compute method

RATIONALE

Stored editable fields receive their values either from compute either from
user input. If a user input is given to create / write compute method is not
called. If multiple fields are computed through the same method giving one
field value discard call to compute method and other fields are not called.

SPECIFICATIONS

Split ``_compute_contact_info`` compute method so that partner related fields
are independent.

LINKS

COM PR #65688
Task ID-2455165

X-original-commit odoo/odoo@dfc319f584

X-original-commit: c251048cfead27d12117557fe4b6601bef39e8e1
This commit is contained in:
Thibault Delavallée
2021-02-11 12:41:47 +00:00
parent 87f3891244
commit 6986faf533
2 changed files with 51 additions and 26 deletions
+48 -23
View File
@@ -1,13 +1,12 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from dateutil.relativedelta import relativedelta
from odoo import _, api, fields, models
from odoo.tools import format_datetime
from odoo.exceptions import AccessError, ValidationError
from dateutil.relativedelta import relativedelta
class EventRegistration(models.Model):
_name = 'event.registration'
@@ -32,10 +31,10 @@ class EventRegistration(models.Model):
states={'done': [('readonly', True)]})
name = fields.Char(
string='Attendee Name', index=True,
compute='_compute_contact_info', readonly=False, store=True, tracking=10)
email = fields.Char(string='Email', compute='_compute_contact_info', readonly=False, store=True, tracking=11)
phone = fields.Char(string='Phone', compute='_compute_contact_info', readonly=False, store=True, tracking=12)
mobile = fields.Char(string='Mobile', compute='_compute_contact_info', readonly=False, store=True, tracking=13)
compute='_compute_name', readonly=False, store=True, tracking=10)
email = fields.Char(string='Email', compute='_compute_email', readonly=False, store=True, tracking=11)
phone = fields.Char(string='Phone', compute='_compute_phone', readonly=False, store=True, tracking=12)
mobile = fields.Char(string='Mobile', compute='_compute_mobile', readonly=False, store=True, tracking=13)
# organization
date_open = fields.Datetime(string='Registration Date', readonly=True, default=lambda self: fields.Datetime.now()) # weird crash is directly now
date_closed = fields.Datetime(
@@ -72,16 +71,40 @@ class EventRegistration(models.Model):
registration.update(registration._synchronize_partner_values(registration.partner_id))
@api.depends('partner_id')
def _compute_contact_info(self):
def _compute_name(self):
for registration in self:
if registration.partner_id:
partner_vals = self._synchronize_partner_values(registration.partner_id)
registration.update(
dict((fname, fvalue)
for fname, fvalue in partner_vals.items()
if fvalue and not (registration[fname] or registration._origin[fname])
)
)
if not registration.name and registration.partner_id:
registration.name = registration._synchronize_partner_values(
registration.partner_id,
fnames=['name']
).get('name') or False
@api.depends('partner_id')
def _compute_email(self):
for registration in self:
if not registration.email and registration.partner_id:
registration.email = registration._synchronize_partner_values(
registration.partner_id,
fnames=['email']
).get('email') or False
@api.depends('partner_id')
def _compute_phone(self):
for registration in self:
if not registration.phone and registration.partner_id:
registration.phone = registration._synchronize_partner_values(
registration.partner_id,
fnames=['phone']
).get('phone') or False
@api.depends('partner_id')
def _compute_mobile(self):
for registration in self:
if not registration.mobile and registration.partner_id:
registration.mobile = registration._synchronize_partner_values(
registration.partner_id,
fnames=['mobile']
).get('mobile') or False
@api.depends('state')
def _compute_date_closed(self):
@@ -109,6 +132,16 @@ class EventRegistration(models.Model):
if any(registration.event_id != registration.event_ticket_id.event_id for registration in self if registration.event_ticket_id):
raise ValidationError(_('Invalid event / ticket choice'))
def _synchronize_partner_values(self, partner, fnames=None):
if fnames is None:
fnames = ['name', 'email', 'phone', 'mobile']
if partner:
contact_id = partner.address_get().get('contact', False)
if contact_id:
contact = self.env['res.partner'].browse(contact_id)
return dict((fname, contact[fname]) for fname in fnames if contact[fname])
return {}
# ------------------------------------------------------------
# CRUD
# ------------------------------------------------------------
@@ -158,14 +191,6 @@ class EventRegistration(models.Model):
return False
return True
def _synchronize_partner_values(self, partner):
if partner:
contact_id = partner.address_get().get('contact', False)
if contact_id:
contact = self.env['res.partner'].browse(contact_id)
return dict((fname, contact[fname]) for fname in ['name', 'email', 'phone', 'mobile'] if contact[fname])
return {}
# ------------------------------------------------------------
# ACTIONS / BUSINESS
# ------------------------------------------------------------
+3 -3
View File
@@ -351,9 +351,9 @@ class TestEventRegistrationData(TestEventCommon):
self.assertEqual(
new_reg.email, test_email,
'Registration should take user input over computed partner value')
# self.assertEqual(
# new_reg.phone, customer.phone,
# 'Registration should take partner value if not user input')
self.assertEqual(
new_reg.phone, customer.phone,
'Registration should take partner value if not user input')
# already filled information should not be updated
event.write({