social/mail_gateway/models/mail_broker_channel.py

177 lines
6.0 KiB
Python

# Copyright 2020 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from datetime import datetime
from xmlrpc.client import DateTime
from odoo import api, fields, models
class MailBrokerChannel(models.Model):
_name = "mail.broker.channel"
_description = "Mail Broker Channel"
name = fields.Char(required=True)
active = fields.Boolean(default=True)
token = fields.Char(required=True)
broker_id = fields.Many2one("mail.broker", required=True)
message_ids = fields.One2many(
"mail.message.broker",
inverse_name="channel_id",
)
mail_message_ids = fields.One2many(
"mail.message",
inverse_name="broker_channel_id",
)
last_message_date = fields.Datetime(
compute="_compute_message_data",
store=True,
)
unread = fields.Integer(
compute="_compute_message_data",
store=True,
)
broker_token = fields.Char(related="broker_id.token", store=True, required=False)
show_on_app = fields.Boolean()
partner_id = fields.Many2one("res.partner")
message_main_attachment_id = fields.Many2one(
string="Main Attachment",
comodel_name="ir.attachment",
index=True,
copy=False,
)
def message_fetch(self, domain=False, limit=30):
self.ensure_one()
if not domain:
domain = []
return (
self.env["mail.message"]
.search([("broker_channel_id", "=", self.id)] + domain, limit=limit)
.message_format()
)
@api.depends(
"mail_message_ids",
"mail_message_ids.date",
"mail_message_ids.broker_unread",
)
def _compute_message_data(self):
for r in self:
r.last_message_date = (
self.env["mail.message"]
.search(
[("broker_channel_id", "=", r.id)],
limit=1,
order="date DESC",
)
.date
)
r.unread = self.env["mail.message"].search_count(
[("broker_channel_id", "=", r.id), ("broker_unread", "=", True)]
)
def _get_thread_data(self):
return {
"id": "broker_thread_%s" % self.id,
"res_id": self.id,
"name": self.name,
"last_message_date": self.last_message_date,
"channel_type": "broker_thread",
"unread": self.unread,
"broker_id": self.broker_id.id,
}
def _broker_message_post_vals(self, body, **kwargs):
subtype_id = kwargs.get("subtype_id", False)
if not subtype_id:
subtype = kwargs.get("subtype") or "mt_note"
if "." not in subtype:
subtype = "mail.%s" % subtype
subtype_id = self.env["ir.model.data"].xmlid_to_res_id(subtype)
vals = {
"channel_id": self.id,
"body": body,
"subtype_id": subtype_id,
"model": self._name,
"res_id": self.id,
"broker_type": self.broker_id.broker_type,
}
if kwargs.get("author_id", False):
vals["author_id"] = kwargs["author_id"]
if "date" in kwargs:
date = kwargs["date"]
if isinstance(date, DateTime):
date = datetime.strptime(str(date), "%Y%m%dT%H:%M:%S")
vals["date"] = date
if "message_id" in kwargs:
vals["message_id"] = kwargs["message_id"]
vals["broker_unread"] = kwargs.get("broker_unread", False)
vals["attachment_ids"] = []
for attachment_id in kwargs.get("attachment_ids", []):
vals["attachment_ids"].append((4, attachment_id))
for name, content, mimetype in kwargs.get("attachments", []):
vals["attachment_ids"].append(
(
0,
0,
{
"name": name,
"datas": content.encode("utf-8"),
"type": "binary",
"description": name,
"mimetype": mimetype,
},
)
)
return vals
@api.returns("mail.message.broker", lambda value: value.id)
def message_post_broker(self, body=False, broker_type=False, **kwargs):
self.ensure_one()
if (
not body
and not kwargs.get("attachments")
and not kwargs.get("attachment_ids")
):
return False
vals = self._broker_message_post_vals(
body, broker_unread=True, author_id=self.partner_id.id, **kwargs
)
vals["state"] = "received"
vals["broker_type"] = broker_type
return self.env["mail.message.broker"].create(vals)
@api.model_create_multi
def create(self, vals_list):
channels = super().create(vals_list)
notifications = []
for channel in channels:
if channel.show_on_app and channel.broker_id.show_on_app:
notifications.append(
(
(self._cr.dbname, "mail.broker", channel.broker_id.id),
{"thread": channel._get_thread_data()},
)
)
if notifications:
self.env["bus.bus"].sendmany(notifications)
return channels
@api.returns("mail.message.broker", lambda value: value.id)
def broker_message_post(self, body=False, **kwargs):
self.ensure_one()
if not body and not kwargs.get("attachment_ids"):
return
message = (
self.with_context(do_not_notify=True)
.env["mail.message.broker"]
.create(self._broker_message_post_vals(body, **kwargs))
)
message.send()
self.env["bus.bus"].sendone(
(self._cr.dbname, "mail.broker", message.channel_id.broker_id.id),
{"message": message.mail_message_id.message_format()[0]},
)
return message