diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 17922dde265..9cb195d54ed 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -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 diff --git a/addons/mail/models/mail_tracking_value.py b/addons/mail/models/mail_tracking_value.py index 17dbc569363..9bd56e3be79 100644 --- a/addons/mail/models/mail_tracking_value.py +++ b/addons/mail/models/mail_tracking_value.py @@ -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) diff --git a/addons/mail/static/tests/helpers/mock_server/models/mail_tracking_value.js b/addons/mail/static/tests/helpers/mock_server/models/mail_tracking_value.js index d64af76e7c6..f8c9b450a0a 100644 --- a/addons/mail/static/tests/helpers/mock_server/models/mail_tracking_value.js +++ b/addons/mail/static/tests/helpers/mock_server/models/mail_tracking_value.js @@ -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`]; diff --git a/addons/mail/views/mail_tracking_value_views.xml b/addons/mail/views/mail_tracking_value_views.xml index 1d6cb2769cc..d9fe1b47e25 100644 --- a/addons/mail/views/mail_tracking_value_views.xml +++ b/addons/mail/views/mail_tracking_value_views.xml @@ -32,8 +32,6 @@ - - diff --git a/addons/project/data/project_demo.xml b/addons/project/data/project_demo.xml index 27a2d62fa16..b562716dadd 100644 --- a/addons/project/data/project_demo.xml +++ b/addons/project/data/project_demo.xml @@ -304,20 +304,16 @@ - Stage New In Progress - many2one 1 2 - Stage In Progress Done - many2one 2 3 @@ -354,20 +350,16 @@ - Stage New In Progress - many2one 1 2 - Stage In Progress Done - many2one 2 3 @@ -404,20 +396,16 @@ - Stage New In Progress - many2one 1 2 - Stage In Progress Done - many2one 2 3 @@ -446,10 +434,8 @@ - Stage New In Progress - many2one 1 2 @@ -489,10 +475,8 @@ - Stage New In Progress - many2one 1 2 @@ -529,10 +513,8 @@ - Stage New In Progress - many2one 1 2 @@ -563,10 +545,8 @@ - Stage New In Progress - many2one 1 2 @@ -747,10 +727,8 @@ - Stage New In Progress - many2one 1 2 @@ -765,10 +743,8 @@ - Stage In Progress Done - many2one 2 3 @@ -795,10 +771,8 @@ - Stage New In Progress - many2one 1 2 @@ -813,10 +787,8 @@ - Stage In Progress Done - many2one 2 3 @@ -844,10 +816,8 @@ - Stage New In Progress - many2one 1 2 @@ -910,10 +880,8 @@ Send it ASAP, its urgent. - Stage New In Progress - many2one 1 2 @@ -942,10 +910,8 @@ Send it ASAP, its urgent. - Stage New In Progress - many2one 1 2 @@ -972,10 +938,8 @@ Send it ASAP, its urgent. - Stage New In Progress - many2one 1 2 @@ -1004,10 +968,8 @@ Send it ASAP, its urgent. - Stage New In Progress - many2one 1 2 @@ -1022,10 +984,8 @@ Send it ASAP, its urgent. - Stage In Progress Done - many2one 2 3 @@ -1054,10 +1014,8 @@ Send it ASAP, its urgent. - Stage New In Progress - many2one 1 2 diff --git a/addons/test_mail/tests/test_performance.py b/addons/test_mail/tests/test_performance.py index fe45a0cfbcc..08f7b90f0fa 100644 --- a/addons/test_mail/tests/test_performance.py +++ b/addons/test_mail/tests/test_performance.py @@ -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',