[REF] mail: remove 'field_{desc/type}' from 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

Remove 'field_desc' and 'field_type' from 'mail.tracking.value' model. Those
can be retrieved when necessary, as it is mainly used for frontend display
in Chatter.

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 b4cb36ed80
commit 6aa0a25df7
6 changed files with 38 additions and 81 deletions
+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_type == 'boolean':
if value.field.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_desc + ': ' + old_value
tracking_message += value.field.field_description + ': ' + old_value
if old_value != new_value:
tracking_message += ' → ' + new_value
tracking_message += return_line
+18 -18
View File
@@ -13,8 +13,6 @@ class MailTracking(models.Model):
_order = 'id DESC'
field = fields.Many2one('ir.model.fields', required=True, readonly=True, index=True, ondelete='cascade')
field_desc = fields.Char('Field Description', required=True, readonly=True)
field_type = fields.Char('Field Type')
field_groups = fields.Char(compute='_compute_field_groups')
old_value_integer = fields.Integer('Old Value Integer', readonly=True)
@@ -63,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, 'field_desc': col_info['string'], 'field_type': col_info['type']}
values = {'field': field.id}
if col_info['type'] in {'integer', 'float', 'char', 'text', 'datetime', 'monetary'}:
values.update({
@@ -119,33 +117,36 @@ class MailTracking(models.Model):
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)
fields_sequence_map = dict(TrackedModel._mail_track_order_fields(tracked_fields))
formatted = []
for tracking in self:
formatted.append({
'changedField': tracking.field_desc,
formatted = [
{
'changedField': col_info['string'],
'id': tracking.id,
'fieldName': tracking.field.name,
'fieldType': tracking.field_type,
'fieldType': col_info['type'],
'newValue': {
'currencyId': tracking.currency_id.id,
'value': tracking._format_display_value(new=True)[0],
'value': tracking._format_display_value(col_info['type'], new=True)[0],
},
'oldValue': {
'currencyId': tracking.currency_id.id,
'value': tracking._format_display_value(new=False)[0],
'value': tracking._format_display_value(col_info['type'], new=False)[0],
},
})
}
for tracking, col_info in zip(self, fields_col_info)
]
formatted.sort(
key=lambda info: (fields_sequence_map[info['fieldName']], info['fieldName']),
reverse=False,
)
return formatted
def _format_display_value(self, new=True):
def _format_display_value(self, field_type, new=True):
""" Format value of 'mail.tracking.value', according to the field type.
:param str field_type: Odoo field type;
:param bool new: if True, display the 'new' value. Otherwise display
the 'old' one.
"""
@@ -162,22 +163,21 @@ class MailTracking(models.Model):
result = []
for record in self:
ftype = record.field_type
value_fname = field_mapping.get(
ftype, ('old_value_char', 'new_value_char')
field_type, ('old_value_char', 'new_value_char')
)[bool(new)]
value = record[value_fname]
if ftype in {'integer', 'float', 'char', 'text', 'monetary'}:
if field_type in {'integer', 'float', 'char', 'text', 'monetary'}:
result.append(value)
elif ftype in {'date', 'datetime'}:
elif field_type in {'date', 'datetime'}:
if not record[value_fname]:
result.append(value)
elif ftype == 'date':
elif field_type == 'date':
result.append(fields.Date.to_string(value))
else:
result.append(f'{value}Z')
elif ftype == 'boolean':
elif field_type == 'boolean':
result.append(bool(value))
else:
result.append(value)
@@ -1,6 +1,7 @@
/* @odoo-module */
import { patch } from "@web/core/utils/patch";
import { capitalize } from "@web/core/utils/strings";
import { MockServer } from "@web/../tests/helpers/mock_server";
patch(MockServer.prototype, {
@@ -12,9 +13,13 @@ patch(MockServer.prototype, {
// creation of the ir.model.fields records, required for tracked fields
for (const modelName in this.models) {
const fieldNamesToFields = this.models[modelName].fields;
for (const fname in fieldNamesToFields) {
for (const [fname, field] of Object.entries(fieldNamesToFields)) {
if (fieldNamesToFields[fname].tracking) {
this.mockCreate("ir.model.fields", { model: modelName, name: fname });
this.mockCreate("ir.model.fields", {
model: modelName,
name: fname,
ttype: field.type,
});
}
}
}
@@ -44,25 +49,20 @@ patch(MockServer.prototype, {
const irField = this.models["ir.model.fields"].records.find(
(field) => field.model === modelName && field.name === fieldName
);
if (!irField) {
return;
}
const values = {
field: irField["id"],
field_desc: field["string"],
field_type: field["type"],
};
switch (values.field_type) {
const values = {field: irField.id};
switch (irField.ttype) {
case "char":
case "datetime":
case "float":
case "integer":
case "monetary":
case "text":
values[`old_value_${values.field_type}`] = initialValue;
values[`new_value_${values.field_type}`] = newValue;
values[`old_value_${irField.ttype}`] = initialValue;
values[`new_value_${irField.ttype}`] = newValue;
break;
case "date":
values["old_value_datetime"] = initialValue;
@@ -105,10 +105,10 @@ patch(MockServer.prototype, {
(field) => field.id === tracking.field
);
return {
changedField: tracking.field_desc,
changedField: capitalize(irField.ttype),
id: tracking.id,
fieldName: irField.name,
fieldType: tracking.field_type,
fieldType: irField.ttype,
newValue: {
value: this._mockMailTrackingValue_FormatDisplayValue(tracking, "new"),
},
@@ -123,12 +123,15 @@ patch(MockServer.prototype, {
* Simulates `_format_display_value` on `mail.tracking.value`
*/
_mockMailTrackingValue_FormatDisplayValue(record, type) {
switch (record.field_type) {
const irField = this.models["ir.model.fields"].records.find(
(field) => field.id === record.field
);
switch (irField.ttype) {
case "float":
case "integer":
case "monetary":
case "text":
return record[`${type}_value_${record.field_type}`];
return record[`${type}_value_${irField.ttype}`];
case "datetime":
if (record[`${type}_value_datetime`]) {
const datetime = record[`${type}_value_datetime`];
@@ -32,8 +32,6 @@
<sheet>
<group name="field_details" string="Field details">
<field name="field"/>
<field name="field_desc"/>
<field name="field_type"/>
</group>
<group name="values">
<group name="old_values" string="Old values">
-42
View File
@@ -304,20 +304,16 @@
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<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_desc">Stage</field>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">2</field>
<field name="new_value_integer">3</field>
<field name="mail_message_id" ref="project_1_task_2_mail_message_2"/>
@@ -354,20 +350,16 @@
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<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_desc">Stage</field>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">2</field>
<field name="new_value_integer">3</field>
<field name="mail_message_id" ref="project_1_task_3_mail_message_2"/>
@@ -404,20 +396,16 @@
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<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_desc">Stage</field>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">2</field>
<field name="new_value_integer">3</field>
<field name="mail_message_id" ref="project_1_task_4_mail_message_2"/>
@@ -446,10 +434,8 @@
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_1_task_5_mail_message_1"/>
@@ -489,10 +475,8 @@
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_1_task_6_mail_message_1"/>
@@ -529,10 +513,8 @@
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_1_task_7_mail_message_1"/>
@@ -563,10 +545,8 @@
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_1_task_8_mail_message_1"/>
@@ -747,10 +727,8 @@
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_2_task_1_mail_message_1"/>
@@ -765,10 +743,8 @@
</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_desc">Stage</field>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">2</field>
<field name="new_value_integer">3</field>
<field name="mail_message_id" ref="project_2_task_1_mail_message_2"/>
@@ -795,10 +771,8 @@
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_2_task_2_mail_message_1"/>
@@ -813,10 +787,8 @@
</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_desc">Stage</field>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">2</field>
<field name="new_value_integer">3</field>
<field name="mail_message_id" ref="project_2_task_2_mail_message_2"/>
@@ -844,10 +816,8 @@
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_2_task_3_mail_message_1"/>
@@ -910,10 +880,8 @@ Send it ASAP, its urgent.</field>
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_2_task_4_mail_message_1"/>
@@ -942,10 +910,8 @@ Send it ASAP, its urgent.</field>
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_2_task_5_mail_message_1"/>
@@ -972,10 +938,8 @@ Send it ASAP, its urgent.</field>
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_2_task_6_mail_message_1"/>
@@ -1004,10 +968,8 @@ Send it ASAP, its urgent.</field>
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_2_task_7_mail_message_1"/>
@@ -1022,10 +984,8 @@ Send it ASAP, its urgent.</field>
</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_desc">Stage</field>
<field name="old_value_char">In Progress</field>
<field name="new_value_char">Done</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">2</field>
<field name="new_value_integer">3</field>
<field name="mail_message_id" ref="project_2_task_7_mail_message_2"/>
@@ -1054,10 +1014,8 @@ Send it ASAP, its urgent.</field>
</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_desc">Stage</field>
<field name="old_value_char">New</field>
<field name="new_value_char">In Progress</field>
<field name="field_type">many2one</field>
<field name="old_value_integer">1</field>
<field name="new_value_integer">2</field>
<field name="mail_message_id" ref="project_2_task_8_mail_message_1"/>
@@ -854,13 +854,11 @@ class TestMailComplexPerformance(BaseMailPerformance):
'tracking_value_ids': [
(0, 0, {
'field': name_field.id,
'field_desc': 'Name',
'new_value_char': 'new 0',
'old_value_char': 'old 0',
}),
(0, 0, {
'field': customer_id_field.id,
'field_desc': 'Customer',
'new_value_char': 'new 1',
'new_value_integer': cls.partners[(record_idx * 5)].id,
'old_value_char': 'old 1',