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

[14.0][IMP] mail_tracking: add job to delete old tracking records #1430

Merged
Merged
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
37 changes: 37 additions & 0 deletions mail_tracking/models/mail_tracking_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,3 +473,40 @@
# - return 'NONE' if this request is not for you
# - return 'ERROR' if any error
return "NONE" # pragma: no cover

def _get_old_mail_tracking_email_domain(self, max_age_days):
target_write_date = fields.Datetime.subtract(
fields.Datetime.now(), days=max_age_days
)
return [("write_date", "<", target_write_date)]

@api.autovacuum
def _gc_mail_tracking_email(self, limit=5000):
config_max_age_days = (
self.env["ir.config_parameter"]
.sudo()
.get_param("mail_tracking.mail_tracking_email_max_age_days")
)
try:
max_age_days = int(config_max_age_days)
except ValueError:
max_age_days = 0

Check warning on line 493 in mail_tracking/models/mail_tracking_email.py

View check run for this annotation

Codecov / codecov/patch

mail_tracking/models/mail_tracking_email.py#L492-L493

Added lines #L492 - L493 were not covered by tests

if not max_age_days > 0:
return False

domain = self._get_old_mail_tracking_email_domain(max_age_days)
records_to_delete = self.search(domain, limit=limit).exists()
if records_to_delete:
_logger.info(
"Deleting %s mail.tracking.email records", len(records_to_delete)
)
self.flush()
# Using a direct query to avoid ORM as it causes an issue with
# a related field mass_mailing_id in customer DB when deleting
# the records. This might be 14.0 specific, so changing to
# .unlink() should be tested when forward porting.
query = "DELETE FROM mail_tracking_email WHERE id IN %s"
args = (tuple(records_to_delete.ids),)
self.env.cr.execute(query, args)
self.invalidate_cache()
6 changes: 6 additions & 0 deletions mail_tracking/models/res_config_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ class ResConfigSettings(models.TransientModel):
related="company_id.mail_tracking_show_aliases",
readonly=False,
)
mail_tracking_email_max_age_days = fields.Integer(
"Max age in days of mail tracking email records",
config_parameter="mail_tracking.mail_tracking_email_max_age_days",
help="If set as positive integer enables the deletion of "
"old mail tracking records to reduce the database size.",
)
1 change: 1 addition & 0 deletions mail_tracking/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from . import test_mail_tracking
from . import test_gc_mail_tracking_email
87 changes: 87 additions & 0 deletions mail_tracking/tests/test_gc_mail_tracking_email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Copyright 2024 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo import fields
from odoo.tests.common import SavepointCase


class TestMailTrackingEmailCleanUp(SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.settings = cls.env["res.config.settings"].create(
{"mail_tracking_email_max_age_days": 365}
)
cls.settings.set_values()
cls.partner = cls.env.ref("base.res_partner_address_28")
cls.message = cls.env["mail.message"].create(
{
"model": "res.partner",
"res_id": cls.partner.id,
"body": "TEST",
"message_type": "email",
"subtype_id": cls.env.ref("mail.mt_comment").id,
"author_id": cls.partner.id,
"date": "2024-03-26",
}
)
cls.recent_mail_tracking_email = cls.env["mail.tracking.email"].create(
{"mail_message_id": cls.message.id}
)
# Can't set the write_date directly as it gets overwritten by the ORM
cls.old_mail_tracking_email = cls.env["mail.tracking.email"].create(
{"mail_message_id": cls.message.id}
)
cls.total_count = 2
cls.recent_count = 1
cls.domain = [
("mail_message_id", "=", cls.message.id),
]

def _set_write_date(self):
# Set the write_date of the old record to be older than the max_age_days
# Update DB directly to avoid ORM overwriting the write_date
old_write_date = fields.Datetime.subtract(fields.Datetime.now(), days=400)
self.env.cr.execute(
"UPDATE mail_tracking_email SET write_date = %s WHERE id = %s",
(old_write_date, self.old_mail_tracking_email.id),
)

def test_deletion_of_mail_tracking_email(self):
self._set_write_date()
self.assertEqual(
len(self.env["mail.tracking.email"].search(self.domain)), self.total_count
)
self.env["mail.tracking.email"]._gc_mail_tracking_email()
self.assertEqual(
len(self.env["mail.tracking.email"].search(self.domain)), self.recent_count
)
self.assertTrue(self.recent_mail_tracking_email.exists())

def test_deletion_follows_configuration_variable(self):
self._set_write_date()
self.assertEqual(
len(self.env["mail.tracking.email"].search(self.domain)), self.total_count
)
# when disabled, no deletions should happen
self.settings.mail_tracking_email_max_age_days = 0
self.settings.set_values()
self.env["mail.tracking.email"]._gc_mail_tracking_email()
self.assertEqual(
len(self.env["mail.tracking.email"].search(self.domain)), self.total_count
)
# when disabled, no deletions should happen
self.settings.mail_tracking_email_max_age_days = -1
self.settings.set_values()
self.env["mail.tracking.email"]._gc_mail_tracking_email()
self.assertEqual(
len(self.env["mail.tracking.email"].search(self.domain)), self.total_count
)
# when enabled, deletions should happen
self.settings.mail_tracking_email_max_age_days = 365
self.settings.set_values()
self.env["mail.tracking.email"]._gc_mail_tracking_email()
self.assertEqual(
len(self.env["mail.tracking.email"].search(self.domain)), self.recent_count
)
22 changes: 22 additions & 0 deletions mail_tracking/views/res_config_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,28 @@
</div>
</div>
</div>
<div
class="col-12 col-lg-6 o_setting_box"
id="mail_tracking_deletion_job_settings"
>
<div class="o_setting_left_pane">
<field name="mail_tracking_email_max_age_days" />
</div>
<div class="o_setting_right_pane">
<div class="content-group">
<label
for="mail_tracking_email_max_age_days"
string="Max age in days of mail tracking email records"
/>
<div
class="text-muted"
id="mail_tracking_email_max_age_days"
>
If set as positive integer enables the deletion of old mail tracking records to reduce the database size.
</div>
</div>
</div>
</div>
</div>
</field>
</record>
Expand Down
Loading