Odoo Chatter Tracking fields provide developers and users with valuable insights into data changes within the platform. When you need to understand which fields are being tracked in Odoo’s chatter functionality, several methods exist to identify and customize this behavior. Furthermore, tracking field changes in Odoo’s chatter system allows businesses to maintain comprehensive audit trails and improve collaboration across teams.
Understanding Odoo’s Chatter System
Odoo Chatter Tracking. Before diving into tracked fields, it’s essential to understand what the chatter system is and how it functions across the Odoo platform.
What is the Odoo Chatter?
The chatter is Odoo’s integrated communication tool that appears at the bottom of many record forms. Additionally, it serves two primary functions:
- Communication: Allows users to post messages, mention colleagues, and attach files
- Tracking: Automatically records changes to specified fields in the record
Therefore, the chatter creates a chronological history of both manual communications and system-tracked changes, making it easier to understand a record’s history at a glance.
How Field Tracking Works in Odoo
Field tracking in Odoo works by monitoring specific fields for changes and automatically generating messages in the chatter when those changes occur. Moreover, this tracking happens at the database level and is configured in the model definition itself.
When a tracked field changes value, Odoo:
- Captures the old value
- Records the new value
- Creates a message showing both values
- Posts this message to the chatter
Consequently, users can see a complete history of important changes without manually documenting them.
Finding Tracked Fields in Odoo
Odoo Chatter Tracking. There are several methods to identify which fields are being tracked in Odoo’s chatter system. Let’s explore these approaches in detail.
Method 1: Using the Developer Mode Interface
The easiest way to check which fields are tracked is through Odoo’s interface while in developer mode. Here’s how:
- Activate developer mode in your Odoo instance
- Navigate to the record type you want to check (e.g., Sales Orders, Invoices)
- Click on “Edit” for any record
- Click “Show fields” in the developer toolbar
- Filter by “Tracking: On”
As a result, you’ll see all fields that are configured for tracking in the chatter. For example, on invoices, you might find around 20 tracked fields including status, payment state, and reference numbers.
Method 2: Examining the Database Structure
For a more technical approach, you can examine the message records directly in the database:
- Access the
mail_messagetable in your Odoo database - Filter for messages with
tracking_value_idsthat are not empty - Check the related
mail_tracking_valuerecords to see which fields are being tracked
Furthermore, this method allows you to see the actual data structure used for tracking changes and can help in understanding the underlying mechanism.
Method 3: Reviewing the Python Model Definition
For developers, the most direct method is to examine the Python model definition:
class SaleOrder(models.Model):
_name = 'sale.order'
_inherit = ['mail.thread', 'mail.activity.mixin']
name = fields.Char(string='Order Reference', tracking=True)
state = fields.Selection([
('draft', 'Quotation'),
('sent', 'Quotation Sent'),
('sale', 'Sales Order'),
('done', 'Locked'),
('cancel', 'Cancelled'),
], string='Status', tracking=True, default='draft')
partner_id = fields.Many2one('res.partner', tracking=True)
# Other fields...
In this example, the tracking=True parameter indicates fields that will be tracked in the chatter. Therefore, by reviewing the model code, you can definitively identify all tracked fields.
Customizing Field Tracking in Odoo
Once you understand which fields are tracked, you may want to customize this behavior for your specific needs.
Adding Tracking to Existing Fields
To add tracking to an existing field, you have two options:
Option 1: Using Odoo Studio (No Development Required)
If you have Odoo Studio enabled:
- Enter Edit mode for the model you want to modify
- Open the field properties using Studio
- Check the “Track Changes” option
- Save your changes
For example, if you have a custom field on the customer model that you want to track changes for, this method allows you to enable tracking without writing code.
Option 2: Through Python Inheritance (For Developers)
For a more permanent solution, you can extend the model in Python:
class SaleOrderInherit(models.Model):
_inherit = 'sale.order'
# Add tracking to an existing field
commitment_date = fields.Datetime(tracking=True)
# Create a new tracked field
custom_reference = fields.Char(string='Custom Reference', tracking=True)
Moreover, this approach allows you to version-control your tracking configurations and deploy them across multiple environments.
Removing Tracking from Fields
Similarly, you might want to disable tracking for certain fields to reduce chatter noise:
class AccountMoveInherit(models.Model):
_inherit = 'account.move'
# Override the field definition to remove tracking
invoice_date = fields.Date(string='Invoice/Bill Date', tracking=False)
As a result, changes to the invoice date would no longer generate messages in the chatter.
Advanced Tracking Features in Odoo
Beyond basic field tracking, Odoo offers several advanced features for monitoring changes.
Tracking Many2one Field Changes
When tracking Many2one relationship fields, Odoo provides additional information in the chatter:
class SaleOrder(models.Model):
_inherit = 'sale.order'
partner_id = fields.Many2one('res.partner', tracking=True)
In this case, when the customer changes, Odoo will show both the previous and new customer names in the chatter. Furthermore, it links to both records, allowing quick navigation.
Tracking Selection Field States
For selection fields like status fields, tracking is particularly useful:
class SaleOrder(models.Model):
_inherit = 'sale.order'
state = fields.Selection([
('draft', 'Quotation'),
('sent', 'Quotation Sent'),
('sale', 'Sales Order'),
('done', 'Locked'),
('cancel', 'Cancelled'),
], string='Status', tracking=True, default='draft')
Consequently, each status change generates a clear message in the chatter, creating a visual workflow history for the record.
Tracking Numeric and Boolean Fields
Numeric and boolean fields can also be tracked, providing insights into quantitative changes:
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
product_uom_qty = fields.Float(string='Quantity', tracking=True)
price_unit = fields.Float(string='Unit Price', tracking=True)
is_downpayment = fields.Boolean(string='Is a Downpayment', tracking=True)
As a result, price adjustments, quantity changes, and toggle state modifications are all recorded in the chatter history.
Practical Use Cases for Tracked Fields
Understanding how to implement tracked fields opens up several practical applications for businesses.
Audit Trail for Critical Business Documents
By tracking fields on invoices, orders, and contracts, you create an automatic audit trail:
class AccountMove(models.Model):
_inherit = 'account.move'
amount_total = fields.Monetary(tracking=True)
payment_state = fields.Selection([
('not_paid', 'Not Paid'),
('in_payment', 'In Payment'),
('paid', 'Paid'),
('partial', 'Partially Paid'),
('reversed', 'Reversed'),
('invoicing_legacy', 'Invoicing App Legacy'),
], string="Payment Status", tracking=True)
partner_id = fields.Many2one(tracking=True)
For instance, tracking payment status changes helps accounting teams monitor payment progression without manual logging.
Monitoring Price and Discount Changes
For sales teams, tracking pricing fields helps maintain accountability:
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
price_unit = fields.Float(tracking=True)
discount = fields.Float(tracking=True)
Therefore, any price adjustments or special discounts are automatically documented, creating transparency in the sales process.
Tracking Approval Workflows
For approval-based processes, tracking status and responsible persons is valuable:
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
state = fields.Selection([
('draft', 'RFQ'),
('sent', 'RFQ Sent'),
('to approve', 'To Approve'),
('purchase', 'Purchase Order'),
('done', 'Locked'),
('cancel', 'Cancelled')
], tracking=True)
user_id = fields.Many2one('res.users', tracking=True)
approval_date = fields.Date(tracking=True)
As a result, each step in the approval process is documented with timestamps and responsible users, creating accountability.
Leveraging the Tracking Data for Reporting
The tracking data stored in Odoo can be used for analytical purposes as well.
Accessing Tracking Data Programmatically
You can access tracking data programmatically through the mail.tracking.value model:
def get_field_change_history(self, model_name, record_id, field_name):
# Get messages with tracking values for this record
messages = self.env['mail.message'].search([
('model', '=', model_name),
('res_id', '=', record_id),
('tracking_value_ids', '!=', False)
])
# Filter tracking values for the specific field
tracking_values = self.env['mail.tracking.value'].search([
('mail_message_id', 'in', messages.ids),
('field', '=', field_name)
])
return tracking_values
Furthermore, this allows you to build custom reports showing how specific fields change over time across your database.
Creating Change Frequency Reports
With the tracking data, you can analyze which fields change most frequently:
def field_change_frequency(self, model_name, days=30):
# Find messages with tracking from last X days
date_limit = fields.Datetime.now() - timedelta(days=days)
messages = self.env['mail.message'].search([
('model', '=', model_name),
('tracking_value_ids', '!=', False),
('date', '>=', date_limit)
])
# Count changes by field
field_counts = {}
for message in messages:
for tracking in message.tracking_value_ids:
field_name = tracking.field
field_counts[field_name] = field_counts.get(field_name, 0) + 1
return sorted(field_counts.items(), key=lambda x: x[1], reverse=True)
As a result, you can identify which fields are most volatile and may require additional attention or workflow adjustments.
Best Practices for Field Tracking in Odoo
After understanding how tracking works, it’s important to follow best practices for implementation.
Only Track Meaningful Fields
While tracking is useful, too much tracking creates noise. Therefore, focus on fields that have business significance:
class ProjectTask(models.Model):
_inherit = 'project.task'
# Track important fields
stage_id = fields.Many2one(tracking=True) # Task stage is important to track
user_id = fields.Many2one(tracking=True) # Assigned user changes are important
# Don't track fields that change frequently with little value
# sequence = fields.Integer(tracking=True) # Avoid tracking this
# color = fields.Integer(tracking=True) # Avoid tracking this
Consequently, your chatter will contain relevant information without overwhelming users with trivial updates.
Group Related Field Changes
When multiple related fields change together, consider using the write method to group these changes:
def update_pricing(self):
# Instead of setting these fields individually, which would create
# multiple tracking messages, group them in a single write
self.write({
'price_unit': self.calculated_price,
'discount': self.calculated_discount,
'tax_id': [(6, 0, self.applicable_tax_ids.ids)]
})
# This creates a single change event in the chatter
Moreover, this approach keeps the chatter cleaner and provides better context for the changes.
Document Tracking Decisions
When implementing custom tracking, document your decisions:
class CustomModel(models.Model):
_name = 'custom.model'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = 'Custom Model'
# Track status changes for compliance requirements (SOX Section 404)
state = fields.Selection([
('draft', 'Draft'),
('approved', 'Approved'),
('rejected', 'Rejected')
], tracking=True)
# Track amount changes for audit purposes
amount = fields.Monetary(tracking=True) # Required by finance department
# Don't track these fields as they change frequently
# last_computation_date = fields.Datetime()
# sequence = fields.Integer()
As a result, future developers will understand why certain fields are tracked while others are not.
Troubleshooting Tracking Issues
Even with proper configuration, you might encounter issues with field tracking.
Field Changes Not Appearing in Chatter
If field changes aren’t appearing in the chatter, check the following:
- Verify the field has
tracking=Truein its definition - Ensure the model inherits from
mail.thread - Check if changes are being made through the ORM (direct SQL won’t trigger tracking)
- Verify the user has access rights to see the chatter messages
For example, the model definition should look like:
class SampleModel(models.Model):
_name = 'sample.model'
_inherit = ['mail.thread', 'mail.activity.mixin']
tracked_field = fields.Char(tracking=True)
Furthermore, changes should be made through ORM methods like write() or form updates, not direct SQL.
Too Many Messages in Chatter
If your chatter is overwhelmed with tracking messages:
- Review which fields are tracked and consider reducing the number
- Group related changes into a single
write()call - Consider implementing custom tracking logic for batch operations
For instance, you might implement a custom method for batch updates:
def update_multiple_records(self, records, values):
# Add a manual note instead of tracking each individual change
for record in records:
record.write(values)
if len(records) > 1:
record.message_post(
body=f"Updated {len(values)} fields in a batch operation",
subtype_id=self.env.ref('mail.mt_note').id
)
return True
As a result, bulk operations generate cleaner, more useful chatter history.
Enhancing Odoo’s Tracking with Custom Development
For advanced use cases, you might need to implement custom tracking behavior.
Custom Tracking Messages
You can create more descriptive tracking messages for specific fields:
class SaleOrder(models.Model):
_inherit = 'sale.order'
def write(self, vals):
# Before the update
for record in self:
# Store old value if we're updating the amount
if 'amount_total' in vals:
old_amount = record.amount_total
# Perform the standard update (with normal tracking)
result = super(SaleOrder, self).write(vals)
# After the update, add a custom tracking message
for record in self:
if 'amount_total' in vals and old_amount != record.amount_total:
difference = record.amount_total - old_amount
message = f"Order value {'increased' if difference > 0 else 'decreased'} by {abs(difference):.2f} {record.currency_id.name}"
record.message_post(body=message)
return result
Consequently, you can provide more business context in tracking messages beyond simple “changed from X to Y” notifications.
Tracking Related Fields
Standard tracking doesn’t work for related fields, but you can implement custom tracking:
class SaleOrder(models.Model):
_inherit = 'sale.order'
# Related field that we want to track
partner_credit_limit = fields.Float(related='partner_id.credit_limit', readonly=True)
@api.model
def create(self, vals):
record = super(SaleOrder, self).create(vals)
# Track initial value on creation
if record.partner_id and record.partner_id.credit_limit:
record.message_post(body=f"Customer credit limit is {record.partner_credit_limit}")
return record
def write(self, vals):
# Track changes to the partner
if 'partner_id' in vals:
for record in self:
new_partner = self.env['res.partner'].browse(vals['partner_id'])
if new_partner and new_partner.credit_limit:
record.message_post(body=f"New customer credit limit is {new_partner.credit_limit}")
return super(SaleOrder, self).write(vals)
Therefore, you can track information even from related models, providing more context in your chatter history.
Conclusion
Understanding and configuring tracked fields in Odoo’s chatter system is essential for maintaining good record-keeping and enabling effective collaboration. Moreover, whether you’re using the interface to check existing tracking or developing custom modules with tracked fields, this knowledge helps create more transparent and auditable business processes.
To learn more about Odoo’s chatter and tracking capabilities, visit the official Odoo documentation for detailed explanations and examples from the source.
By implementing the strategies outlined in this guide, you’ll create more informative record histories that help your team understand not just what changed, but when, why, and by whom—improving accountability and communication throughout your organization.
Do you have specific questions about tracking fields in Odoo’s chatter? Share your experiences or challenges in the comments below!
Discover more from teguhteja.id
Subscribe to get the latest posts sent to your email.
