Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const discussChannelPatch = {
<span class="o_mail_notification">
Create a new lead: <a href="#" data-oe-model="crm.lead" data-oe-id="${leadId}">${leadName}</a>
</span>`,
thread: { model: "discuss.channel", id: ids[0] },
channel_id: ids[0],
});
return true;
},
Expand Down
27 changes: 12 additions & 15 deletions addons/hr_holidays/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,15 @@ def _compute_im_status(self):
def _get_on_leave_ids(self):
return self.env['res.users']._get_on_leave_ids(partner=True)

def _to_store(self, store: Store, /, *, fields=None, **kwargs):
"""Override to add the current leave status."""
super()._to_store(store, fields=fields, **kwargs)
if fields is None:
fields = ["out_of_office_date_end"]
for partner in self:
if "out_of_office_date_end" in fields:
# in the rare case of multi-user partner, return the earliest possible return date
dates = partner.mapped("user_ids.leave_date_to")
states = partner.mapped("user_ids.current_leave_state")
date = sorted(dates)[0] if dates and all(dates) else False
state = sorted(states)[0] if states and all(states) else False
store.add(
partner, {"out_of_office_date_end": date if state == "validate" else False}
)
def _to_store_defaults(self):
def out_of_office_date_end(partner):
# in the rare case of multi-user partner, return the earliest possible return date
dates = partner.mapped("user_ids.leave_date_to")
states = partner.mapped("user_ids.current_leave_state")
date = sorted(dates)[0] if dates and all(dates) else False
state = sorted(states)[0] if states and all(states) else False
return date if state == "validate" else False

return super()._to_store_defaults() + [
Store.Attr("out_of_office_date_end", out_of_office_date_end)
]
12 changes: 6 additions & 6 deletions addons/im_livechat/controllers/chatbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,18 @@ def chatbot_trigger_step(self, channel_id, chatbot_script_id=None):
posted_message = next_step._process_step(discuss_channel)
store = Store(posted_message, for_current_user=True)
store.add(next_step)
store.add(
store.add_model_values(
"ChatbotStep",
{
"id": (next_step.id, discuss_channel.id),
"isLast": next_step._is_last_step(discuss_channel),
"message": Store.one(posted_message, only_id=True),
"message": posted_message.id,
"operatorFound": next_step.step_type == "forward_operator"
and len(discuss_channel.channel_member_ids) > 2,
"scriptStep": Store.one(next_step, only_id=True),
"scriptStep": next_step.id,
},
)
store.add(
store.add_model_values(
"Chatbot",
{
"currentStep": {
Expand All @@ -84,8 +84,8 @@ def chatbot_trigger_step(self, channel_id, chatbot_script_id=None):
"message": posted_message.id,
},
"id": (chatbot.id, discuss_channel.id),
"script": Store.one(chatbot, only_id=True),
"thread": Store.one(discuss_channel, only_id=True),
"script": chatbot.id,
"thread": Store.One(discuss_channel, [], as_thread=True),
},
)
return store.get_result()
Expand Down
13 changes: 5 additions & 8 deletions addons/im_livechat/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,20 +154,18 @@ def get_session(self, channel_id, anonymous_name, previous_operator_id=None, cha
}
store.add(chatbot_script)
store.add(welcome_steps)
operator = request.env["res.partner"].sudo().browse(channel_vals["livechat_operator_id"])
channel_info = {
"id": -1, # only one temporary thread at a time, id does not matter.
"isLoaded": True,
"name": channel_vals["name"],
"operator": Store.one(
request.env["res.partner"].sudo().browse(channel_vals["livechat_operator_id"]),
fields=["user_livechat_username", "write_date"],
),
"operator": Store.One(operator, ["user_livechat_username", "write_date"]),
"scrollUnread": False,
"state": "open",
"channel_type": "livechat",
"chatbot": chatbot_data,
}
store.add("discuss.channel", channel_info)
store.add_model_values("discuss.channel", channel_info)
else:
channel = request.env['discuss.channel'].with_context(
mail_create_nosubscribe=False,
Expand All @@ -187,10 +185,9 @@ def get_session(self, channel_id, anonymous_name, previous_operator_id=None, cha
channel.channel_member_ids.filtered(lambda m: m.is_self).fold_state = "open"
if not chatbot_script or chatbot_script.operator_partner_id != channel.livechat_operator_id:
channel._broadcast([channel.livechat_operator_id.id])
store.add(channel)
store.add(channel, {"isLoaded": not chatbot_script, "scrollUnread": False})
store.add(channel, extra_fields={"isLoaded": not chatbot_script, "scrollUnread": False})
if guest:
store.add({"guest_token": guest._format_auth_cookie()})
store.add_global_values(guest_token=guest._format_auth_cookie())
request.env["res.users"]._init_store_data(store)
return store.get_result()

Expand Down
8 changes: 3 additions & 5 deletions addons/im_livechat/controllers/webclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from odoo.http import request, route
from odoo.addons.mail.controllers.webclient import WebclientController
from odoo.addons.mail.models.discuss.mail_guest import add_guest_to_context
from odoo.addons.mail.tools.discuss import Store


class WebClient(WebclientController):
Expand All @@ -16,9 +16,7 @@ def test_external_livechat(self, **kwargs):
},
)

def _process_request_for_internal_user(self, store, **kwargs):
def _process_request_for_internal_user(self, store: Store, **kwargs):
super()._process_request_for_internal_user(store, **kwargs)
if kwargs.get("livechat_channels"):
store.add(
request.env["im_livechat.channel"].search([]), fields=["are_you_inside", "name"]
)
store.add(request.env["im_livechat.channel"].search([]), ["are_you_inside", "name"])
12 changes: 2 additions & 10 deletions addons/im_livechat/models/chatbot_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,16 +184,8 @@ def action_view_livechat_channels(self):
# Tooling / Misc
# --------------------------

def _to_store(self, store: Store, /, *, fields=None, **kwargs):
if fields is None:
fields = ["title", "operator_partner_id"]
for script in self:
data = script._read_format(
[f for f in fields if f not in {"operator_partner_id"}], load=False
)[0]
if "operator_partner_id" in fields:
data["operator_partner_id"] = Store.one(script.operator_partner_id, fields=["name"])
store.add(script, data)
def _to_store_defaults(self):
return [Store.One("operator_partner_id", ["name"]), "title"]

def _validate_email(self, email_address, discuss_channel):
email_address = html2plaintext(email_address)
Expand Down
6 changes: 2 additions & 4 deletions addons/im_livechat/models/chatbot_script_answer.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,5 @@ def _search_display_name(self, operator, value):

return domain

def _to_store(self, store: Store, /, *, fields=None):
if fields is None:
fields = ["name", "redirect_link"]
store.add("chatbot.script.answer", self._read_format(fields, load=False))
def _to_store_defaults(self):
return ["name", "redirect_link"]
23 changes: 7 additions & 16 deletions addons/im_livechat/models/chatbot_script_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,19 +360,10 @@ def _process_step_forward_operator(self, discuss_channel):

return posted_message

def _to_store(self, store: Store, /, *, fields=None):
if fields is None:
fields = ["answer_ids", "message", "type", "is_last"]
for step in self:
data = step._read_format(
[f for f in fields if f not in {"answer_ids", "message", "type", "is_last"}], load=False
)[0]
if "answer_ids" in fields:
data["answers"] = Store.many(step.answer_ids)
if "message" in fields:
data["message"] = plaintext2html(step.message) if step.message else False
if "type" in fields:
data["type"] = step.step_type
if "is_last" in fields:
data["isLast"] = step._is_last_step()
store.add("chatbot.script.step", data)
def _to_store_defaults(self):
return [
Store.Many("answer_ids", rename="answers"),
Store.Attr("is_last", lambda step: step._is_last_step()),
Store.Attr("message", lambda s: plaintext2html(s.message) if s.message else False),
Store.Attr("step_type", rename="type"),
]
82 changes: 41 additions & 41 deletions addons/im_livechat/models/discuss_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,49 +37,49 @@ def _compute_duration(self):
end = record.message_ids[0].date if record.message_ids else fields.Datetime.now()
record.duration = (end - start).total_seconds() / 3600

def _to_store(self, store: Store):
def _to_store_defaults(self):
fields = [
"anonymous_name",
"chatbot_current_step",
Store.One("country_id", ["code", "name"], rename="anonymous_country"),
Store.One(
"livechat_operator_id", ["user_livechat_username", "write_date"], rename="operator"
),
]
if self.env.user._is_internal():
fields.append(Store.One("livechat_channel_id", ["name"], rename="livechatChannel"))
return super()._to_store_defaults() + fields

def _to_store(self, store: Store, fields):
"""Extends the channel header by adding the livechat operator and the 'anonymous' profile"""
super()._to_store(store)
chatbot_lang = self.env["chatbot.script"]._get_chatbot_language()
for channel in self:
channel_info = {}
if channel.chatbot_current_step_id:
# sudo: chatbot.script.step - returning the current script/step of the channel
current_step_sudo = channel.chatbot_current_step_id.sudo().with_context(lang=chatbot_lang)
chatbot_script = current_step_sudo.chatbot_script_id
# sudo: channel - accessing chatbot messages to get the current step message
step_message = next((
m.mail_message_id for m in channel.sudo().chatbot_message_ids
if m.script_step_id == current_step_sudo
super()._to_store(store, [f for f in fields if f != "chatbot_current_step"])
if "chatbot_current_step" not in fields:
return
lang = self.env["chatbot.script"]._get_chatbot_language()
for channel in self.filtered(lambda channel: channel.chatbot_current_step_id):
# sudo: chatbot.script.step - returning the current script/step of the channel
current_step_sudo = channel.chatbot_current_step_id.sudo().with_context(lang=lang)
chatbot_script = current_step_sudo.chatbot_script_id
step_message = self.env["chatbot.message"]
if current_step_sudo.step_type != "forward_operator":
step_message = channel.sudo().chatbot_message_ids.filtered(
lambda m: m.script_step_id == current_step_sudo
and m.mail_message_id.author_id == chatbot_script.operator_partner_id
), None) if channel.chatbot_current_step_id.sudo().step_type != 'forward_operator' else None
current_step = {
'scriptStep': current_step_sudo.id,
"message": Store.one_id(step_message),
'operatorFound': current_step_sudo.step_type == 'forward_operator' and len(channel.channel_member_ids) > 2,
}
channel_info["chatbot"] = {
'script': chatbot_script.id,
'steps': [current_step],
'currentStep': current_step,
}
store.add(current_step_sudo)
store.add(chatbot_script)
channel_info['anonymous_name'] = channel.anonymous_name
channel_info['anonymous_country'] = {
'code': channel.country_id.code,
'id': channel.country_id.id,
'name': channel.country_id.name,
} if channel.country_id else False
if channel.channel_type == "livechat":
channel_info["operator"] = Store.one(
channel.livechat_operator_id, fields=["user_livechat_username", "write_date"]
)
if channel.channel_type == "livechat" and self.env.user._is_internal():
channel_info["livechatChannel"] = Store.one(
channel.livechat_channel_id, fields=["name"]
)
store.add(channel, channel_info)
)[:1]
current_step = {
"scriptStep": current_step_sudo.id,
"message": step_message.mail_message_id.id,
"operatorFound": current_step_sudo.step_type == "forward_operator"
and len(channel.channel_member_ids) > 2,
}
store.add(current_step_sudo)
store.add(chatbot_script)
chatbot_data = {
"script": chatbot_script.id,
"steps": [current_step],
"currentStep": current_step,
}
store.add(channel, {"chatbot": chatbot_data})

@api.autovacuum
def _gc_empty_livechat_sessions(self):
Expand Down
27 changes: 16 additions & 11 deletions addons/im_livechat/models/discuss_channel_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,27 @@ def _gc_unpin_livechat_sessions(self):
for member in sessions_to_be_unpinned:
member._bus_send("discuss.channel/unpin", {"id": member.channel_id.id})

def _to_store(self, store: Store, **kwargs):
super()._to_store(store, **kwargs)
for member in self.filtered(lambda m: m.channel_id.channel_type == "livechat"):
# sudo: discuss.channel - reading livechat channel to check whether current member is a bot is allowed
store.add(
member,
{
"is_bot": member.partner_id
in member.channel_id.sudo().livechat_channel_id.rule_ids.chatbot_script_id.operator_partner_id,
},
def _to_store_defaults(self):
# sudo: discuss.channel - reading livechat channel to check whether current member is a bot is allowed
bot = self.channel_id.sudo().livechat_channel_id.rule_ids.chatbot_script_id.operator_partner_id
return super()._to_store_defaults() + [
Store.Attr(
"is_bot",
lambda member: member.partner_id in bot,
predicate=lambda member: member.channel_id.channel_type == "livechat",
)
]

def _get_store_partner_fields(self, fields):
self.ensure_one()
if self.channel_id.channel_type == 'livechat':
return ["active", "country", "is_public", "user_livechat_username", "write_date"]
return [
"active",
Store.One("country_id", ["code", "name"], rename="country"),
"is_public",
"user_livechat_username",
"write_date",
]
return super()._get_store_partner_fields(fields)

def _get_rtc_invite_members_domain(self, *a, **kw):
Expand Down
9 changes: 2 additions & 7 deletions addons/im_livechat/models/im_livechat_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,12 @@ def _compute_nbr_channel(self):
def action_join(self):
self.ensure_one()
self.user_ids = [Command.link(self.env.user.id)]
self.env.user._bus_send_store(self, fields=["are_you_inside", "name"])
self.env.user._bus_send_store(self, ["are_you_inside", "name"])

def action_quit(self):
self.ensure_one()
self.user_ids = [Command.unlink(self.env.user.id)]
self.env.user._bus_send_store(self, fields=["are_you_inside", "name"])
self.env.user._bus_send_store(self, ["are_you_inside", "name"])

def action_view_rating(self):
""" Action to display the rating relative to the channel, so all rating of the
Expand Down Expand Up @@ -331,11 +331,6 @@ def get_livechat_info(self, username=None):
info['options']["default_username"] = username
return info

def _to_store(self, store: Store, /, *, fields=None):
if fields is None:
fields = []
store.add(self._name, self._read_format(fields))


class Im_LivechatChannelRule(models.Model):
""" Channel Rules
Expand Down
Loading