[FIX] mail_activity_done: patch _action_done in a more reliable way

pull/1011/head
Holger Brunn 2022-12-01 09:12:58 +01:00
parent 5a77fdeef0
commit 5f1f8435c1
5 changed files with 18 additions and 74 deletions

View File

@ -1,2 +1,2 @@
from . import models
from .hooks import post_load_hook, pre_init_hook, uninstall_hook
from .hooks import pre_init_hook, uninstall_hook

View File

@ -10,6 +10,5 @@
"depends": ["mail"],
"data": ["views/templates.xml", "views/mail_activity_views.xml"],
"pre_init_hook": "pre_init_hook",
"post_load": "post_load_hook",
"uninstall_hook": "uninstall_hook",
}

View File

@ -1,9 +1,6 @@
# Copyright 2018-20 ForgeFlow <http://www.forgeflow.com>
# Copyright 2018 Odoo, S.A.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from odoo import fields
from odoo.addons.mail.models.mail_activity import MailActivity
def pre_init_hook(cr):
@ -31,73 +28,6 @@ def pre_init_hook(cr):
)
def post_load_hook():
def _new_action_done(self, feedback=False, attachment_ids=None):
"""Overwritten method"""
if "done" not in self._fields:
return self._action_done_original(
feedback=feedback, attachment_ids=attachment_ids
)
# marking as 'done'
messages = self.env["mail.message"]
next_activities_values = []
for activity in self:
# extract value to generate next activities
if activity.force_next:
# context key is required in the onchange to set deadline
Activity = self.env["mail.activity"].with_context(
activity_previous_deadline=activity.date_deadline
)
vals = Activity.default_get(Activity.fields_get())
vals.update(
{
"previous_activity_type_id": activity.activity_type_id.id,
"res_id": activity.res_id,
"res_model": activity.res_model,
"res_model_id": self.env["ir.model"]
._get(activity.res_model)
.id,
}
)
virtual_activity = Activity.new(vals)
virtual_activity._onchange_previous_activity_type_id()
virtual_activity._onchange_activity_type_id()
next_activities_values.append(
virtual_activity._convert_to_write(virtual_activity._cache)
)
# post message on activity, before deleting it
record = self.env[activity.res_model].browse(activity.res_id)
activity.done = True
activity.active = False
activity.date_done = fields.Date.today()
record.message_post_with_view(
"mail.message_activity_done",
values={
"activity": activity,
"feedback": feedback,
"display_assignee": activity.user_id != self.env.user,
},
subtype_id=self.env["ir.model.data"].xmlid_to_res_id(
"mail.mt_activities"
),
mail_activity_type_id=activity.activity_type_id.id,
attachment_ids=[(4, attachment_id) for attachment_id in attachment_ids]
if attachment_ids
else [],
)
messages |= record.message_ids[0]
next_activities = self.env["mail.activity"].create(next_activities_values)
return messages, next_activities
if not hasattr(MailActivity, "_action_done_original"):
MailActivity._action_done_original = MailActivity._action_done
MailActivity._action_done = _new_action_done
def uninstall_hook(cr, registry):
""" The objective of this hook is to remove all activities that are done
upon module uninstall

View File

@ -2,6 +2,8 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo import api, fields, models
delete_sentinel = object()
class MailActivity(models.Model):
@ -18,6 +20,18 @@ class MailActivity(models.Model):
for record in self.filtered(lambda activity: activity.done):
record.state = "done"
def unlink(self):
"""Don't unlink if we're asked not to"""
if self.env.context.get("mail_activity_done") != delete_sentinel:
return super().unlink()
def _action_done(self, feedback=False, attachment_ids=None):
"""Ask super not to delete the activity and set it to done"""
self.write({"done": True, "active": False, "date_done": fields.Date.today()})
return super(
MailActivity, self.with_context(mail_activity_done=delete_sentinel),
)._action_done(feedback=feedback, attachment_ids=attachment_ids)
class MailActivityMixin(models.AbstractModel):

View File

@ -31,11 +31,12 @@ class TestMailActivityDoneMethods(TransactionCase):
)
def test_mail_activity_done(self):
self.act1.done = True
self.act1._action_done()
self.assertTrue(self.act1.exists())
self.assertEquals(self.act1.state, "done")
def test_systray_get_activities(self):
act_count = self.employee.sudo(self.employee).systray_get_activities()
act_count = self.employee.with_user(self.employee).systray_get_activities()
self.assertEqual(
len(act_count), 1, "Number of activities should be equal to one"
)