mirror of https://github.com/OCA/social.git
commit
dd49b6df24
|
@ -1,6 +1,9 @@
|
||||||
# Copyright 2018-22 ForgeFlow <http://www.forgeflow.com>
|
# 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).
|
# 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):
|
class ResUsers(models.Model):
|
||||||
|
@ -8,51 +11,61 @@ class ResUsers(models.Model):
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def systray_get_activities(self):
|
def systray_get_activities(self):
|
||||||
# Here we totally override the method. Not very nice, but
|
# TODO: Simplify if Odoo allows to modify query
|
||||||
# we should perhaps ask Odoo to add a hook here.
|
res = super().systray_get_activities()
|
||||||
query = """SELECT m.id, count(*), act.res_model as model,
|
# Convert list to dict
|
||||||
CASE
|
user_activities = {}
|
||||||
WHEN %(today)s::date -
|
for item in res:
|
||||||
act.date_deadline::date = 0 Then 'today'
|
user_activities[item["model"]] = item
|
||||||
WHEN %(today)s::date -
|
# Redo the method only with the archived records and subtract them.
|
||||||
act.date_deadline::date > 0 Then 'overdue'
|
query = """SELECT array_agg(res_id) as res_ids, m.id, count(*),
|
||||||
WHEN %(today)s::date -
|
CASE
|
||||||
act.date_deadline::date < 0 Then 'planned'
|
WHEN %(today)s::date - act.date_deadline::date = 0 Then 'today'
|
||||||
END AS states
|
WHEN %(today)s::date - act.date_deadline::date > 0 Then 'overdue'
|
||||||
FROM mail_activity AS act
|
WHEN %(today)s::date - act.date_deadline::date < 0 Then 'planned'
|
||||||
JOIN ir_model AS m ON act.res_model_id = m.id
|
END AS states
|
||||||
WHERE user_id = %(user_id)s
|
FROM mail_activity AS act
|
||||||
AND act.done = False
|
JOIN ir_model AS m ON act.res_model_id = m.id
|
||||||
GROUP BY m.id, states, act.res_model;
|
WHERE user_id = %(user_id)s
|
||||||
"""
|
AND act.active = False
|
||||||
|
GROUP BY m.id, states;
|
||||||
|
"""
|
||||||
self.env.cr.execute(
|
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()
|
activity_data = self.env.cr.dictfetchall()
|
||||||
model_ids = [a["id"] for a in activity_data]
|
records_by_state_by_model = defaultdict(
|
||||||
model_names = {
|
lambda: {"today": set(), "overdue": set(), "planned": set(), "all": set()}
|
||||||
n[0]: n[1] for n in self.env["ir.model"].sudo().browse(model_ids).name_get()
|
)
|
||||||
}
|
for data in activity_data:
|
||||||
|
records_by_state_by_model[data["id"]][data["states"]] = set(data["res_ids"])
|
||||||
user_activities = {}
|
records_by_state_by_model[data["id"]]["all"] = records_by_state_by_model[
|
||||||
for activity in activity_data:
|
data["id"]
|
||||||
if not user_activities.get(activity["model"]):
|
]["all"] | set(data["res_ids"])
|
||||||
user_activities[activity["model"]] = {
|
for model_id in records_by_state_by_model:
|
||||||
"name": model_names[activity["id"]],
|
model_dic = records_by_state_by_model[model_id]
|
||||||
"model": activity["model"],
|
model = (
|
||||||
"icon": modules.module.get_module_icon(
|
self.env["ir.model"]
|
||||||
self.env[activity["model"]]._original_module
|
.sudo()
|
||||||
),
|
.browse(model_id)
|
||||||
"total_count": 0,
|
.with_prefetch(tuple(records_by_state_by_model.keys()))
|
||||||
"today_count": 0,
|
)
|
||||||
"overdue_count": 0,
|
allowed_records = self.env[model.model].search(
|
||||||
"planned_count": 0,
|
[("id", "in", tuple(model_dic["all"]))]
|
||||||
"type": "activity",
|
)
|
||||||
}
|
if not allowed_records:
|
||||||
user_activities[activity["model"]][
|
continue
|
||||||
"%s_count" % activity["states"]
|
today = len(model_dic["today"] & set(allowed_records.ids))
|
||||||
] += activity["count"]
|
overdue = len(model_dic["overdue"] & set(allowed_records.ids))
|
||||||
if activity["states"] in ("today", "overdue"):
|
# Decrease total
|
||||||
user_activities[activity["model"]]["total_count"] += activity["count"]
|
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())
|
return list(user_activities.values())
|
||||||
|
|
|
@ -1,31 +1,39 @@
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
# Copyright 2023 Tecnativa - Víctor Martínez
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
from odoo.tests.common import TransactionCase
|
from odoo.tests.common import TransactionCase, new_test_user
|
||||||
|
|
||||||
|
|
||||||
class TestMailActivityDoneMethods(TransactionCase):
|
class TestMailActivityDoneMethods(TransactionCase):
|
||||||
def setUp(self):
|
@classmethod
|
||||||
super(TestMailActivityDoneMethods, self).setUp()
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
self.employee = self.env["res.users"].create(
|
cls.env = cls.env(
|
||||||
{
|
context=dict(
|
||||||
"company_id": self.env.ref("base.main_company").id,
|
cls.env.context,
|
||||||
"name": "Test User",
|
mail_activity_quick_update=True,
|
||||||
"login": "testuser",
|
mail_create_nolog=True,
|
||||||
"groups_id": [(6, 0, [self.env.ref("base.group_user").id])],
|
mail_create_nosubscribe=True,
|
||||||
}
|
mail_notrack=True,
|
||||||
|
no_reset_password=True,
|
||||||
|
tracking_disable=True,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
activity_type = self.env["mail.activity.type"].search(
|
cls.employee = new_test_user(
|
||||||
|
cls.env,
|
||||||
|
name="Test User",
|
||||||
|
login="testuser",
|
||||||
|
)
|
||||||
|
activity_type = cls.env["mail.activity.type"].search(
|
||||||
[("name", "=", "Meeting")], limit=1
|
[("name", "=", "Meeting")], limit=1
|
||||||
)
|
)
|
||||||
self.act1 = self.env["mail.activity"].create(
|
cls.act1 = cls.env["mail.activity"].create(
|
||||||
{
|
{
|
||||||
"activity_type_id": activity_type.id,
|
"activity_type_id": activity_type.id,
|
||||||
"res_id": self.env.ref("base.res_partner_1").id,
|
"res_id": cls.env.ref("base.res_partner_1").id,
|
||||||
"res_model_id": self.env["ir.model"]._get("res.partner").id,
|
"res_model_id": cls.env["ir.model"]._get("res.partner").id,
|
||||||
"user_id": self.employee.id,
|
"user_id": cls.employee.id,
|
||||||
"date_deadline": date.today(),
|
"date_deadline": date.today(),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -35,7 +43,12 @@ class TestMailActivityDoneMethods(TransactionCase):
|
||||||
self.assertEqual(self.act1.state, "done")
|
self.assertEqual(self.act1.state, "done")
|
||||||
|
|
||||||
def test_systray_get_activities(self):
|
def test_systray_get_activities(self):
|
||||||
act_count = self.employee.with_user(self.employee).systray_get_activities()
|
res = self.employee.with_user(self.employee).systray_get_activities()
|
||||||
self.assertEqual(
|
self.assertEqual(res[0]["total_count"], 1)
|
||||||
len(act_count), 1, "Number of activities should be equal to one"
|
self.act1.action_feedback()
|
||||||
)
|
self.assertFalse(self.act1.active)
|
||||||
|
self.assertEqual(self.act1.state, "done")
|
||||||
|
self.assertTrue(self.act1.done)
|
||||||
|
self.act1.flush()
|
||||||
|
res = self.employee.with_user(self.employee).systray_get_activities()
|
||||||
|
self.assertEqual(res[0]["total_count"], 0)
|
||||||
|
|
|
@ -2,52 +2,45 @@
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
from odoo.exceptions import ValidationError
|
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):
|
class TestMailActivityTeam(TransactionCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
super().setUpClass()
|
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
|
# Start from a clean slate
|
||||||
cls.env["mail.activity.team"].search([]).unlink()
|
cls.env["mail.activity.team"].search([]).unlink()
|
||||||
# Create Users
|
# Create Users
|
||||||
cls.employee = cls.env["res.users"].create(
|
cls.employee = new_test_user(
|
||||||
{
|
cls.env,
|
||||||
"company_id": cls.env.ref("base.main_company").id,
|
name="Employee",
|
||||||
"name": "Employee",
|
login="csu",
|
||||||
"login": "csu",
|
email="crmuser@yourcompany.com",
|
||||||
"email": "crmuser@yourcompany.com",
|
groups="base.group_user,base.group_partner_manager",
|
||||||
"groups_id": [
|
|
||||||
(
|
|
||||||
6,
|
|
||||||
0,
|
|
||||||
[
|
|
||||||
cls.env.ref("base.group_user").id,
|
|
||||||
cls.env.ref("base.group_partner_manager").id,
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
cls.employee2 = cls.env["res.users"].create(
|
cls.employee2 = new_test_user(
|
||||||
{
|
cls.env,
|
||||||
"company_id": cls.env.ref("base.main_company").id,
|
name="Employee 2",
|
||||||
"name": "Employee 2",
|
login="csu2",
|
||||||
"login": "csu2",
|
email="crmuser2@yourcompany.com",
|
||||||
"email": "crmuser2@yourcompany.com",
|
|
||||||
"groups_id": [(6, 0, [cls.env.ref("base.group_user").id])],
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
cls.employee3 = cls.env["res.users"].create(
|
cls.employee3 = new_test_user(
|
||||||
{
|
cls.env,
|
||||||
"company_id": cls.env.ref("base.main_company").id,
|
name="Employee 3",
|
||||||
"name": "Employee 3",
|
login="csu3",
|
||||||
"login": "csu3",
|
email="crmuser3@yourcompany.com",
|
||||||
"email": "crmuser3@yourcompany.com",
|
|
||||||
"groups_id": [(6, 0, [cls.env.ref("base.group_user").id])],
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
# Create Activity Types
|
# Create Activity Types
|
||||||
cls.activity1 = cls.env["mail.activity.type"].create(
|
cls.activity1 = cls.env["mail.activity.type"].create(
|
||||||
|
@ -279,7 +272,7 @@ class TestMailActivityTeam(TransactionCase):
|
||||||
self.assertEqual(res[0]["total_count"], 1)
|
self.assertEqual(res[0]["total_count"], 1)
|
||||||
self.assertEqual(res[0]["today_count"], 2)
|
self.assertEqual(res[0]["today_count"], 2)
|
||||||
res = self.env["res.users"].with_user(self.employee.id).systray_get_activities()
|
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):
|
def test_activity_schedule_next(self):
|
||||||
self.activity1.write(
|
self.activity1.write(
|
||||||
|
|
Loading…
Reference in New Issue