diff --git a/addons/event/models/event_registration.py b/addons/event/models/event_registration.py index b9d88dab020..e22283172e2 100644 --- a/addons/event/models/event_registration.py +++ b/addons/event/models/event_registration.py @@ -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: diff --git a/addons/event/tests/test_event_flow.py b/addons/event/tests/test_event_flow.py index 1ec9208e1b3..ff114bb4196 100644 --- a/addons/event/tests/test_event_flow.py +++ b/addons/event/tests/test_event_flow.py @@ -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')