In the odoo Sales menu, if you open the Quotation or Order menu, at the very bottom of the form there will be a block. If you make changes to the sales order form, for example changing the customer name, changing the price, etc, the changes will be recorded in that block. As shown below.
![The view of the data changes history in the odoo sales menu](https://en.ngasturi.id/wp-content/uploads/2021/02/data_change_history_in_odoo_sales_menu.png)
That block is usually called a Chatter (I don’t know what the official name is, but in the odoo forum it’s called like that). In this tutorial, I will share how to add a chatter to a form to record the data changes, so we can know who made the changes and when the changes were made.
To be able to record the data changes, the model that we create must inherit several models. Also, we have to manually mark which fields if the data changes, the changes will be recorded, because by default odoo doesn’t do it. Please take a look at the code below.
# -*- coding: utf-8 -*- from odoo import api, fields, models, exceptions, _ class MyService(models.Model): _name = 'my.service' # You are recommended to fill in the _description # fill in with an appropriate name, so it will easier when we read the chatter _description = 'Service' # this part is mandatory if you want the chatter functionality _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin'] # pay attention to the track_visibility parameter name = fields.Char('Service Number', track_visibility='onchange') customer = fields.Many2one('res.partner','Customer', track_visibility='onchange') date = fields.Date('Date') service_detail = fields.One2many('my.service.detail', 'service_id') class MyServiceDetail(models.Model): _name = 'my.service.detail' # You are recommended to fill in the _description # fill in with an appropriate name, so it will easier when we read the chatter _description = 'Service Detail' # this part is mandatory if you want the chatter functionality _inherit = ['portal.mixin', 'mail.thread', 'mail.activity.mixin'] # pay attention to the track_visibility parameter product = fields.Many2one('product.product', 'Product', track_visibility='onchange') customer_complaint = fields.Char('Customer Complaint', track_visibility='onchange') warranty = fields.Boolean('Warranty') service_id = fields.Many2one('my.service')
The model that we create must inherit to these three models => portal.mixin, mail.thread, and mail.activity.mixin to use the chatter functionality.
Then insert the track_visibility parameter in the field that you want to record the data changes if its value changed. There are two choices that you can use, it is onchange and always.
Update !!!
Since odoo version 13, the track_visibility parameter is no longer can be used. Instead, odoo create a new parameter, namely tracking. With the value of choice of True or False. If the value is True, if the data in that field changes, odoo will record the changes. So the code above in odoo version 13 and newer can be written like this.
name = fields.Char('Service Number', tracking=True)
Meanwhile, the _description is not mandatory. But it would be nice if you fill it.
Furthermore, to see the data changes in the form, we must display several fields from the portal.mixin, mail.thread, and mail.activity.mixin model like in the code below.
<!-- the main service form --> <record id="service_form" model="ir.ui.view"> <field name="name">Service Form</field> <field name="model">my.service</field> <field name="type">form</field> <field name="arch" type="xml"> <form> <sheet> <group> <group> <field name="name" /> </group> <group> <field name="customer" /> <field name="date" /> </group> </group> <notebook> <page string="Detail"> <field name="service_detail"> <tree editable="bottom"> <field name="product" /> <field name="customer_complaint" /> <field name="warranty" /> </tree> </field> </page> </notebook> </sheet> <!-- the above part is a normal Odoo view --> <!-- the section below is the code to display the chatter --> <div class="oe_chatter"> <field name="message_follower_ids" widget="mail_followers"/> <field name="activity_ids" widget="mail_activity"/> <field name="message_ids" widget="mail_thread"/> </div> </form> </field> </record> <!-- the form service detail, if a user clicks on the data in the Detail tab this form will be opened --> <record id="service_detail_form" model="ir.ui.view"> <field name="name">Service Detail Form</field> <field name="model">my.service.detail</field> <field name="type">form</field> <field name="arch" type="xml"> <form> <sheet> <group> <group> <field name="product" /> </group> <group> <field name="customer_complaint" /> <field name="warranty" /> </group> </group> </sheet> <!-- the above part is a normal Odoo view --> <!-- the section below is the code to display the chatter --> <!-- because this form is called in a modal, don't use the oe_chatter class. if you use this class the chatter will not appear in the modal. --> <div class="oe_chatter"> <field name="message_follower_ids" widget="mail_followers"/> <field name="activity_ids" widget="mail_activity"/> <field name="message_ids" widget="mail_thread"/> </div> </form> </field> </record>
To display the chatter function, you just need to add a div block with the oe_chatter class and some fields from the portal.mixin, mail.thread, and mail.activity.mixin models.
If your form or model is opened in a modal, like the form service detail above, don’t use the oe_chatter class. Just enough to write the fields only. Because if you use it, the chatter will not appear.
This is the view of the detailed service form opened in a modal. You can see that the chatter does not appear even though we have added some fields from the portal.mixin, mail.thread, and mail.activity.mixin model in the service_detail_form view.
![An odoo modal without chatter](https://en.ngasturi.id/wp-content/uploads/2021/02/odoo_modal_without_chatter.png)
Meanwhile, if we remove the oe_chatter class like the code below.
<!-- the form service detail, if a user clicks on the data in the Detail tab this form will be opened --> <record id="service_detail_form" model="ir.ui.view"> <field name="name">Service Detail Form</field> <field name="model">my.service.detail</field> <field name="type">form</field> <field name="arch" type="xml"> <form> <sheet> <group> <group> <field name="product" /> </group> <group> <field name="customer_complaint" /> <field name="warranty" /> </group> </group> </sheet> <!-- the above part is a normal Odoo view --> <!-- the section below is the code to display the chatter --> <!-- because this form is called in a modal, don't use the oe_chatter class. if you use this class the chatter will not appear in the modal. --> <!-- the oe_chatter is removed --> <div> <field name="message_follower_ids" widget="mail_followers"/> <field name="activity_ids" widget="mail_activity"/> <field name="message_ids" widget="mail_thread"/> </div> </form> </field> </record>
The chatter will appear as shown in the image below.
![An odoo modal with chatter](https://en.ngasturi.id/wp-content/uploads/2021/02/odoo_modal_with_chatter.png)
The difference between using the oe_chatter class and not is that if you use the oe_chatter class you can add a note/log manually, but the chatter does not appear if it is opened via a modal. Meanwhile, if you don’t use the oe_chatter class, the chatter function will still appear if you open it via a modal but can’t add a note/log manually.
![An odoo chatter with Log Note button](https://en.ngasturi.id/wp-content/uploads/2021/02/odoo_chatter_with_log_note.png)
The picture above shows a form with the oe_chatter class, so the Log Note buttons appear. You can click the Log Note button to add a message manually.
Meanwhile, if we remove the oe_chatter class the Log Note button will disappear as shown below.
![An odoo chatter without Log Note button](https://en.ngasturi.id/wp-content/uploads/2021/02/odoo_chatter_without_log_note.png)
Update !!!
I have created an addon so that the chatter in a modal will still appear without removing the oe_chatter class, please read here.
One Reply on “How to Record the Data Changes in Odoo”
I tried to show 2 oe_chatter on 1 view but it only shows 1. Please help me with this paragraph