# 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 += "
" for attachment in announcement.attachment_ids: attachment_url = "/web/content/%s?download=false" % attachment.id attachment_link = ( f' ' f"{attachment.name}" ) attachment_links += attachment_link attachment_links += "
" if attachment_links: content += Markup("
") + 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})