server-ux/announcement/models/res_users.py
2024-10-01 07:56:39 +02:00

95 lines
3.7 KiB
Python

# Copyright 2022 Tecnativa - David Vidal
# Copyright 2022 Tecnativa - Pilar Vargas
# Copyright 2022 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from markupsafe import Markup
from flectra import api, fields, models
class ResUsers(models.Model):
_inherit = "res.users"
unread_announcement_ids = fields.Many2many(
comodel_name="announcement",
relation="unread_announcement_user_rel",
)
read_announcement_ids = fields.Many2many(
comodel_name="announcement",
relation="read_announcement_user_rel",
)
@api.model
def announcement_user_count(self):
"""The js widget gathers the announcements from this method"""
# It would be better to rely on record rules, but then announcement managers
# would see every announcement, which would be annoying.
group_announcements = self.env["announcement"].search_read(
[
("announcement_type", "=", "user_group"),
("in_date", "=", True),
("id", "not in", self.env.user.read_announcement_ids.ids),
],
["user_group_ids"],
)
announcements = self.env["announcement"].browse(
{
x["id"]
for x in group_announcements
if any(
[g for g in x["user_group_ids"] if g in self.env.user.groups_id.ids]
)
}
)
# Unread announcements are directly linked to the user. Normally, only a
# handful of records will be evaluated at best.
announcements |= self.env.user.unread_announcement_ids.filtered("in_date")
return [
{
"id": announcement.id,
"name": announcement.name,
"content": self._add_attachment_links(announcement),
}
for announcement in announcements.sorted(lambda k: k.sequence)
]
@api.model
def get_announcements(self):
announcements = self.announcement_user_count()
return {
"data": announcements,
"count": len(announcements),
}
def _add_attachment_links(self, announcement):
"""In case the announcement has attachments, show the list below the
modal content"""
content = announcement.content or Markup("")
attachment_links = ""
if announcement.attachment_ids:
attachment_links += "<div class='list-group'>"
for attachment in announcement.attachment_ids:
attachment_url = "/web/content/%s?download=false" % attachment.id
attachment_link = (
f'<a href="{attachment_url}" '
f'class="list-group-item list-group-item-action'
f'target="_blank"><i class="fa fa-download" /> '
f"{attachment.name}</a>"
)
attachment_links += attachment_link
attachment_links += "</div>"
if attachment_links:
content += Markup("<br/>") + Markup(attachment_links)
return content
@api.model
def mark_announcement_as_read(self, announcement_id):
"""Used as a controller for the widget"""
announcement = self.env["announcement"].browse(int(announcement_id))
self.env.user.unread_announcement_ids -= announcement
# Log only the first time. Users with the announcement in multiple windows would
# log multiple reads. We're only interested in the first one.
if announcement not in self.env.user.read_announcement_ids:
self.env.user.read_announcement_ids += announcement
self.env["announcement.log"].create({"announcement_id": announcement.id})