Skip to content

Commit

Permalink
[IMP] tracking_manager: add domain condition for tracking fields
Browse files Browse the repository at this point in the history
  • Loading branch information
CRogos committed Jan 24, 2025
1 parent bde9391 commit 1baa1e4
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 8 deletions.
11 changes: 7 additions & 4 deletions tracking_manager/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ Usage

- 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 @@ -57,14 +59,14 @@ Usage
accordingly.
- Click "Update" for the domain to take effect.

|image|
|model_view|

- 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.png

Bug Tracker
===========
Expand All @@ -89,6 +91,7 @@ Contributors

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

Maintainers
-----------
Expand Down
9 changes: 9 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,8 @@ class IrModelFields(models.Model):
store=True,
)

tracking_domain = fields.Char()

@api.depends("native_tracking")
def _compute_custom_tracking(self):
for record in self:
Expand Down Expand Up @@ -59,4 +61,11 @@ 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)
38 changes: 38 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,43 @@ 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
)

# load the fields that have a tracking_domain
field_ids = []
for tracking_value_id in tracking_value_ids:
tracking_value = tracking_value_id[2]
field_ids.append(tracking_value["field_id"])

fields = self.env["ir.model.fields"].search(
[
("id", "in", field_ids),
("tracking_domain", "!=", False),
("tracking_domain", "!=", "[]"),
]
)

# remove all fields that are not matching the tracking_domain
remove = []
for field in fields:
if not self.filtered_domain(literal_eval(field.tracking_domain)):
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):
tracking_value = tracking_value_id[2]
if tracking_value["field_id"] not in remove:
res_changes.append(change)
res_tracking_value_ids.append(tracking_value_id)

return res_changes, res_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.png)
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.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 +1,2 @@
from . import test_tracking_manager
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)
6 changes: 6 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,17 @@
<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'}"
/>
</tree>
</field>
</record>
Expand Down

0 comments on commit 1baa1e4

Please sign in to comment.