[IMP] mail : Add possiblities to sequence tracking fields in the chatter
Fields in the chatter can be organized with a business logic. Here fields for CRM and Website E-commerce have a tracking sequence. For other fields/module just add "track_sequence=x" on model
This commit is contained in:
committed by
Yannick Tivisse
parent
9c9215fef2
commit
ec35eca7c6
@@ -63,23 +63,23 @@ class Lead(models.Model):
|
|||||||
return self._stage_find(team_id=team.id, domain=[('fold', '=', False)]).id
|
return self._stage_find(team_id=team.id, domain=[('fold', '=', False)]).id
|
||||||
|
|
||||||
name = fields.Char('Opportunity', required=True, index=True)
|
name = fields.Char('Opportunity', required=True, index=True)
|
||||||
partner_id = fields.Many2one('res.partner', string='Customer', track_visibility='onchange', index=True,
|
partner_id = fields.Many2one('res.partner', string='Customer', track_visibility='onchange', track_sequence=1, index=True,
|
||||||
help="Linked partner (optional). Usually created when converting the lead.")
|
help="Linked partner (optional). Usually created when converting the lead.")
|
||||||
active = fields.Boolean('Active', default=True)
|
active = fields.Boolean('Active', default=True)
|
||||||
date_action_last = fields.Datetime('Last Action', readonly=True)
|
date_action_last = fields.Datetime('Last Action', readonly=True)
|
||||||
email_from = fields.Char('Email', help="Email address of the contact", index=True)
|
email_from = fields.Char('Email', help="Email address of the contact", track_visibility='onchange', track_sequence=4, index=True)
|
||||||
website = fields.Char('Website', index=True, help="Website of the contact")
|
website = fields.Char('Website', index=True, help="Website of the contact")
|
||||||
team_id = fields.Many2one('crm.team', string='Sales Channel', oldname='section_id', default=lambda self: self.env['crm.team'].sudo()._get_default_team_id(user_id=self.env.uid),
|
team_id = fields.Many2one('crm.team', string='Sales Channel', oldname='section_id', default=lambda self: self.env['crm.team'].sudo()._get_default_team_id(user_id=self.env.uid),
|
||||||
index=True, track_visibility='onchange', help='When sending mails, the default email address is taken from the sales channel.')
|
index=True, track_visibility='onchange', help='When sending mails, the default email address is taken from the sales channel.')
|
||||||
kanban_state = fields.Selection([('grey', 'No next activity planned'), ('red', 'Next activity late'), ('green', 'Next activity is planned')],
|
kanban_state = fields.Selection([('grey', 'No next activity planned'), ('red', 'Next activity late'), ('green', 'Next activity is planned')],
|
||||||
string='Kanban State', compute='_compute_kanban_state')
|
string='Kanban State', compute='_compute_kanban_state')
|
||||||
email_cc = fields.Text('Global CC', help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma")
|
email_cc = fields.Text('Global CC', help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma")
|
||||||
description = fields.Text('Notes')
|
description = fields.Text('Notes', track_visibility='onchange', track_sequence=6)
|
||||||
create_date = fields.Datetime('Create Date', readonly=True)
|
create_date = fields.Datetime('Create Date', readonly=True)
|
||||||
write_date = fields.Datetime('Update Date', readonly=True)
|
write_date = fields.Datetime('Update Date', readonly=True)
|
||||||
tag_ids = fields.Many2many('crm.lead.tag', 'crm_lead_tag_rel', 'lead_id', 'tag_id', string='Tags', help="Classify and analyze your lead/opportunity categories like: Training, Service")
|
tag_ids = fields.Many2many('crm.lead.tag', 'crm_lead_tag_rel', 'lead_id', 'tag_id', string='Tags', help="Classify and analyze your lead/opportunity categories like: Training, Service")
|
||||||
contact_name = fields.Char('Contact Name')
|
contact_name = fields.Char('Contact Name', track_visibility='onchange', track_sequence=3)
|
||||||
partner_name = fields.Char("Customer Name", index=True, help='The name of the future partner company that will be created while converting the lead into opportunity')
|
partner_name = fields.Char("Customer Name", track_visibility='onchange', track_sequence=2, index=True, help='The name of the future partner company that will be created while converting the lead into opportunity')
|
||||||
opt_out = fields.Boolean(string='Opt-Out', oldname='optout',
|
opt_out = fields.Boolean(string='Opt-Out', oldname='optout',
|
||||||
help="If opt-out is checked, this contact has refused to receive emails for mass mailing and marketing campaign. "
|
help="If opt-out is checked, this contact has refused to receive emails for mass mailing and marketing campaign. "
|
||||||
"Filter 'Available for Mass Mailing' allows users to filter the leads when performing mass mailing.")
|
"Filter 'Available for Mass Mailing' allows users to filter the leads when performing mass mailing.")
|
||||||
@@ -124,7 +124,7 @@ class Lead(models.Model):
|
|||||||
city = fields.Char('City')
|
city = fields.Char('City')
|
||||||
state_id = fields.Many2one("res.country.state", string='State')
|
state_id = fields.Many2one("res.country.state", string='State')
|
||||||
country_id = fields.Many2one('res.country', string='Country')
|
country_id = fields.Many2one('res.country', string='Country')
|
||||||
phone = fields.Char('Phone')
|
phone = fields.Char('Phone', track_visibility='onchange', track_sequence=5)
|
||||||
mobile = fields.Char('Mobile')
|
mobile = fields.Char('Mobile')
|
||||||
function = fields.Char('Job Position')
|
function = fields.Char('Job Position')
|
||||||
title = fields.Many2one('res.partner.title')
|
title = fields.Many2one('res.partner.title')
|
||||||
|
|||||||
@@ -592,7 +592,8 @@ class MailThread(models.AbstractModel):
|
|||||||
new_value = getattr(self, col_name)
|
new_value = getattr(self, col_name)
|
||||||
|
|
||||||
if new_value != initial_value and (new_value or initial_value): # because browse null != False
|
if new_value != initial_value and (new_value or initial_value): # because browse null != False
|
||||||
tracking = self.env['mail.tracking.value'].create_tracking_values(initial_value, new_value, col_name, col_info)
|
track_sequence = getattr(self._fields[col_name], 'track_sequence', 100)
|
||||||
|
tracking = self.env['mail.tracking.value'].create_tracking_values(initial_value, new_value, col_name, col_info, track_sequence)
|
||||||
if tracking:
|
if tracking:
|
||||||
tracking_value_ids.append([0, 0, tracking])
|
tracking_value_ids.append([0, 0, tracking])
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ from odoo import api, fields, models, tools
|
|||||||
class MailTracking(models.Model):
|
class MailTracking(models.Model):
|
||||||
_name = 'mail.tracking.value'
|
_name = 'mail.tracking.value'
|
||||||
_description = 'Mail Tracking Value'
|
_description = 'Mail Tracking Value'
|
||||||
|
_order = 'track_sequence asc'
|
||||||
|
|
||||||
# TDE CLEANME: why not a m2o to ir model field ?
|
# TDE CLEANME: why not a m2o to ir model field ?
|
||||||
field = fields.Char('Changed Field', required=True, readonly=1)
|
field = fields.Char('Changed Field', required=True, readonly=1)
|
||||||
@@ -31,10 +32,12 @@ class MailTracking(models.Model):
|
|||||||
|
|
||||||
mail_message_id = fields.Many2one('mail.message', 'Message ID', required=True, index=True, ondelete='cascade')
|
mail_message_id = fields.Many2one('mail.message', 'Message ID', required=True, index=True, ondelete='cascade')
|
||||||
|
|
||||||
|
track_sequence = fields.Integer('Tracking field sequence', readonly=1, default=100)
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def create_tracking_values(self, initial_value, new_value, col_name, col_info):
|
def create_tracking_values(self, initial_value, new_value, col_name, col_info, track_sequence):
|
||||||
tracked = True
|
tracked = True
|
||||||
values = {'field': col_name, 'field_desc': col_info['string'], 'field_type': col_info['type']}
|
values = {'field': col_name, 'field_desc': col_info['string'], 'field_type': col_info['type'], 'track_sequence': track_sequence}
|
||||||
|
|
||||||
if col_info['type'] in ['integer', 'float', 'char', 'text', 'datetime', 'monetary']:
|
if col_info['type'] in ['integer', 'float', 'char', 'text', 'datetime', 'monetary']:
|
||||||
values.update({
|
values.update({
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
<field name="new_value_char"/>
|
<field name="new_value_char"/>
|
||||||
<field name="new_value_text"/>
|
<field name="new_value_text"/>
|
||||||
<field name="new_value_datetime"/>
|
<field name="new_value_datetime"/>
|
||||||
|
<field name="track_sequence"/>
|
||||||
</group>
|
</group>
|
||||||
<group string='Related Message'>
|
<group string='Related Message'>
|
||||||
<field name="mail_message_id"/>
|
<field name="mail_message_id"/>
|
||||||
|
|||||||
@@ -122,15 +122,15 @@ class SaleOrder(models.Model):
|
|||||||
('sale', 'Sales Order'),
|
('sale', 'Sales Order'),
|
||||||
('done', 'Locked'),
|
('done', 'Locked'),
|
||||||
('cancel', 'Cancelled'),
|
('cancel', 'Cancelled'),
|
||||||
], string='Status', readonly=True, copy=False, index=True, track_visibility='onchange', default='draft')
|
], string='Status', readonly=True, copy=False, index=True, track_visibility='onchange', track_sequence=3, default='draft')
|
||||||
date_order = fields.Datetime(string='Order Date', required=True, readonly=True, index=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, copy=False, default=fields.Datetime.now)
|
date_order = fields.Datetime(string='Order Date', required=True, readonly=True, index=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, copy=False, default=fields.Datetime.now)
|
||||||
validity_date = fields.Date(string='Quote Validity', readonly=True, copy=False, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
|
validity_date = fields.Date(string='Quote Validity', readonly=True, copy=False, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
|
||||||
help="Validity date of the quotation, after this date, the customer won't be able to validate the quotation online.")
|
help="Validity date of the quotation, after this date, the customer won't be able to validate the quotation online.")
|
||||||
is_expired = fields.Boolean(compute='_compute_is_expired', string="Is expired")
|
is_expired = fields.Boolean(compute='_compute_is_expired', string="Is expired")
|
||||||
create_date = fields.Datetime(string='Creation Date', readonly=True, index=True, help="Date on which sales order is created.")
|
create_date = fields.Datetime(string='Creation Date', readonly=True, index=True, help="Date on which sales order is created.")
|
||||||
confirmation_date = fields.Datetime(string='Confirmation Date', readonly=True, index=True, help="Date on which the sales order is confirmed.", oldname="date_confirm", copy=False)
|
confirmation_date = fields.Datetime(string='Confirmation Date', readonly=True, index=True, help="Date on which the sales order is confirmed.", oldname="date_confirm", copy=False)
|
||||||
user_id = fields.Many2one('res.users', string='Salesperson', index=True, track_visibility='onchange', default=lambda self: self.env.user)
|
user_id = fields.Many2one('res.users', string='Salesperson', index=True, track_visibility='onchange', track_sequence=2, default=lambda self: self.env.user)
|
||||||
partner_id = fields.Many2one('res.partner', string='Customer', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, required=True, change_default=True, index=True, track_visibility='always')
|
partner_id = fields.Many2one('res.partner', string='Customer', readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, required=True, change_default=True, index=True, track_visibility='always', track_sequence=1)
|
||||||
partner_invoice_id = fields.Many2one('res.partner', string='Invoice Address', readonly=True, required=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]}, help="Invoice address for current sales order.")
|
partner_invoice_id = fields.Many2one('res.partner', string='Invoice Address', readonly=True, required=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]}, help="Invoice address for current sales order.")
|
||||||
partner_shipping_id = fields.Many2one('res.partner', string='Delivery Address', readonly=True, required=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]}, help="Delivery address for current sales order.")
|
partner_shipping_id = fields.Many2one('res.partner', string='Delivery Address', readonly=True, required=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]}, help="Delivery address for current sales order.")
|
||||||
|
|
||||||
@@ -151,9 +151,9 @@ class SaleOrder(models.Model):
|
|||||||
|
|
||||||
note = fields.Text('Terms and conditions', default=_default_note)
|
note = fields.Text('Terms and conditions', default=_default_note)
|
||||||
|
|
||||||
amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, readonly=True, compute='_amount_all', track_visibility='onchange')
|
amount_untaxed = fields.Monetary(string='Untaxed Amount', store=True, readonly=True, compute='_amount_all', track_visibility='onchange', track_sequence=5)
|
||||||
amount_tax = fields.Monetary(string='Taxes', store=True, readonly=True, compute='_amount_all')
|
amount_tax = fields.Monetary(string='Taxes', store=True, readonly=True, compute='_amount_all')
|
||||||
amount_total = fields.Monetary(string='Total', store=True, readonly=True, compute='_amount_all', track_visibility='always')
|
amount_total = fields.Monetary(string='Total', store=True, readonly=True, compute='_amount_all', track_visibility='always', track_sequence=6)
|
||||||
|
|
||||||
payment_term_id = fields.Many2one('account.payment.term', string='Payment Terms', oldname='payment_term')
|
payment_term_id = fields.Many2one('account.payment.term', string='Payment Terms', oldname='payment_term')
|
||||||
fiscal_position_id = fields.Many2one('account.fiscal.position', oldname='fiscal_position', string='Fiscal Position')
|
fiscal_position_id = fields.Many2one('account.fiscal.position', oldname='fiscal_position', string='Fiscal Position')
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ class MailTestFull(models.Model):
|
|||||||
count = fields.Integer(default=1)
|
count = fields.Integer(default=1)
|
||||||
datetime = fields.Datetime(default=fields.Datetime.now)
|
datetime = fields.Datetime(default=fields.Datetime.now)
|
||||||
mail_template = fields.Many2one('mail.template', 'Template')
|
mail_template = fields.Many2one('mail.template', 'Template')
|
||||||
customer_id = fields.Many2one('res.partner', 'Customer', track_visibility='onchange')
|
customer_id = fields.Many2one('res.partner', 'Customer', track_visibility='onchange', track_sequence=2)
|
||||||
user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange')
|
user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange', track_sequence=1)
|
||||||
umbrella_id = fields.Many2one('mail.test', track_visibility='onchange')
|
umbrella_id = fields.Many2one('mail.test', track_visibility='onchange')
|
||||||
|
|
||||||
def _track_template(self, tracking):
|
def _track_template(self, tracking):
|
||||||
|
|||||||
@@ -116,3 +116,18 @@ class TestTracking(common.BaseFunctionalTest, common.MockEmails):
|
|||||||
self.record.message_ids[1],
|
self.record.message_ids[1],
|
||||||
[('customer_id', 'many2one', False, self.user_admin.partner_id) # onchange tracked field
|
[('customer_id', 'many2one', False, self.user_admin.partner_id) # onchange tracked field
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def test_message_track_sequence(self):
|
||||||
|
""" Update some tracked fields and check that the mail.tracking.value are ordered according to their track_sequence"""
|
||||||
|
self.record.write({
|
||||||
|
'name': 'Zboub',
|
||||||
|
'customer_id': self.user_admin.partner_id.id,
|
||||||
|
'user_id': self.user_admin.id,
|
||||||
|
'umbrella_id': self.env['mail.test'].with_context(mail_create_nosubscribe=True).create({'name': 'Umbrella'}).id
|
||||||
|
})
|
||||||
|
self.assertEqual(len(self.record.message_ids), 1, 'should have 1 tracking message')
|
||||||
|
|
||||||
|
tracking_values = self.env['mail.tracking.value'].search([('mail_message_id', '=', self.record.message_ids.id)])
|
||||||
|
self.assertEqual(tracking_values[0].track_sequence, 1)
|
||||||
|
self.assertEqual(tracking_values[1].track_sequence, 2)
|
||||||
|
self.assertEqual(tracking_values[2].track_sequence, 100)
|
||||||
|
|||||||
Reference in New Issue
Block a user