[REF] mail: rename 'field' to 'field_id' on tracking value

PURPOSE

Simplify 'mail.tracking.value' model and code. Remove unnecessary fields and
computation. Make code easier to handle and more batch-enabled.

SPECIFICATIONS

Rename 'field' to 'field_id' on tracking model. It better indicates it is a
many2one and not a char field holding a field name for example.

Task-3345979 (Mail: Simplify tracking model)

Part-of: odoo/odoo#124182
This commit is contained in:
Thibault Delavallée
2023-10-06 06:13:55 +00:00
parent b2d7f03398
commit e147d35590
16 changed files with 56 additions and 55 deletions
@@ -261,7 +261,7 @@ class TestAccountComposerPerformance(AccountTestInvoicingCommon, MailCommon):
# tracking: is_move_sent
self.assertEqual(track_msg.author_id, self.env.user.partner_id)
self.assertEqual(track_msg.email_from, self.env.user.email_formatted)
self.assertTrue('is_move_sent' in track_msg.tracking_value_ids.field.mapped('name'))
self.assertTrue('is_move_sent' in track_msg.tracking_value_ids.field_id.mapped('name'))
# sent email
self.assertMailMail(
test_customer,
@@ -348,7 +348,7 @@ class TestAccountComposerPerformance(AccountTestInvoicingCommon, MailCommon):
# tracking: is_move_sent
self.assertEqual(track_msg.author_id, self.env.user.partner_id)
self.assertEqual(track_msg.email_from, self.env.user.email_formatted)
self.assertTrue('is_move_sent' in track_msg.tracking_value_ids.field.mapped('name'))
self.assertTrue('is_move_sent' in track_msg.tracking_value_ids.field_id.mapped('name'))
# sent email
self.assertMailMail(
test_customer,
+2 -2
View File
@@ -4404,14 +4404,14 @@ class MailThread(models.AbstractModel):
tracking_message = return_line + message.subtype_id.description + return_line
for value in message.sudo().tracking_value_ids.filtered(lambda tracking: not tracking.field_groups):
if value.field.ttype == 'boolean':
if value.field_id.ttype == 'boolean':
old_value = str(bool(value.old_value_integer))
new_value = str(bool(value.new_value_integer))
else:
old_value = value.old_value_char if value.old_value_char else str(value.old_value_integer)
new_value = value.new_value_char if value.new_value_char else str(value.new_value_integer)
tracking_message += value.field.field_description + ': ' + old_value
tracking_message += value.field_id.field_description + ': ' + old_value
if old_value != new_value:
tracking_message += ' → ' + new_value
tracking_message += return_line
@@ -53,7 +53,7 @@ class MailTrackingDurationMixin(models.AbstractModel):
FROM mail_tracking_value v
LEFT JOIN mail_message m
ON m.id = v.mail_message_id
AND v.field = %(field_id)s
AND v.field_id = %(field_id)s
WHERE m.model = %(model_name)s
AND m.res_id IN %(record_ids)s
ORDER BY v.id
+12 -10
View File
@@ -3,16 +3,18 @@
from datetime import datetime
from odoo import api, fields, models, _
from odoo import api, fields, models
class MailTracking(models.Model):
_name = 'mail.tracking.value'
_description = 'Mail Tracking Value'
_rec_name = 'field'
_rec_name = 'field_id'
_order = 'id DESC'
field = fields.Many2one('ir.model.fields', required=True, readonly=True, index=True, ondelete='cascade')
field_id = fields.Many2one(
'ir.model.fields', required=True, readonly=True,
index=True, ondelete='cascade')
field_groups = fields.Char(compute='_compute_field_groups')
old_value_integer = fields.Integer('Old Value Integer', readonly=True)
@@ -32,11 +34,11 @@ class MailTracking(models.Model):
mail_message_id = fields.Many2one('mail.message', 'Message ID', required=True, index=True, ondelete='cascade')
@api.depends('mail_message_id', 'field')
@api.depends('mail_message_id', 'field_id')
def _compute_field_groups(self):
for tracking in self:
model = self.env[tracking.mail_message_id.model]
field = model._fields.get(tracking.field.name)
field = model._fields.get(tracking.field_id.name)
tracking.field_groups = field.groups if field else 'base.group_system'
@api.model
@@ -59,7 +61,7 @@ class MailTracking(models.Model):
if not field:
raise ValueError(f'Unknown field {col_name} on model {record._name}')
values = {'field': field.id}
values = {'field_id': field.id}
if col_info['type'] in {'integer', 'float', 'char', 'text', 'datetime'}:
values.update({
@@ -114,19 +116,19 @@ class MailTracking(models.Model):
"""
if not self:
return []
field_models = self.field.mapped('model')
field_models = self.field_id.mapped('model')
if len(set(field_models)) != 1:
raise ValueError('All tracking value should belong to the same model.')
TrackedModel = self.env[field_models[0]]
tracked_fields = TrackedModel.fields_get(self.field.mapped('name'), attributes={'string', 'type'})
fields_col_info = (tracked_fields.get(tracking.field.name) for tracking in self)
tracked_fields = TrackedModel.fields_get(self.field_id.mapped('name'), attributes={'string', 'type'})
fields_col_info = (tracked_fields.get(tracking.field_id.name) for tracking in self)
fields_sequence_map = dict(TrackedModel._mail_track_order_fields(tracked_fields))
formatted = [
{
'changedField': col_info['string'],
'id': tracking.id,
'fieldName': tracking.field.name,
'fieldName': tracking.field_id.name,
'fieldType': col_info['type'],
'newValue': {
'currencyId': tracking.currency_id.id,
@@ -53,7 +53,7 @@ patch(MockServer.prototype, {
return;
}
const values = {field: irField.id};
const values = {field_id: irField.id};
switch (irField.ttype) {
case "char":
case "datetime":
@@ -105,7 +105,7 @@ patch(MockServer.prototype, {
_mockMailTrackingValue_TrackingValueFormat(tracking_value_ids) {
const trackingValues = tracking_value_ids.map((tracking) => {
const irField = this.models["ir.model.fields"].records.find(
(field) => field.id === tracking.field
(field) => field.id === tracking.field_id
);
return {
changedField: capitalize(irField.ttype),
@@ -127,7 +127,7 @@ patch(MockServer.prototype, {
*/
_mockMailTrackingValue_FormatDisplayValue(record, type) {
const irField = this.models["ir.model.fields"].records.find(
(field) => field.id === record.field
(field) => field.id === record.field_id
);
switch (irField.ttype) {
case "float":
+1 -1
View File
@@ -1150,7 +1150,7 @@ class MailCase(MockEmail):
'text': 'text',
}
for field_name, value_type, old_value, new_value in data:
tracking = tracking_values.filtered(lambda track: track.field.name == field_name)
tracking = tracking_values.filtered(lambda track: track.field_id.name == field_name)
self.assertEqual(len(tracking), 1, f'Tracking: not found for {field_name}')
msg_base = f'Tracking: {field_name} ({value_type}: '
if value_type in suffix_mapping:
+1 -1
View File
@@ -109,7 +109,7 @@ class TestPartner(MailCommon):
self.assertIn(f'{self.env.company.name}, Some Other Street Name, Some Other City Name CA 94134, United States',
tracking_values.new_value_char)
# 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')))
self.assertEqual(set(), set(partner._address_fields()) & set(tracking_values.sudo().field_id.mapped('name')))
def test_discuss_mention_suggestions_priority(self):
name = uuid4() # unique name to avoid conflict with already existing users
@@ -8,7 +8,7 @@
<field name="priority">12</field>
<field name="arch" type="xml">
<tree string="Tracking Value">
<field name="field"/>
<field name="field_id"/>
<field name="old_value_integer"/>
<field name="old_value_float"/>
<field name="old_value_char"/>
@@ -31,7 +31,7 @@
<form string="Tracking Value">
<sheet>
<group name="field_details" string="Field details">
<field name="field"/>
<field name="field_id"/>
</group>
<group name="values">
<group name="old_values" string="Old values">
+1 -1
View File
@@ -31,5 +31,5 @@ def _project_post_init(env):
'mail_tracking_value_mail_message_id_old_value_integer_task_stage',
env['mail.tracking.value']._table,
['mail_message_id', 'old_value_integer'],
where=f'field={project_task_stage_field_id}'
where=f'field_id={project_task_stage_field_id}'
)
+21 -21
View File
@@ -303,7 +303,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_1_task_2_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -311,7 +311,7 @@
<field name="mail_message_id" ref="project_1_task_2_mail_message_1"/>
</record>
<record id="project_1_task_2_mail_message_2_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="old_value_integer">2</field>
@@ -349,7 +349,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_1_task_3_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -357,7 +357,7 @@
<field name="mail_message_id" ref="project_1_task_3_mail_message_1"/>
</record>
<record id="project_1_task_3_mail_message_2_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="old_value_integer">2</field>
@@ -395,7 +395,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_1_task_4_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -403,7 +403,7 @@
<field name="mail_message_id" ref="project_1_task_4_mail_message_1"/>
</record>
<record id="project_1_task_4_mail_message_2_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="old_value_integer">2</field>
@@ -433,7 +433,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_1_task_5_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -474,7 +474,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_1_task_6_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -512,7 +512,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_1_task_7_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -544,7 +544,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_1_task_8_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -726,7 +726,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_2_task_1_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -742,7 +742,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_2_task_1_mail_message_2_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="old_value_integer">2</field>
@@ -770,7 +770,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_2_task_2_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -786,7 +786,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_2_task_2_mail_message_2_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="old_value_integer">2</field>
@@ -815,7 +815,7 @@
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_2_task_3_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -879,7 +879,7 @@ Send it ASAP, its urgent.</field>
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_2_task_4_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -909,7 +909,7 @@ Send it ASAP, its urgent.</field>
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_2_task_5_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -937,7 +937,7 @@ Send it ASAP, its urgent.</field>
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_2_task_6_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -967,7 +967,7 @@ Send it ASAP, its urgent.</field>
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_2_task_7_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
@@ -983,7 +983,7 @@ Send it ASAP, its urgent.</field>
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_2_task_7_mail_message_2_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="old_value_integer">2</field>
@@ -1013,7 +1013,7 @@ Send it ASAP, its urgent.</field>
<field name="author_id" ref="base.partner_admin"/>
</record>
<record id="project_2_task_8_mail_message_1_track_1" model="mail.tracking.value">
<field name="field" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="field_id" model="ir.model.fields" eval="obj().search([('model', '=', 'project.task'), ('name', '=', 'stage_id')])"/>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="old_value_integer">1</field>
+1 -1
View File
@@ -159,7 +159,7 @@ class ProjectUpdate(models.Model):
INNER JOIN mail_tracking_value mtv
ON mm.id = mtv.mail_message_id
INNER JOIN ir_model_fields imf
ON mtv.field = imf.id
ON mtv.field_id = imf.id
AND imf.model = 'project.milestone'
AND imf.name = 'deadline'
INNER JOIN project_milestone pm
@@ -124,7 +124,7 @@ class ReportProjectTaskBurndownChart(models.AbstractModel):
LEFT JOIN (
mail_message mm
JOIN mail_tracking_value mtv ON mm.id = mtv.mail_message_id
AND mtv.field = %(field_id)s
AND mtv.field_id = %(field_id)s
AND mm.model='project.task'
AND mm.message_type = 'notification'
JOIN project_task_type ptt ON ptt.id = mtv.old_value_integer
@@ -154,7 +154,7 @@ class ReportProjectTaskBurndownChart(models.AbstractModel):
SELECT mm.date
FROM mail_message mm
JOIN mail_tracking_value mtv ON mm.id = mtv.mail_message_id
AND mtv.field = %(field_id)s
AND mtv.field_id = %(field_id)s
AND mm.model='project.task'
AND mm.message_type = 'notification'
AND mm.res_id = pt.id
@@ -70,7 +70,7 @@ class AccountMoveLine(models.Model):
move = aml.move_id
if move.state != 'posted':
continue
state_trackings = move.message_ids.tracking_value_ids.filtered(lambda t: t.field == am_state_field).sorted('id')
state_trackings = move.message_ids.tracking_value_ids.filtered(lambda t: t.field_id == am_state_field).sorted('id')
time = state_trackings[-1:].create_date or move.create_date # `or` in case it has been created in posted state
history.append((time, aml, False))
# Sort history based on the datetime. In case of equality, the prority is given to SVLs, then to IDs.
+3 -3
View File
@@ -681,7 +681,7 @@ class TestTrackingInternals(MailCommon):
[('mail_message_id', '=', record.message_ids[0].id)]
)
self.assertEqual(
tracking_values.field.mapped('name'),
tracking_values.field_id.mapped('name'),
ordered_fnames,
'Track: order, based on ID DESC, should follow tracking sequence (or name) on field'
)
@@ -698,7 +698,7 @@ class TestTrackingInternals(MailCommon):
]
self.env['mail.tracking.value'].sudo().create([
{
'field': field_id,
'field_id': field_id,
'mail_message_id': new_msg.id,
'old_value_char': 'unimportant',
'new_value_char': 'unimportant',
@@ -709,7 +709,7 @@ class TestTrackingInternals(MailCommon):
[('mail_message_id', '=', record.message_ids[0].id)]
)
self.assertEqual(
tracking_values.field.mapped('name'),
tracking_values.field_id.mapped('name'),
list(reversed(custom_order_fnames)),
'Tracking model: order, based on ID DESC, following reverted insertion'
)
+2 -2
View File
@@ -853,12 +853,12 @@ class TestMailComplexPerformance(BaseMailPerformance):
'subtype_id': comment_subtype_id,
'tracking_value_ids': [
(0, 0, {
'field': name_field.id,
'field_id': name_field.id,
'new_value_char': 'new 0',
'old_value_char': 'old 0',
}),
(0, 0, {
'field': customer_id_field.id,
'field_id': customer_id_field.id,
'new_value_char': 'new 1',
'new_value_integer': cls.partners[(record_idx * 5)].id,
'old_value_char': 'old 1',
@@ -198,8 +198,7 @@ class TestPortalFormatPerformance(FullBaseMailPerformance):
],
'tracking_value_ids': [
(0, 0, {
'field': user_id_field.id,
'field_desc': 'Responsible',
'field_id': user_id_field.id,
'new_value_char': 'new 1',
'new_value_integer': record.user_id.id,
'old_value_char': 'old 1',