diff --git a/addons/mail/models/mail_activity_mixin.py b/addons/mail/models/mail_activity_mixin.py index b3c55903cb6..da2330cd69a 100644 --- a/addons/mail/models/mail_activity_mixin.py +++ b/addons/mail/models/mail_activity_mixin.py @@ -163,6 +163,7 @@ class MailActivityMixin(models.AbstractModel): search_states_int = {integer_state_value.get(s or False) for s in search_states} + self.env['mail.activity'].flush_model(['active', 'date_deadline', 'res_model', 'user_id']) query = """ SELECT res_id FROM ( @@ -182,7 +183,7 @@ class MailActivityMixin(models.AbstractModel): ON res_users.id = mail_activity.user_id LEFT JOIN res_partner ON res_partner.id = res_users.partner_id - WHERE mail_activity.res_model = %(res_model_table)s + WHERE mail_activity.res_model = %(res_model_table)s AND mail_activity.active = true GROUP BY res_id ) AS res_record WHERE %(search_states_int)s @> ARRAY[activity_state] @@ -271,18 +272,19 @@ class MailActivityMixin(models.AbstractModel): """ (SELECT res_id, CASE - WHEN min(date_deadline - (now() AT TIME ZONE COALESCE(res_partner.tz, %(tz)s))::date) > 0 THEN 'planned' - WHEN min(date_deadline - (now() AT TIME ZONE COALESCE(res_partner.tz, %(tz)s))::date) < 0 THEN 'overdue' - WHEN min(date_deadline - (now() AT TIME ZONE COALESCE(res_partner.tz, %(tz)s))::date) = 0 THEN 'today' + WHEN min(EXTRACT(day from (mail_activity.date_deadline - DATE_TRUNC('day', %(today_utc)s AT TIME ZONE COALESCE(res_partner.tz, %(tz)s))))) > 0 THEN 'planned' + WHEN min(EXTRACT(day from (mail_activity.date_deadline - DATE_TRUNC('day', %(today_utc)s AT TIME ZONE COALESCE(res_partner.tz, %(tz)s))))) < 0 THEN 'overdue' + WHEN min(EXTRACT(day from (mail_activity.date_deadline - DATE_TRUNC('day', %(today_utc)s AT TIME ZONE COALESCE(res_partner.tz, %(tz)s))))) = 0 THEN 'today' ELSE null END AS activity_state FROM mail_activity JOIN res_users ON (res_users.id = mail_activity.user_id) JOIN res_partner ON (res_partner.id = res_users.partner_id) - WHERE res_model = %(res_model)s + WHERE res_model = %(res_model)s AND mail_activity.active = true GROUP BY res_id) """, res_model=self._name, + today_utc=pytz.utc.localize(datetime.utcnow()), tz=tz, ) alias = query.join(self._table, "id", sql_join, "res_id", "last_activity_state") diff --git a/addons/test_mail/tests/test_mail_activity.py b/addons/test_mail/tests/test_mail_activity.py index 53945a9adc9..1c6052fd214 100644 --- a/addons/test_mail/tests/test_mail_activity.py +++ b/addons/test_mail/tests/test_mail_activity.py @@ -600,12 +600,14 @@ class TestActivityMixin(TestActivityCommon): ]) origin_1, origin_2 = self.env['mail.test.activity'].search([], limit=2) + activity_type = self.env.ref('test_mail.mail_act_test_todo') + activity_type.sudo().keep_done = True with patch('odoo.addons.mail.models.mail_activity.datetime', MockedDatetime), \ patch('odoo.addons.mail.models.mail_activity_mixin.datetime', MockedDatetime): origin_1_activity_1 = self.env['mail.activity'].create({ 'summary': 'Test', - 'activity_type_id': 1, + 'activity_type_id': activity_type.id, 'res_model_id': self.env.ref('test_mail.model_mail_test_activity').id, 'res_id': origin_1.id, 'date_deadline': today_utc, @@ -623,7 +625,7 @@ class TestActivityMixin(TestActivityCommon): origin_2_activity_1 = self.env['mail.activity'].create({ 'summary': 'Test', - 'activity_type_id': 1, + 'activity_type_id': activity_type.id, 'res_model_id': self.env.ref('test_mail.model_mail_test_activity').id, 'res_id': origin_2.id, 'date_deadline': today_utc + relativedelta(hours=8), @@ -674,6 +676,22 @@ class TestActivityMixin(TestActivityCommon): self.assertTrue(len(result) > 0) self.assertEqual(result, all_activity_mixin_record.filtered(lambda p: p.activity_state in ('today', False))) + # Check that activity done are not taken into account by group and search by activity_state. + Model = self.env['mail.test.activity'] + search_params = { + 'domain': [('id', 'in', (origin_1 | origin_2).ids), ('activity_state', '=', 'overdue')]} + read_group_params = {'domain': [('id', 'in', (origin_1 | origin_2).ids)], 'fields': ['id:array_agg'], + 'groupby': ['activity_state']} + self.assertEqual(Model.search(**search_params), origin_1) + self.assertEqual( + {(e['activity_state'], e['activity_state_count']) for e in Model.read_group(**read_group_params)}, + {('today', 1), ('overdue', 1)}) + origin_1_activity_2.action_feedback(feedback='Done') + self.assertFalse(Model.search(**search_params)) + self.assertEqual( + {(e['activity_state'], e['activity_state_count']) for e in Model.read_group(**read_group_params)}, + {('today', 2)}) + @mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.tests') def test_mail_activity_mixin_search_state_different_day_but_close_time(self): """Test the case where there's less than 24 hours between the deadline and now_tz,