[IMP] mail: track contact address

Currently there is no way of knowing who changed the address
of a partner. This field is of high importance and should be
tracked to be able to follow who is editing it.
As addresses are represented with a bunch of fields, tracking
them individually would result in weird-looking tracking
messages with each value stacked on top of the other.

To avoid this, we take advantage of the fact that tracking can
be used on non-stored compute fields to log any change as a
change over the full address.

The full address is derived from the contact_address field to
take advantage of the existing regional formatting of addresses.
It is however modified to replace return to lines with commas to
accomodate the formatting of tracking messages in the front-end.

task-3165293

closes odoo/odoo#114695

Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
This commit is contained in:
Renaud Thiry
2023-03-30 16:22:45 +02:00
parent 15a202c976
commit 035057a522
2 changed files with 51 additions and 0 deletions
+12
View File
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import re
from odoo import _, api, fields, models, tools
from odoo.osv import expression
@@ -20,6 +22,16 @@ class Partner(models.Model):
vat = fields.Char(tracking=5)
# channels
channel_ids = fields.Many2many('mail.channel', 'mail_channel_member', 'partner_id', 'channel_id', string='Channels', copy=False)
# tracked field used for chatter logging purposes
# we need this to be readable inline as tracking messages use inline HTML nodes
contact_address_inline = fields.Char(compute='_compute_contact_address_inline', string='Inlined Complete Address', tracking=True)
@api.depends('contact_address')
def _compute_contact_address_inline(self):
"""Compute an inline-friendly address based on contact_address."""
for partner in self:
# replace any successive \n with a single comma
partner.contact_address_inline = re.sub(r'\n(\s|\n)*', ', ', partner.contact_address).strip().strip(',')
def _compute_im_status(self):
super()._compute_im_status()
+39
View File
@@ -90,6 +90,45 @@ class TestPartner(MailCommon):
self.assertEqual(parsed[0], expected_name)
self.assertEqual(parsed[1], expected_email)
def test_res_partner_address_tracking(self):
company_partner = self.env.company.partner_id
# use some wacky formatting to check inlining
company_partner.country_id.address_format = """%(street)s
\n\n\n%(street2)s
%(city)s %(state_code)s %(zip)s
\n%(country_name)s\n
\n """
company_partner.write({
'city': 'Some City Name',
'street': 'Some Street Name',
'type': 'contact',
})
child_partner = self.env['res.partner'].create({
'name': 'Some Guy',
'parent_id': company_partner.id,
})
self.env.flush_all()
self.cr.precommit.run()
# keep track of setup messages
partners = (company_partner, child_partner)
partner_original_messages = (company_partner.message_ids, child_partner.message_ids)
company_partner.street = 'Some Other Street Name'
company_partner.city = 'Some Other City Name'
self.env.flush_all()
self.cr.precommit.run()
for partner, original_messages in zip(partners, partner_original_messages):
change_messages = partner.message_ids - original_messages
self.assertEqual(len(change_messages), 1)
tracking_values = change_messages.tracking_value_ids
self.assertIn('YourCompany, Some Street Name, Some City Name CA 94134, United States',
tracking_values._get_old_display_value())
self.assertIn('YourCompany, Some Other Street Name, Some Other City Name CA 94134, United States',
tracking_values._get_new_display_value())
# none of the address fields are logged at the same time
self.assertEqual(set(), set(partner._address_fields()) & set(tracking_values.sudo().field.mapped('name')))
def test_res_partner_find_or_create(self):
PartnerModel = self.env['res.partner']