mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-20 07:12:02 +02:00
133 lines
5.9 KiB
Python
133 lines
5.9 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from collections import defaultdict
|
|
|
|
from odoo import http
|
|
from odoo.http import request
|
|
from odoo.addons.mail.controllers.thread import ThreadController
|
|
from odoo.addons.mail.tools.discuss import add_guest_to_context, Store
|
|
|
|
|
|
class WebclientController(ThreadController):
|
|
"""Routes for the web client."""
|
|
|
|
@http.route("/mail/action", methods=["POST"], type="jsonrpc", auth="public")
|
|
@add_guest_to_context
|
|
def mail_action(self, fetch_params, context=None):
|
|
"""Execute actions and returns data depending on request parameters.
|
|
This is similar to /mail/data except this method can have side effects.
|
|
"""
|
|
return self._process_request(fetch_params, context=context)
|
|
|
|
@http.route("/mail/data", methods=["POST"], type="jsonrpc", auth="public", readonly=True)
|
|
@add_guest_to_context
|
|
def mail_data(self, fetch_params, context=None):
|
|
"""Returns data depending on request parameters.
|
|
This is similar to /mail/action except this method should be read-only.
|
|
"""
|
|
return self._process_request(fetch_params, context=context)
|
|
|
|
@classmethod
|
|
def _process_request(self, fetch_params, context):
|
|
store = Store()
|
|
if context:
|
|
request.update_context(**context)
|
|
self._process_request_loop(store, fetch_params)
|
|
return store.get_result()
|
|
|
|
@classmethod
|
|
def _process_request_loop(self, store: Store, fetch_params):
|
|
for fetch_param in fetch_params:
|
|
name, params, data_id = (
|
|
(fetch_param, None, None)
|
|
if isinstance(fetch_param, str)
|
|
else (fetch_param + [None, None])[:3]
|
|
)
|
|
store.data_id = data_id
|
|
self._process_request_for_all(store, name, params)
|
|
if not request.env.user._is_public():
|
|
self._process_request_for_logged_in_user(store, name, params)
|
|
if request.env.user._is_internal():
|
|
self._process_request_for_internal_user(store, name, params)
|
|
store.data_id = None
|
|
|
|
@classmethod
|
|
def _process_request_for_all(self, store: Store, name, params):
|
|
if name == "init_messaging":
|
|
if not request.env.user._is_public():
|
|
user = request.env.user.sudo(False)
|
|
user._init_messaging(store)
|
|
if name == "mail.thread":
|
|
thread = self._get_thread_with_access(
|
|
params["thread_model"],
|
|
params["thread_id"],
|
|
mode="read",
|
|
**params.get("access_params", {}),
|
|
)
|
|
if not thread:
|
|
store.add(
|
|
request.env[params["thread_model"]].browse(params["thread_id"]),
|
|
{"hasReadAccess": False, "hasWriteAccess": False},
|
|
as_thread=True,
|
|
)
|
|
else:
|
|
store.add(thread, request_list=params["request_list"], as_thread=True)
|
|
|
|
@classmethod
|
|
def _process_request_for_logged_in_user(self, store: Store, name, params):
|
|
if name == "failures":
|
|
domain = [
|
|
("author_id", "=", request.env.user.partner_id.id),
|
|
("notification_status", "in", ("bounce", "exception")),
|
|
("mail_message_id.message_type", "!=", "user_notification"),
|
|
("mail_message_id.model", "!=", False),
|
|
("mail_message_id.res_id", "!=", 0),
|
|
]
|
|
# sudo as to not check ACL, which is far too costly
|
|
# sudo: mail.notification - return only failures of current user as author
|
|
notifications = request.env["mail.notification"].sudo().search(domain, limit=100)
|
|
found = defaultdict(list)
|
|
for message in notifications.mail_message_id:
|
|
found[message.model].append(message.res_id)
|
|
existing = {
|
|
model: set(request.env[model].browse(ids).exists().ids)
|
|
for model, ids in found.items()
|
|
}
|
|
valid = notifications.filtered(
|
|
lambda n: n.mail_message_id.res_id in existing[n.mail_message_id.model]
|
|
)
|
|
lost = notifications - valid
|
|
# might break readonly status of mail/data, but in really rare cases
|
|
# and solves it by removing useless notifications
|
|
if lost:
|
|
lost.sudo().unlink() # no unlink right except admin, ok to remove as lost anyway
|
|
valid.mail_message_id._message_notifications_to_store(store)
|
|
|
|
@classmethod
|
|
def _process_request_for_internal_user(self, store: Store, name, params):
|
|
if name == "systray_get_activities":
|
|
# sudo: bus.bus: reading non-sensitive last id
|
|
bus_last_id = request.env["bus.bus"].sudo()._bus_last_id()
|
|
groups = request.env["res.users"]._get_activity_groups()
|
|
store.add_global_values(
|
|
activityCounter=sum(group.get("total_count", 0) for group in groups),
|
|
activity_counter_bus_id=bus_last_id,
|
|
activityGroups=groups,
|
|
)
|
|
if name == "mail.canned.response":
|
|
domain = [
|
|
"|",
|
|
("create_uid", "=", request.env.user.id),
|
|
("group_ids", "in", request.env.user.all_group_ids.ids),
|
|
]
|
|
store.add(request.env["mail.canned.response"].search(domain))
|
|
if name == "avatar_card":
|
|
record_id, model = params.get("id"), params.get("model")
|
|
if not record_id or model not in ("res.users", "res.partner"):
|
|
return
|
|
context = {
|
|
"active_test": False,
|
|
"allowed_company_ids": request.env.user._get_company_ids(),
|
|
}
|
|
record = request.env[model].with_context(**context).search([("id", "=", record_id)])
|
|
store.add(record, record._get_store_avatar_card_fields(store.target))
|