Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[17.0][IMP] tracking_manager: add domain condition for tracking fields #3176

Open
wants to merge 1 commit into
base: 17.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 21 additions & 18 deletions tracking_manager/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,31 @@ order_line in a sale order).
Usage
=====

- In setting > models: select a model
- Check "Active" under Custom Tracking.
- You have two options - 1) manually configure tracked fields one by
one, or 2) determine tracked fields based on a specific domain.
- For 1) manually configure tracked fields one by one
- In setting > models: select a model
- Check "Active" under Custom Tracking.
- Add an optional domain on the field to limit tracking on certain
condition.
- You have two options - 1) manually configure tracked fields one by
one, or 2) determine tracked fields based on a specific domain.
- For 1) manually configure tracked fields one by one

- Click on Tracked Fields smart button, and select/unselect Custom
Tracking.
- Click on Tracked Fields smart button, and select/unselect Custom
Tracking.

- For 2) determine tracked fields based on a specific domain
- For 2) determine tracked fields based on a specific domain

- Select "Automatic configuration", and then set the domain
accordingly.
- Click "Update" for the domain to take effect.
- Select "Automatic configuration", and then set the domain
accordingly.
- Click "Update" for the domain to take effect.

|image|
|model_view|

- Then select the fields to track
- Then select the fields to track

|image1|
|fields|

.. |image| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/tracking_manager/static/description/model_view.png
.. |image1| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/tracking_manager/static/description/fields.png
.. |model_view| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/tracking_manager/static/description/model_view.png
.. |fields| image:: https://raw.githubusercontent.com/OCA/server-tools/17.0/tracking_manager/static/description/fields.drawio.png

Bug Tracker
===========
Expand All @@ -87,8 +89,9 @@ Authors
Contributors
------------

- Kévin Roche <[email protected]>
- Sébastien BEAU <[email protected]>
- Kévin Roche <[email protected]>
- Sébastien BEAU <[email protected]>
- Christopher Rogos <[email protected]>

Maintainers
-----------
Expand Down
11 changes: 11 additions & 0 deletions tracking_manager/models/ir_model_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class IrModelFields(models.Model):
store=True,
)

tracking_domain = fields.Char(
help="Add a domain filter to only track changes when"
" certain condition apply on the parent record."
)

@api.depends("native_tracking")
def _compute_custom_tracking(self):
for record in self:
Expand Down Expand Up @@ -59,4 +64,10 @@ def write(self, vals):
custom_tracking = vals.pop("custom_tracking")
self._write({"custom_tracking": custom_tracking})
self.invalidate_model(fnames=["custom_tracking"])
if "tracking_domain" in vals:
self.env.registry.clear_cache()
self.check_access_rights("write")
custom_tracking_domain = vals.pop("tracking_domain")
self._write({"tracking_domain": custom_tracking_domain})
self.invalidate_model(fnames=["tracking_domain"])
return super().write(vals)
36 changes: 36 additions & 0 deletions tracking_manager/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).


from ast import literal_eval
from collections import defaultdict

from odoo import api, models, tools
Expand All @@ -21,6 +22,41 @@ class Base(models.AbstractModel):
def is_tracked_by_o2m(self):
return self._name in self.env["ir.model"]._get_model_tracked_by_o2m()

def _mail_track(self, tracked_fields, initial_values):
changes, tracking_value_ids = super()._mail_track(
tracked_fields, initial_values
)
tracking_value_field_ids = [
tracking_value_id[2]["field_id"] for tracking_value_id in tracking_value_ids
]
if tracking_value_field_ids:
# if there are fields to track, load tracking_domain information
field_with_domain = self.env["ir.model.fields"].search(
[
("id", "in", tracking_value_field_ids),
("tracking_domain", "!=", False),
("tracking_domain", "!=", "[]"),
]
)
if field_with_domain:
# remove entries that are not matching the tracking_domain of the field
fields_to_remove = []
for field in field_with_domain:
if not self.filtered_domain(literal_eval(field.tracking_domain)):
fields_to_remove.append(field.id)
res_changes = []
res_tracking_value_ids = []
# remove values from tracking result
for change, tracking_value_id in zip(
changes, tracking_value_ids, strict=True
):
if tracking_value_id[2]["field_id"] not in fields_to_remove:
res_changes.append(change)
res_tracking_value_ids.append(tracking_value_id)
changes = res_changes
tracking_value_ids = res_tracking_value_ids
return changes, tracking_value_ids

def _tm_get_fields_to_notify(self):
return (
self.env["ir.model"]
Expand Down
1 change: 1 addition & 0 deletions tracking_manager/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
- Kévin Roche \<<[email protected]>\>
- Sébastien BEAU \<<[email protected]>\>
- Christopher Rogos \<<[email protected]>\>
5 changes: 3 additions & 2 deletions tracking_manager/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
- In setting \> models: select a model
- Check "Active" under Custom Tracking.
- Add an optional domain on the field to limit tracking on certain condition.
- You have two options - 1) manually configure tracked fields one by
one, or 2) determine tracked fields based on a specific domain.
- For 1) manually configure tracked fields one by one
Expand All @@ -10,8 +11,8 @@
accordingly.
- Click "Update" for the domain to take effect.

![image](./static/description/model_view.png)
![model_view](./static/description/model_view.png)

- Then select the fields to track

![image](./static/description/fields.png)
![fields](./static/description/fields.drawio.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed tracking_manager/static/description/fields.png
Binary file not shown.
7 changes: 5 additions & 2 deletions tracking_manager/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ <h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<ul class="simple">
<li>In setting &gt; models: select a model</li>
<li>Check “Active” under Custom Tracking.</li>
<li>Add an optional domain on the field to limit tracking on certain
condition.</li>
<li>You have two options - 1) manually configure tracked fields one by
one, or 2) determine tracked fields based on a specific domain.</li>
<li>For 1) manually configure tracked fields one by one<ul>
Expand All @@ -407,11 +409,11 @@ <h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
</ul>
</li>
</ul>
<p><img alt="image" src="https://raw.githubusercontent.com/OCA/server-tools/17.0/tracking_manager/static/description/model_view.png" /></p>
<p><img alt="model_view" src="https://raw.githubusercontent.com/OCA/server-tools/17.0/tracking_manager/static/description/model_view.png" /></p>
<ul class="simple">
<li>Then select the fields to track</li>
</ul>
<p><img alt="image1" src="https://raw.githubusercontent.com/OCA/server-tools/17.0/tracking_manager/static/description/fields.png" /></p>
<p><img alt="fields" src="https://raw.githubusercontent.com/OCA/server-tools/17.0/tracking_manager/static/description/fields.drawio.png" /></p>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h1>
Expand All @@ -434,6 +436,7 @@ <h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<ul class="simple">
<li>Kévin Roche &lt;<a class="reference external" href="mailto:kevin.roche&#64;akretion.com">kevin.roche&#64;akretion.com</a>&gt;</li>
<li>Sébastien BEAU &lt;<a class="reference external" href="mailto:sebastien.beau&#64;akretion.com">sebastien.beau&#64;akretion.com</a>&gt;</li>
<li>Christopher Rogos &lt;<a class="reference external" href="mailto:crogos&#64;gmail.com">crogos&#64;gmail.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
Expand Down
1 change: 1 addition & 0 deletions tracking_manager/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from . import test_tracking_manager
from . import test_mail_tracking_value
from . import test_models
47 changes: 47 additions & 0 deletions tracking_manager/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from odoo.tests.common import TransactionCase


class TestMailTrack(TransactionCase):
def setUp(self):
super().setUp()

self.Field = self.env["ir.model.fields"]
self.field_mobile = self.Field.search(
[("model", "=", "res.partner"), ("name", "=", "mobile")], limit=1
)
self.field_mobile.write({"tracking_domain": "[('is_company', '=', True)]"})

def test_mail_track(self):
# arrange
company = self.env.ref("base.res_partner_12")
tracked_fields = {"mobile": {"string": "Mobile", "type": "char"}}
initial_values = {"mobile": "1234"}

# act
changes, tracking_value_ids = company._mail_track(
tracked_fields, initial_values
)

# assert
# Check if changes and tracking_value_ids are returned correctly
self.assertEqual(len(changes), 1)
self.assertEqual(len(tracking_value_ids), 1)

# Check if the field is tracked correctly
tracking_value = tracking_value_ids[0][2]
self.assertEqual(tracking_value["field_id"], self.field_mobile.id)

def test_mail_track_with_non_matching_domain(self):
# arrange
person = self.env.ref("base.partner_admin")

tracked_fields = {"mobile": {"string": "Mobile", "type": "char"}}
initial_values = {"mobile": "1234"}

# act
changes, tracking_value_ids = person._mail_track(tracked_fields, initial_values)

# assert
# Check if changes and tracking_value_ids are empty when domain does not match
self.assertEqual(len(changes), 0)
self.assertEqual(len(tracking_value_ids), 0)
7 changes: 7 additions & 0 deletions tracking_manager/views/ir_model_fields.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@
<field name="model">ir.model.fields</field>
<field name="arch" type="xml">
<tree editable="bottom" create="0" delete="0" duplicate="0">
<field name="model" invisible="1" />
<field name="name" readonly="True" />
<field name="field_description" readonly="True" />
<field name="ttype" readonly="True" />
<field name="native_tracking" readonly="True" />
<field name="custom_tracking" widget="boolean_toggle" />
<field
name="tracking_domain"
widget="domain"
options="{'model': 'model'}"
optional="hide"
/>
</tree>
</field>
</record>
Expand Down