[IMP] event: set an explicit onchange on partner_id of registration

RATIONALE

Manual onchange is necessary because you spot an issue (or customer complains).
Automatic update through computed feild is only there to try to add missing
pieces of information but cannot decide which is the correct field value to keep.

SPECIFICATIONS

Keep an explicit onchange on partner_id. Rationale : if user explicitly
changes the partner in interface, he wants to update the whole customer
information. If partner_id is updated in code (e.g. updating your personal
information after registeration in website_event_sale) fields with a value
should not be reset as we do not know which one is the correct one.

How it should behave as following

  * computed fields based on partner_id should only update missing
    information. Indeed automated code cannot decide which information
    is more accurate;
  * interface should allow to update all customer related information
    at once. We consider event users really want to update all fields

Tests are added to ensure behavior is not modified without notice.

LINKS

Task ID 2089156
Community PR odoo/odoo#42911
This commit is contained in:
Thibault Delavallée
2020-03-10 11:15:09 +00:00
parent 5e4efef3ca
commit c6003af734
2 changed files with 84 additions and 4 deletions
+24 -4
View File
@@ -31,10 +31,10 @@ class EventRegistration(models.Model):
states={'done': [('readonly', True)]})
name = fields.Char(
string='Attendee Name', index=True,
compute='_compute_contact_info', copy=True, readonly=False, store=True, tracking=True)
email = fields.Char(string='Email', compute='_compute_contact_info', copy=True, readonly=False, store=True)
phone = fields.Char(string='Phone', compute='_compute_contact_info', copy=True, readonly=False, store=True)
mobile = fields.Char(string='Mobile', compute='_compute_contact_info', copy=True, readonly=False, store=True)
compute='_compute_contact_info', copy=True, readonly=False, store=True, tracking=10)
email = fields.Char(string='Email', compute='_compute_contact_info', copy=True, readonly=False, store=True, tracking=11)
phone = fields.Char(string='Phone', compute='_compute_contact_info', copy=True, readonly=False, store=True, tracking=12)
mobile = fields.Char(string='Mobile', compute='_compute_contact_info', copy=True, 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(
@@ -50,6 +50,26 @@ class EventRegistration(models.Model):
('open', 'Confirmed'), ('done', 'Attended')],
string='Status', default='draft', readonly=True, copy=False, tracking=True)
@api.onchange('partner_id')
def _onchange_partner_id(self):
""" Keep an explicit onchange on partner_id. Rationale : if user explicitly
changes the partner in interface, he want to update the whole customer
information. If partner_id is updated in code (e.g. updating your personal
information after having registered in website_event_sale) fields with a
value should not be reset as we don't know which one is the right one.
In other words
* computed fields based on partner_id should only update missing
information. Indeed automated code cannot decide which information
is more accurate;
* interface should allow to update all customer related information
at once. We consider event users really want to update all fields
related to the partner;
"""
for registration in self:
if registration.partner_id:
registration.update(registration._synchronize_partner_values(registration.partner_id))
@api.depends('partner_id')
def _compute_contact_info(self):
for registration in self:
+60
View File
@@ -7,9 +7,69 @@ from dateutil.relativedelta import relativedelta
from odoo.addons.event.tests.common import TestEventCommon
from odoo.exceptions import ValidationError
from odoo.tests.common import Form
from odoo.tools import mute_logger
class TestEventUI(TestEventCommon):
def test_event_registration_partner_sync(self):
""" Ensure onchange on partner_id is kept for interface, not for computed
fields. """
registration_form = Form(self.env['event.registration'].with_context(
default_name='WrongName',
default_event_id=self.event_0.id
))
self.assertEqual(registration_form.event_id, self.event_0)
self.assertEqual(registration_form.name, 'WrongName')
self.assertFalse(registration_form.email)
self.assertFalse(registration_form.phone)
self.assertFalse(registration_form.mobile)
# trigger onchange
registration_form.partner_id = self.customer
self.assertEqual(registration_form.name, self.customer.name)
self.assertEqual(registration_form.email, self.customer.email)
self.assertEqual(registration_form.phone, self.customer.phone)
self.assertEqual(registration_form.mobile, self.customer.mobile)
# save, check record matches Form values
registration = registration_form.save()
self.assertEqual(registration.partner_id, self.customer)
self.assertEqual(registration.name, self.customer.name)
self.assertEqual(registration.email, self.customer.email)
self.assertEqual(registration.phone, self.customer.phone)
self.assertEqual(registration.mobile, self.customer.mobile)
# allow writing on some fields independently from customer config
registration.write({'phone': False, 'mobile': False})
self.assertFalse(registration.phone)
self.assertFalse(registration.mobile)
# reset partner should not reset other fields
registration.write({'partner_id': False})
self.assertEqual(registration.partner_id, self.env['res.partner'])
self.assertEqual(registration.name, self.customer.name)
self.assertEqual(registration.email, self.customer.email)
self.assertFalse(registration.phone)
self.assertFalse(registration.mobile)
# update to a new partner not through UI -> update only void feilds
customer2 = self.env['res.partner'].create({
'name': 'Constantin Customer 2',
'email': 'constantin2@test.example.com',
'country_id': self.env.ref('base.be').id,
'phone': '0456987654',
'mobile': '0456654321',
})
registration.write({'partner_id': customer2.id})
self.assertEqual(registration.partner_id, customer2)
self.assertEqual(registration.name, self.customer.name)
self.assertEqual(registration.email, self.customer.email)
self.assertEqual(registration.phone, customer2.phone)
self.assertEqual(registration.mobile, customer2.mobile)
class TestEventFlow(TestEventCommon):
@mute_logger('odoo.addons.base.models.ir_model', 'odoo.models')