-
-
Notifications
You must be signed in to change notification settings - Fork 623
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by pedrobaeza
- Loading branch information
Showing
3 changed files
with
121 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,71 @@ | ||
# Copyright 2018-22 ForgeFlow <http://www.forgeflow.com> | ||
# Copyright 2023 Tecnativa - Víctor Martínez | ||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). | ||
from odoo import api, fields, models, modules | ||
from collections import defaultdict | ||
|
||
from odoo import api, fields, models | ||
|
||
|
||
class ResUsers(models.Model): | ||
_inherit = "res.users" | ||
|
||
@api.model | ||
def systray_get_activities(self): | ||
# Here we totally override the method. Not very nice, but | ||
# we should perhaps ask Odoo to add a hook here. | ||
query = """SELECT m.id, count(*), act.res_model as model, | ||
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.done = False | ||
GROUP BY m.id, states, act.res_model; | ||
""" | ||
# TODO: Simplify if Odoo allows to modify query | ||
res = super().systray_get_activities() | ||
# Convert list to dict | ||
user_activities = {} | ||
for item in res: | ||
user_activities[item["model"]] = item | ||
# Redo the method only with the archived records and subtract them. | ||
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 = False | ||
GROUP BY m.id, states; | ||
""" | ||
self.env.cr.execute( | ||
query, {"today": fields.Date.context_today(self), "user_id": self.env.uid} | ||
query, | ||
{ | ||
"today": fields.Date.context_today(self), | ||
"user_id": self.env.uid, | ||
}, | ||
) | ||
activity_data = self.env.cr.dictfetchall() | ||
model_ids = [a["id"] for a in activity_data] | ||
model_names = { | ||
n[0]: n[1] for n in self.env["ir.model"].sudo().browse(model_ids).name_get() | ||
} | ||
|
||
user_activities = {} | ||
for activity in activity_data: | ||
if not user_activities.get(activity["model"]): | ||
user_activities[activity["model"]] = { | ||
"name": model_names[activity["id"]], | ||
"model": activity["model"], | ||
"icon": modules.module.get_module_icon( | ||
self.env[activity["model"]]._original_module | ||
), | ||
"total_count": 0, | ||
"today_count": 0, | ||
"overdue_count": 0, | ||
"planned_count": 0, | ||
"type": "activity", | ||
} | ||
user_activities[activity["model"]][ | ||
"%s_count" % activity["states"] | ||
] += activity["count"] | ||
if activity["states"] in ("today", "overdue"): | ||
user_activities[activity["model"]]["total_count"] += activity["count"] | ||
|
||
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"]) | ||
for model_id in records_by_state_by_model: | ||
model_dic = records_by_state_by_model[model_id] | ||
model = ( | ||
self.env["ir.model"] | ||
.sudo() | ||
.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 | ||
today = len(model_dic["today"] & set(allowed_records.ids)) | ||
overdue = len(model_dic["overdue"] & set(allowed_records.ids)) | ||
# Decrease total | ||
user_activities[model.model]["total_count"] -= today + overdue | ||
user_activities[model.model]["today_count"] -= today | ||
user_activities[model.model]["overdue_count"] -= overdue | ||
user_activities[model.model]["planned_count"] -= len( | ||
model_dic["planned"] & set(allowed_records.ids) | ||
) | ||
return list(user_activities.values()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,52 +2,45 @@ | |
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
from odoo.exceptions import ValidationError | ||
from odoo.tests.common import Form, TransactionCase | ||
from odoo.tests.common import Form, TransactionCase, new_test_user | ||
|
||
|
||
class TestMailActivityTeam(TransactionCase): | ||
@classmethod | ||
def setUpClass(cls): | ||
super().setUpClass() | ||
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) | ||
cls.env = cls.env( | ||
context=dict( | ||
cls.env.context, | ||
mail_activity_quick_update=True, | ||
mail_create_nolog=True, | ||
mail_create_nosubscribe=True, | ||
mail_notrack=True, | ||
no_reset_password=True, | ||
tracking_disable=True, | ||
) | ||
) | ||
# Start from a clean slate | ||
cls.env["mail.activity.team"].search([]).unlink() | ||
# Create Users | ||
cls.employee = cls.env["res.users"].create( | ||
{ | ||
"company_id": cls.env.ref("base.main_company").id, | ||
"name": "Employee", | ||
"login": "csu", | ||
"email": "[email protected]", | ||
"groups_id": [ | ||
( | ||
6, | ||
0, | ||
[ | ||
cls.env.ref("base.group_user").id, | ||
cls.env.ref("base.group_partner_manager").id, | ||
], | ||
) | ||
], | ||
} | ||
cls.employee = new_test_user( | ||
cls.env, | ||
name="Employee", | ||
login="csu", | ||
email="[email protected]", | ||
groups="base.group_user,base.group_partner_manager", | ||
) | ||
cls.employee2 = cls.env["res.users"].create( | ||
{ | ||
"company_id": cls.env.ref("base.main_company").id, | ||
"name": "Employee 2", | ||
"login": "csu2", | ||
"email": "[email protected]", | ||
"groups_id": [(6, 0, [cls.env.ref("base.group_user").id])], | ||
} | ||
cls.employee2 = new_test_user( | ||
cls.env, | ||
name="Employee 2", | ||
login="csu2", | ||
email="[email protected]", | ||
) | ||
cls.employee3 = cls.env["res.users"].create( | ||
{ | ||
"company_id": cls.env.ref("base.main_company").id, | ||
"name": "Employee 3", | ||
"login": "csu3", | ||
"email": "[email protected]", | ||
"groups_id": [(6, 0, [cls.env.ref("base.group_user").id])], | ||
} | ||
cls.employee3 = new_test_user( | ||
cls.env, | ||
name="Employee 3", | ||
login="csu3", | ||
email="[email protected]", | ||
) | ||
# Create Activity Types | ||
cls.activity1 = cls.env["mail.activity.type"].create( | ||
|
@@ -279,7 +272,7 @@ def test_activity_count(self): | |
self.assertEqual(res[0]["total_count"], 1) | ||
self.assertEqual(res[0]["today_count"], 2) | ||
res = self.env["res.users"].with_user(self.employee.id).systray_get_activities() | ||
self.assertEqual(res[0]["total_count"], 2) | ||
self.assertEqual(res[0]["total_count"], 1) | ||
|
||
def test_activity_schedule_next(self): | ||
self.activity1.write( | ||
|