Skip to content

Commit ea4838f

Browse files
committed
[FIX]mail_activity_done: Fix activity_state search.
1 parent f00dd76 commit ea4838f

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

mail_activity_done/models/mail_activity.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Copyright 2018-22 ForgeFlow <http://www.forgeflow.com>
22
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
3+
from datetime import datetime
4+
5+
import pytz
6+
37
from odoo import api, fields, models
48
from odoo.osv import expression
59

@@ -92,3 +96,77 @@ def _read_progress_bar(self, domain, group_by, progress_bar):
9296
"""
9397
domain = expression.AND([domain, [("activity_ids.done", "=", False)]])
9498
return super()._read_progress_bar(domain, group_by, progress_bar)
99+
100+
def _search_activity_state(self, operator, value):
101+
# Totally override the method.
102+
all_states = {"overdue", "today", "planned", False}
103+
if operator == "=":
104+
search_states = {value}
105+
elif operator == "!=":
106+
search_states = all_states - {value}
107+
elif operator == "in":
108+
search_states = set(value)
109+
elif operator == "not in":
110+
search_states = all_states - set(value)
111+
112+
reverse_search = False
113+
if False in search_states:
114+
# If we search "activity_state = False", they might be a lot of records
115+
# (million for some models), so instead of returning the list of IDs
116+
# [(id, 'in', ids)] we will reverse the domain and return something like
117+
# [(id, 'not in', ids)], so the list of ids is as small as possible
118+
reverse_search = True
119+
search_states = all_states - search_states
120+
121+
# Use number in the SQL query for performance purpose
122+
integer_state_value = {
123+
"overdue": -1,
124+
"today": 0,
125+
"planned": 1,
126+
False: None,
127+
}
128+
129+
search_states_int = {integer_state_value.get(s or False) for s in search_states}
130+
131+
query = """
132+
SELECT res_id
133+
FROM (
134+
SELECT res_id,
135+
-- Global activity state
136+
MIN(
137+
-- Compute the state of each individual activities
138+
-- -1: overdue
139+
-- 0: today
140+
-- 1: planned
141+
SIGN(EXTRACT(day from (
142+
mail_activity.date_deadline - DATE_TRUNC(
143+
'day', %(today_utc)s AT TIME ZONE res_partner.tz)
144+
)))
145+
)::INT AS activity_state
146+
FROM mail_activity
147+
LEFT JOIN res_users
148+
ON res_users.id = mail_activity.user_id
149+
LEFT JOIN res_partner
150+
ON res_partner.id = res_users.partner_id
151+
WHERE mail_activity.res_model = %(res_model_table)s
152+
and mail_activity.done=False
153+
GROUP BY res_id
154+
) AS res_record
155+
WHERE %(search_states_int)s @> ARRAY[activity_state]
156+
"""
157+
158+
self._cr.execute(
159+
query,
160+
{
161+
"today_utc": pytz.utc.localize(datetime.utcnow()),
162+
"res_model_table": self._name,
163+
"search_states_int": list(search_states_int),
164+
},
165+
)
166+
return [
167+
(
168+
"id",
169+
"not in" if reverse_search else "in",
170+
[r[0] for r in self._cr.fetchall()],
171+
)
172+
]

mail_activity_done/tests/test_mail_activity_done.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def setUp(self):
1414
"company_id": self.env.ref("base.main_company").id,
1515
"name": "Test User",
1616
"login": "testuser",
17+
"tz": "Europe/Brussels",
1718
"groups_id": [(6, 0, [self.env.ref("base.group_user").id])],
1819
}
1920
)
@@ -56,3 +57,14 @@ def test_read_progress_bar(self):
5657
self.assertEqual(self.act1.state, "done")
5758
result = res_partner._read_progress_bar(**params)
5859
self.assertEqual(len(result), 0)
60+
61+
def test_activity_state_search(self):
62+
today_activities = self.env["res.partner"].search(
63+
[("activity_state", "=", "today")]
64+
)
65+
self.assertEqual(len(today_activities), 1)
66+
self.act1._action_done()
67+
today_activities = self.env["res.partner"].search(
68+
[("activity_state", "=", "today")]
69+
)
70+
self.assertEqual(len(today_activities), 0)

0 commit comments

Comments
 (0)