diff --git a/.docker_files/main/__manifest__.py b/.docker_files/main/__manifest__.py index 171a98a8..d9d3a83a 100644 --- a/.docker_files/main/__manifest__.py +++ b/.docker_files/main/__manifest__.py @@ -39,7 +39,6 @@ "ir_attachment_access_token_portal", "lang_fr_activated", "mail_activity_list_mark_done", - "mail_activity_not_deleted", "mail_bot_no_pong", "mail_notification_no_action_button", "mail_message_from_author", diff --git a/Dockerfile b/Dockerfile index 8573d49c..5e022e53 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,7 +39,6 @@ COPY currency_rate_update_boc /mnt/extra-addons/currency_rate_update_boc COPY ir_attachment_access_token_portal /mnt/extra-addons/ir_attachment_access_token_portal COPY lang_fr_activated /mnt/extra-addons/lang_fr_activated COPY mail_activity_list_mark_done /mnt/extra-addons/mail_activity_list_mark_done -COPY mail_activity_not_deleted /mnt/extra-addons/mail_activity_not_deleted COPY mail_bot_no_pong /mnt/extra-addons/mail_bot_no_pong COPY mail_notification_no_action_button /mnt/extra-addons/mail_notification_no_action_button COPY mail_message_from_author /mnt/extra-addons/mail_message_from_author diff --git a/mail_activity_not_deleted/README.rst b/mail_activity_not_deleted/README.rst deleted file mode 100644 index a59e3f54..00000000 --- a/mail_activity_not_deleted/README.rst +++ /dev/null @@ -1,18 +0,0 @@ -Mail Activity Not Deleted -========================= -Since version 11.0, Odoo adds the concept of activities. -One issue with this feature is that when an activity is completed, the activity record is deleted from the database. - -This module deactivates terminated activities instead of deleting them from the mail_activity table. - -New State ---------- -The state Done is added to activities. Any completed activity is automatically set to Done. - -New Field ---------- -The field Date Done is added to activities. When completing the activity, this field is filled with the current time. - -Contributors ------------- -* Numigi (tm) and all its contributors (https://bit.ly/numigiens) diff --git a/mail_activity_not_deleted/__init__.py b/mail_activity_not_deleted/__init__.py deleted file mode 100644 index fd8d2296..00000000 --- a/mail_activity_not_deleted/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# © 2023 Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from . import models diff --git a/mail_activity_not_deleted/__manifest__.py b/mail_activity_not_deleted/__manifest__.py deleted file mode 100644 index e2d35c89..00000000 --- a/mail_activity_not_deleted/__manifest__.py +++ /dev/null @@ -1,14 +0,0 @@ -# © 2023 Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -{ - 'name': 'Mail Activity Not Deleted', - 'version': '14.0.1.0.1', - 'author': 'Numigi', - 'maintainer': 'Numigi', - 'license': 'LGPL-3', - 'category': 'Other', - 'summary': 'Deactivate terminated activities instead of deleting.', - 'depends': ['mail'], - 'installable': True, -} diff --git a/mail_activity_not_deleted/i18n/fr.po b/mail_activity_not_deleted/i18n/fr.po deleted file mode 100644 index 5b641208..00000000 --- a/mail_activity_not_deleted/i18n/fr.po +++ /dev/null @@ -1,33 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * mail_activity_not_deleted -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 11.0+e\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-05-29 15:13-0400\n" -"PO-Revision-Date: 2018-05-29 19:13+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: \n" -"X-Generator: Poedit 1.8.7.1\n" - -#. module: mail_activity_not_deleted -#: model:ir.model.fields,field_description:mail_activity_not_deleted.field_mail_activity_active -msgid "Active" -msgstr "Actif" - -#. module: mail_activity_not_deleted -#: model:ir.model,name:mail_activity_not_deleted.model_mail_activity -msgid "Activity" -msgstr "Activité" - -#. module: mail_activity_not_deleted -#: model:ir.model.fields,field_description:mail_activity_not_deleted.field_mail_activity_date_done -msgid "Date Done" -msgstr "Terminé le" diff --git a/mail_activity_not_deleted/models/__init__.py b/mail_activity_not_deleted/models/__init__.py deleted file mode 100644 index d970ab5f..00000000 --- a/mail_activity_not_deleted/models/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# © 2023 Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from . import mail_activity, user, mail_activity_mixin diff --git a/mail_activity_not_deleted/models/mail_activity.py b/mail_activity_not_deleted/models/mail_activity.py deleted file mode 100644 index 173cad97..00000000 --- a/mail_activity_not_deleted/models/mail_activity.py +++ /dev/null @@ -1,39 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from datetime import datetime - -from odoo import api, fields, models - - -class MailActivityInactivatedInsteadOfDeleted(models.Model): - - _inherit = "mail.activity" - - active = fields.Boolean(default=True) - date_done = fields.Datetime() - - state = fields.Selection(selection_add=[("done", "Done")]) - - @api.depends("date_deadline") - def _compute_state(self): - super()._compute_state() - - done_activities = self.filtered(lambda a: a.date_done) - for activity in done_activities: - activity.state = "done" - - def unlink(self): - self.write( - {"active": False, "date_done": datetime.now()} - ) - for activity in self: - activity._update_record_date_deadline() - - return True - - def _update_record_date_deadline(self): - """Update the stored fields that depend on activity_ids on the related record.""" - record = self.env[self.res_model].browse(self.res_id) - record.modified(["activity_ids"]) - record.recompute() diff --git a/mail_activity_not_deleted/models/mail_activity_mixin.py b/mail_activity_not_deleted/models/mail_activity_mixin.py deleted file mode 100644 index 5f16303a..00000000 --- a/mail_activity_not_deleted/models/mail_activity_mixin.py +++ /dev/null @@ -1,12 +0,0 @@ -# © 2023 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from odoo import fields, models - - -class MailActivityMixin(models.AbstractModel): - - _inherit = 'mail.activity.mixin' - - # auto_join prevents the active filter from being automatically applied. - activity_ids = fields.One2many(auto_join=False) diff --git a/mail_activity_not_deleted/models/user.py b/mail_activity_not_deleted/models/user.py deleted file mode 100644 index 1d72d7a6..00000000 --- a/mail_activity_not_deleted/models/user.py +++ /dev/null @@ -1,83 +0,0 @@ -# © 2023 Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from collections import defaultdict - -from odoo import api, fields, models, modules - - -class User(models.Model): - - _inherit = 'res.users' - - @api.model - def systray_get_activities(self): - """Prevent inactive activities from appearing in the main Odoo navbar. - - This method is a copy from the method defined at: - odoo/addons/mail/models/res_users.py - - Only the active filter was added in the sql query. - """ - query = """SELECT array_agg(res_id) as res_ids, m.id, count(*), - CASE - WHEN %(today)s::date - act.date_deadline::date = 0 Then 'today' - WHEN %(today)s::date - act.date_deadline::date > 0 Then 'overdue' - WHEN %(today)s::date - act.date_deadline::date < 0 Then 'planned' - END AS states - FROM mail_activity AS act - JOIN ir_model AS m ON act.res_model_id = m.id - WHERE user_id = %(user_id)s - AND act.active - GROUP BY m.id, states; - """ - self.env.cr.execute( - query, - { - "today": fields.Date.context_today(self), - "user_id": self.env.uid, - }, - ) - activity_data = self.env.cr.dictfetchall() - records_by_state_by_model = defaultdict( - lambda: {"today": set(), "overdue": set(), "planned": set(), "all": set()} - ) - for data in activity_data: - records_by_state_by_model[data["id"]][data["states"]] = set(data["res_ids"]) - records_by_state_by_model[data["id"]]["all"] = records_by_state_by_model[ - data["id"] - ]["all"] | set(data["res_ids"]) - user_activities = {} - for model_id in records_by_state_by_model: - model_dic = records_by_state_by_model[model_id] - model = ( - self.env["ir.model"] - .browse(model_id) - .with_prefetch(tuple(records_by_state_by_model.keys())) - ) - allowed_records = self.env[model.model].search( - [("id", "in", tuple(model_dic["all"]))] - ) - if not allowed_records: - continue - module = self.env[model.model]._original_module - icon = module and modules.module.get_module_icon(module) - today = len(model_dic["today"] & set(allowed_records.ids)) - overdue = len(model_dic["overdue"] & set(allowed_records.ids)) - user_activities[model.model] = { - "name": model.name, - "model": model.model, - "type": "activity", - "icon": icon, - "total_count": today + overdue, - "today_count": today, - "overdue_count": overdue, - "planned_count": len(model_dic["planned"] & set(allowed_records.ids)), - "actions": [ - { - "icon": "fa-clock-o", - "name": "Summary", - } - ], - } - return list(user_activities.values()) diff --git a/mail_activity_not_deleted/static/description/icon.png b/mail_activity_not_deleted/static/description/icon.png deleted file mode 100644 index 92a86b10..00000000 Binary files a/mail_activity_not_deleted/static/description/icon.png and /dev/null differ diff --git a/mail_activity_not_deleted/tests/__init__.py b/mail_activity_not_deleted/tests/__init__.py deleted file mode 100644 index 98a1f553..00000000 --- a/mail_activity_not_deleted/tests/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - -from . import test_mail_activity diff --git a/mail_activity_not_deleted/tests/test_mail_activity.py b/mail_activity_not_deleted/tests/test_mail_activity.py deleted file mode 100644 index bb858ab5..00000000 --- a/mail_activity_not_deleted/tests/test_mail_activity.py +++ /dev/null @@ -1,70 +0,0 @@ -# © 2023 Numigi (tm) and all its contributors (https://bit.ly/numigiens) -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - -from datetime import datetime -from odoo.tests import common - - -class TestMailActivity(common.SavepointCase): - - @classmethod - def setUpClass(cls): - super().setUpClass() - cls.partner = cls.env['res.partner'].create({'name': 'Test'}) - cls.partner.write({ - 'activity_ids': [(0, 0, { - 'res_id': cls.partner.id, - 'res_model_id': cls.env.ref('base.model_res_partner').id, - 'date_deadline': datetime.now().date(), - 'user_id': cls.env.user.id, - })] - }) - cls.activity = cls.partner.activity_ids - - def test_when_activity_is_completed_then_it_is_inactive_instead_of_deleted(self): - self.assertTrue(self.activity.active) - - self.activity.action_done() - self.assertTrue(self.activity.exists()) - self.assertFalse(self.activity.active) - - def test_when_activity_is_rescheduled_then_it_is_inactive_instead_of_deleted(self): - self.assertTrue(self.activity.active) - - self.activity.action_done_schedule_next() - self.assertTrue(self.activity.exists()) - self.assertFalse(self.activity.active) - - def test_when_record_is_deactivated_then_the_activity_is_inactive_instead_of_deleted(self): - self.assertTrue(self.activity.active) - - self.partner.active = False - self.activity.refresh() - self.assertTrue(self.activity.exists()) - self.assertFalse(self.activity.active) - - def test_the_date_done_is_computed_when_the_activity_is_completed(self): - self.assertFalse(self.activity.date_done) - - time_before = datetime.now() - self.activity.action_done() - time_after = datetime.now() - - self.assertLessEqual(time_before, self.activity.date_done) - self.assertLessEqual(self.activity.date_done, time_after) - - def test_the_state_is_done_after_the_activity_is_completed(self): - self.assertNotEqual(self.activity.state, 'done') - self.activity.action_done() - self.activity.refresh() - self.assertEqual(self.activity.state, 'done') - - def test_when_the_activity_is_archived_then_it_is_not_due_today(self): - self.assertEqual(self.partner.activity_state, 'today') - self.activity.action_done() - self.assertFalse(self.partner.activity_state) - - def test_when_the_activity_is_archived_then_partner_has_no_activity_deadline(self): - self.assertTrue(self.partner.activity_date_deadline) - self.activity.action_done() - self.assertFalse(self.partner.activity_date_deadline)