[FIX] crm_lead: improve synchronization between lead and partner_id
PURPOSE Distinguish synchronization of partner values on lead: address fields (all or none), classic fields (propagate if set) and special cases (names-alike). SPECIFICATIONS Follow up of https://github.com/odoo/odoo/commit/f8179007f9aa662be7318edeb18426ea1c906c15 Context: many fields are now synchronized from the partner_id: address fields as well as other contact fields. A first commit 9c9f477f04e8f4ee9b18092fe894890c2ab31b58 kept the value from the lead if the value from the partner was empty. This lead to mixed address fields. A second commit fixed that behavior f8179007f9aa662be7318edeb18426ea1c906c15 by taking the value from the partner only when it was set. Problem: This erases too much information. ``` >>> lead.partner_name 'testtest' >>> partner_id.name 'testtest@mailinator.com' >>> partner_id.parent_id res.partner() >>> partner_id.is_company False >>> lead.write({'partner_id': partner_id.id}) >>> lead.partner_name False ``` We indeed need a consistent address but for the other fields we want to keep the maximum of data. SOLUTION For the address fields, take all the values from the partner if one of the address fields is defined, otherwise keep the information defined on the lead. For all the other fields keep the lead information if the partner information is empty. LINKS Task ID-2316828 PR #55825 X-original-commit https://github.com/odoo/odoo/pull/55194/commits/f53fba6663a34e8e6b13354dde3dc225f5814de3 X-original-PR #55194 X-original-commit: b136df8530279a54c9be96beeea9bdda01643000
This commit is contained in:
committed by
Thibault Delavallée
parent
0158fd90f7
commit
6ea7a9a975
@@ -48,17 +48,22 @@ CRM_LEAD_FIELDS_TO_MERGE = [
|
||||
'email_cc',
|
||||
'website']
|
||||
|
||||
# Subset of partner fields: sync any of those
|
||||
PARTNER_FIELDS_TO_SYNC = [
|
||||
'mobile',
|
||||
'title',
|
||||
'function',
|
||||
'website',
|
||||
]
|
||||
|
||||
# Subset of partner fields: sync all or none to avoid mixed addresses
|
||||
PARTNER_ADDRESS_FIELDS_TO_SYNC = [
|
||||
'street',
|
||||
'street2',
|
||||
'city',
|
||||
'zip',
|
||||
'state_id',
|
||||
'country_id',
|
||||
'mobile',
|
||||
'zip',
|
||||
'function',
|
||||
'website',
|
||||
]
|
||||
|
||||
# Those values have been determined based on benchmark to minimise
|
||||
@@ -429,18 +434,27 @@ class Lead(models.Model):
|
||||
self.mobile = self.phone_format(self.mobile)
|
||||
|
||||
def _prepare_values_from_partner(self, partner):
|
||||
""" Get a dictionary with values coming from customer information to
|
||||
copy on a lead. Email_from and phone fields get the current lead
|
||||
values to avoid being reset if customer has no value for them. """
|
||||
""" Get a dictionary with values coming from partner information to
|
||||
copy on a lead. Non-address fields get the current lead
|
||||
values to avoid being reset if partner has no value for them. """
|
||||
|
||||
# Sync all address fields from partner, or none, to avoid mixing them.
|
||||
if any(partner[f] for f in PARTNER_ADDRESS_FIELDS_TO_SYNC):
|
||||
values = {f: partner[f] for f in PARTNER_ADDRESS_FIELDS_TO_SYNC}
|
||||
else:
|
||||
values = {f: self[f] for f in PARTNER_ADDRESS_FIELDS_TO_SYNC}
|
||||
|
||||
# For other fields, get the info from the partner, but only if set
|
||||
values.update({f: partner[f] or self[f] for f in PARTNER_FIELDS_TO_SYNC})
|
||||
|
||||
# Fields with specific logic
|
||||
partner_name = partner.parent_id.name
|
||||
if not partner_name and partner.is_company:
|
||||
partner_name = partner.name
|
||||
contact_name = False if partner.is_company else partner.name
|
||||
|
||||
values = {f: partner[f] if partner else self[f] for f in PARTNER_FIELDS_TO_SYNC}
|
||||
values.update({
|
||||
'partner_name': partner_name or self.partner_name,
|
||||
'contact_name': False if partner.is_company else partner.name or self.contact_name,
|
||||
'contact_name': contact_name or self.contact_name,
|
||||
})
|
||||
return self._convert_to_write(values)
|
||||
|
||||
|
||||
@@ -59,24 +59,74 @@ class TestCRMLead(TestCrmCommon):
|
||||
self.assertEqual(lead.zip, self.contact_1.zip)
|
||||
self.assertEqual(lead.country_id, self.contact_1.country_id)
|
||||
|
||||
def test_crm_lead_creation_partner_no_info(self):
|
||||
def test_crm_lead_creation_partner_address(self):
|
||||
""" Test that an address erases all lead address fields (avoid mixed addresses) """
|
||||
other_country = self.env.ref('base.fr')
|
||||
empty_partner = self.env['res.partner'].create({
|
||||
'name': 'Empty partner',
|
||||
'is_company': True
|
||||
'country_id': other_country.id,
|
||||
})
|
||||
lead_data = {
|
||||
'name': 'Test',
|
||||
'street': 'My street',
|
||||
'street2': 'My street',
|
||||
'city': 'My city',
|
||||
'zip': 'test@odoo.com',
|
||||
'state_id': self.env['res.country.state'].create({
|
||||
'name': 'My state',
|
||||
'country_id': self.country_ref.id,
|
||||
'code': 'MST',
|
||||
}).id,
|
||||
'country_id': self.country_ref.id,
|
||||
'email_from': self.test_email,
|
||||
'phone': self.test_phone,
|
||||
}
|
||||
lead = self.env['crm.lead'].create(lead_data)
|
||||
lead.partner_id = empty_partner
|
||||
self.assertEqual(lead.country_id, self.env['res.country'], "Country should be empty")
|
||||
self.assertEqual(lead.contact_name, False, "Contact name should be empty")
|
||||
self.assertEqual(lead.email_from, self.test_email, "Email From should keep its initial value")
|
||||
self.assertEqual(lead.phone, self.test_phone, "Phone should keep its initial value")
|
||||
# PARTNER_ADDRESS_FIELDS_TO_SYNC
|
||||
self.assertEqual(lead.street, empty_partner.street, "Street should be sync from the Partner")
|
||||
self.assertEqual(lead.street2, empty_partner.street2, "Street 2 should be sync from the Partner")
|
||||
self.assertEqual(lead.city, empty_partner.city, "City should be sync from the Partner")
|
||||
self.assertEqual(lead.zip, empty_partner.zip, "Zip should be sync from the Partner")
|
||||
self.assertEqual(lead.state_id, empty_partner.state_id, "State should be sync from the Partner")
|
||||
self.assertEqual(lead.country_id, empty_partner.country_id, "Country should be sync from the Partner")
|
||||
|
||||
def test_crm_lead_creation_partner_no_address(self):
|
||||
""" Test that an empty address on partner does not void its lead values """
|
||||
empty_partner = self.env['res.partner'].create({
|
||||
'name': 'Empty partner',
|
||||
'is_company': True,
|
||||
'mobile': '123456789',
|
||||
'title': self.env.ref('base.res_partner_title_mister').id,
|
||||
'function': 'My function',
|
||||
})
|
||||
lead_data = {
|
||||
'name': 'Test',
|
||||
'contact_name': 'Test',
|
||||
'street': 'My street',
|
||||
'country_id': self.country_ref.id,
|
||||
'email_from': self.test_email,
|
||||
'phone': self.test_phone,
|
||||
'mobile': '987654321',
|
||||
'website': 'http://mywebsite.org',
|
||||
}
|
||||
lead = self.env['crm.lead'].create(lead_data)
|
||||
lead.partner_id = empty_partner
|
||||
# SPECIFIC FIELDS
|
||||
self.assertEqual(lead.contact_name, lead_data['contact_name'], "Contact should remain")
|
||||
self.assertEqual(lead.email_from, lead_data['email_from'], "Email From should keep its initial value")
|
||||
self.assertEqual(lead.partner_name, empty_partner.name, "Partner name should be set as contact is a company")
|
||||
# PARTNER_ADDRESS_FIELDS_TO_SYNC
|
||||
self.assertEqual(lead.street, lead_data['street'], "Street should remain since partner has no address field set")
|
||||
self.assertEqual(lead.street2, False, "Street2 should remain since partner has no address field set")
|
||||
self.assertEqual(lead.country_id, self.country_ref, "Country should remain since partner has no address field set")
|
||||
self.assertEqual(lead.city, False, "City should remain since partner has no address field set")
|
||||
self.assertEqual(lead.zip, False, "Zip should remain since partner has no address field set")
|
||||
self.assertEqual(lead.state_id, self.env['res.country.state'], "State should remain since partner has no address field set")
|
||||
# PARTNER_FIELDS_TO_SYNC
|
||||
self.assertEqual(lead.phone, lead_data['phone'], "Phone should keep its initial value")
|
||||
self.assertEqual(lead.mobile, empty_partner.mobile, "Mobile from partner should be set on the lead")
|
||||
self.assertEqual(lead.title, empty_partner.title, "Title from partner should be set on the lead")
|
||||
self.assertEqual(lead.function, empty_partner.function, "Function from partner should be set on the lead")
|
||||
self.assertEqual(lead.website, lead_data['website'], "Website should keep its initial value")
|
||||
|
||||
@users('user_sales_manager')
|
||||
def test_crm_lead_partner_sync(self):
|
||||
|
||||
Reference in New Issue
Block a user