odoo-addon-mail-gateway 16.0.1.2.0__py3-none-any.whl → 17.0.1.0.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of odoo-addon-mail-gateway might be problematic. Click here for more details.
- odoo/addons/mail_gateway/README.rst +36 -25
- odoo/addons/mail_gateway/__init__.py +0 -1
- odoo/addons/mail_gateway/__manifest__.py +6 -14
- odoo/addons/mail_gateway/controllers/discuss.py +2 -2
- odoo/addons/mail_gateway/controllers/gateway.py +3 -0
- odoo/addons/mail_gateway/hooks.py +3 -3
- odoo/addons/mail_gateway/i18n/es.po +6 -309
- odoo/addons/mail_gateway/i18n/it.po +5 -336
- odoo/addons/mail_gateway/i18n/mail_gateway.pot +149 -84
- odoo/addons/mail_gateway/models/__init__.py +4 -3
- odoo/addons/mail_gateway/models/{mail_channel.py → discuss_channel.py} +30 -8
- odoo/addons/mail_gateway/models/ir_websocket.py +1 -1
- odoo/addons/mail_gateway/models/mail_gateway.py +4 -4
- odoo/addons/mail_gateway/models/mail_gateway_abstract.py +2 -2
- odoo/addons/mail_gateway/models/mail_message.py +9 -8
- odoo/addons/mail_gateway/models/mail_notification.py +3 -3
- odoo/addons/mail_gateway/models/mail_thread.py +39 -7
- odoo/addons/mail_gateway/models/res_partner.py +10 -18
- odoo/addons/mail_gateway/models/res_users.py +0 -1
- odoo/addons/mail_gateway/models/res_users_settings.py +12 -0
- odoo/addons/mail_gateway/readme/CONTRIBUTORS.md +2 -0
- odoo/addons/mail_gateway/readme/{CREDITS.rst → CREDITS.md} +2 -1
- odoo/addons/mail_gateway/readme/DESCRIPTION.md +8 -0
- odoo/addons/mail_gateway/readme/USAGE.md +12 -0
- odoo/addons/mail_gateway/security/ir.model.access.csv +4 -2
- odoo/addons/mail_gateway/security/security.xml +9 -9
- odoo/addons/mail_gateway/static/description/index.html +39 -26
- odoo/addons/mail_gateway/static/src/components/chatter/chatter.esm.js +15 -0
- odoo/addons/mail_gateway/static/src/components/chatter/chatter.xml +36 -22
- odoo/addons/mail_gateway/static/src/components/composer/composer.esm.js +108 -0
- odoo/addons/mail_gateway/static/src/components/gateway_follower/gateway_follower.esm.js +35 -22
- odoo/addons/mail_gateway/static/src/components/gateway_follower/gateway_follower.xml +3 -5
- odoo/addons/mail_gateway/static/src/components/message/message.xml +15 -15
- odoo/addons/mail_gateway/static/src/components/message/message_patch.esm.js +67 -0
- odoo/addons/mail_gateway/static/src/components/message_notification_popover_content/message_notification_popover_content.xml +3 -7
- odoo/addons/mail_gateway/static/src/core/common/composer_model_patch.esm.js +23 -0
- odoo/addons/mail_gateway/static/src/core/common/discuss_app_model_patch.esm.js +31 -0
- odoo/addons/mail_gateway/static/src/core/common/message_actions.esm.js +23 -0
- odoo/addons/mail_gateway/static/src/core/common/message_model_patch.esm.js +21 -0
- odoo/addons/mail_gateway/static/src/core/common/notification_model_patch.esm.js +35 -0
- odoo/addons/mail_gateway/static/src/core/common/persona_model_patch.esm.js +12 -0
- odoo/addons/mail_gateway/static/src/core/common/store_service_patch.esm.js +14 -0
- odoo/addons/mail_gateway/static/src/core/common/thread_model_patch.esm.js +49 -0
- odoo/addons/mail_gateway/static/src/core/common/thread_service_patch.esm.js +19 -0
- odoo/addons/mail_gateway/static/src/core/web/discuss_app_category_model_patch.esm.js +21 -0
- odoo/addons/mail_gateway/static/src/core/web/discuss_sidebar_categories.esm.js +16 -0
- odoo/addons/mail_gateway/static/src/core/web/discuss_sidebar_category_item_patch.xml +12 -0
- odoo/addons/mail_gateway/static/src/core/web/gateway_core_web_service.esm.js +40 -0
- odoo/addons/mail_gateway/static/src/models/gateway.esm.js +21 -14
- odoo/addons/mail_gateway/static/src/models/gateway_channel.esm.js +21 -13
- odoo/addons/mail_gateway/static/src/models/gateway_follower.esm.js +24 -0
- odoo/addons/mail_gateway/views/mail_gateway.xml +4 -4
- odoo/addons/mail_gateway/views/mail_guest_views.xml +15 -0
- odoo/addons/mail_gateway/wizards/mail_compose_gateway_message.py +19 -4
- odoo/addons/mail_gateway/wizards/mail_compose_gateway_message.xml +1 -2
- odoo/addons/mail_gateway/wizards/mail_guest_manage.py +2 -3
- odoo/addons/mail_gateway/wizards/mail_guest_manage.xml +2 -2
- odoo/addons/mail_gateway/wizards/mail_message_gateway_link.py +0 -1
- odoo/addons/mail_gateway/wizards/mail_message_gateway_send.py +0 -1
- {odoo_addon_mail_gateway-16.0.1.2.0.dist-info → odoo_addon_mail_gateway-17.0.1.0.0.2.dist-info}/METADATA +43 -31
- odoo_addon_mail_gateway-17.0.1.0.0.2.dist-info/RECORD +74 -0
- {odoo_addon_mail_gateway-16.0.1.2.0.dist-info → odoo_addon_mail_gateway-17.0.1.0.0.2.dist-info}/WHEEL +1 -1
- odoo_addon_mail_gateway-17.0.1.0.0.2.dist-info/top_level.txt +1 -0
- odoo/addons/mail_gateway/readme/CONTRIBUTORS.rst +0 -2
- odoo/addons/mail_gateway/readme/DESCRIPTION.rst +0 -5
- odoo/addons/mail_gateway/readme/USAGE.rst +0 -9
- odoo/addons/mail_gateway/static/src/components/composer/composer.xml +0 -24
- odoo/addons/mail_gateway/static/src/components/discuss_sidebar/discuss_sidebar.xml +0 -17
- odoo/addons/mail_gateway/static/src/models/channel.esm.js +0 -33
- odoo/addons/mail_gateway/static/src/models/channel_member_view.esm.js +0 -39
- odoo/addons/mail_gateway/static/src/models/chatter.esm.js +0 -41
- odoo/addons/mail_gateway/static/src/models/composer.esm.js +0 -32
- odoo/addons/mail_gateway/static/src/models/composer_gateway_follower.esm.js +0 -32
- odoo/addons/mail_gateway/static/src/models/composer_view.esm.js +0 -103
- odoo/addons/mail_gateway/static/src/models/discuss.esm.js +0 -51
- odoo/addons/mail_gateway/static/src/models/discuss_sidebar_category.esm.js +0 -128
- odoo/addons/mail_gateway/static/src/models/discuss_sidebar_category_item.esm.js +0 -51
- odoo/addons/mail_gateway/static/src/models/gateway_channel_view.esm.js +0 -15
- odoo/addons/mail_gateway/static/src/models/guest.esm.js +0 -10
- odoo/addons/mail_gateway/static/src/models/message.esm.js +0 -76
- odoo/addons/mail_gateway/static/src/models/message_action.esm.js +0 -45
- odoo/addons/mail_gateway/static/src/models/message_action_list.esm.js +0 -37
- odoo/addons/mail_gateway/static/src/models/message_action_view.esm.js +0 -91
- odoo/addons/mail_gateway/static/src/models/message_view.esm.js +0 -13
- odoo/addons/mail_gateway/static/src/models/messaging_initializer.esm.js +0 -24
- odoo/addons/mail_gateway/static/src/models/notification.esm.js +0 -20
- odoo/addons/mail_gateway/static/src/models/partner.esm.js +0 -11
- odoo/addons/mail_gateway/static/src/models/thread.esm.js +0 -77
- odoo_addon_mail_gateway-16.0.1.2.0.dist-info/RECORD +0 -77
- odoo_addon_mail_gateway-16.0.1.2.0.dist-info/top_level.txt +0 -1
|
@@ -7,13 +7,13 @@ from odoo import fields, models
|
|
|
7
7
|
class MailNotification(models.Model):
|
|
8
8
|
_inherit = "mail.notification"
|
|
9
9
|
|
|
10
|
-
gateway_channel_id = fields.Many2one("
|
|
10
|
+
gateway_channel_id = fields.Many2one("discuss.channel")
|
|
11
11
|
notification_type = fields.Selection(
|
|
12
12
|
selection_add=[("gateway", "Gateway")], ondelete={"gateway": "cascade"}
|
|
13
13
|
)
|
|
14
14
|
gateway_message_id = fields.Char(readonly=True)
|
|
15
15
|
gateway_failure_reason = fields.Text(
|
|
16
|
-
readonly=
|
|
16
|
+
readonly=True,
|
|
17
17
|
help="Failure reason. This is usually the exception thrown by the"
|
|
18
18
|
" email server, stored to ease the debugging of mailing issues.",
|
|
19
19
|
)
|
|
@@ -26,7 +26,7 @@ class MailNotification(models.Model):
|
|
|
26
26
|
|
|
27
27
|
def _notification_format(self):
|
|
28
28
|
result = super()._notification_format()
|
|
29
|
-
for record, formatted_value in zip(self, result):
|
|
29
|
+
for record, formatted_value in zip(self, result, strict=True):
|
|
30
30
|
formatted_value["gateway_type"] = record.gateway_type
|
|
31
31
|
formatted_value["channel_name"] = record.gateway_channel_id.name
|
|
32
32
|
return result
|
|
@@ -6,6 +6,18 @@ from odoo import models
|
|
|
6
6
|
class MailThread(models.AbstractModel):
|
|
7
7
|
_inherit = "mail.thread"
|
|
8
8
|
|
|
9
|
+
def _get_message_create_valid_field_names(self):
|
|
10
|
+
# Add gateway fields
|
|
11
|
+
field_names = super()._get_message_create_valid_field_names()
|
|
12
|
+
field_names.update(
|
|
13
|
+
{"gateway_type", "gateway_notifications", "gateway_message_id"}
|
|
14
|
+
)
|
|
15
|
+
return field_names
|
|
16
|
+
|
|
17
|
+
def _get_notify_valid_parameters(self):
|
|
18
|
+
notify_valid_parameters = super()._get_notify_valid_parameters()
|
|
19
|
+
return notify_valid_parameters | {"gateway_notifications"}
|
|
20
|
+
|
|
9
21
|
def _notify_thread_by_email(self, message, recipients_data, **kwargs):
|
|
10
22
|
partners_data = [r for r in recipients_data if r["notif"] == "gateway"]
|
|
11
23
|
if partners_data:
|
|
@@ -56,30 +68,50 @@ class MailThread(models.AbstractModel):
|
|
|
56
68
|
return result
|
|
57
69
|
return super()._notify_get_recipients(message, msg_vals, **kwargs)
|
|
58
70
|
|
|
71
|
+
def _get_mail_thread_data(self, request_list):
|
|
72
|
+
data = super()._get_mail_thread_data(request_list)
|
|
73
|
+
data["gateway_followers"] = [
|
|
74
|
+
f["partner"]
|
|
75
|
+
for f in data.get("followers", [])
|
|
76
|
+
if f["partner"]["gateway_channels"]
|
|
77
|
+
]
|
|
78
|
+
return data
|
|
79
|
+
|
|
59
80
|
def _check_can_update_message_content(self, messages):
|
|
60
81
|
# We can delete the messages comming from a gateway on not channels
|
|
61
|
-
if self._name != "
|
|
82
|
+
if self._name != "discuss.channel":
|
|
62
83
|
new_messages = messages.filtered(lambda r: not r.gateway_message_ids)
|
|
63
84
|
else:
|
|
64
85
|
new_messages = messages
|
|
65
86
|
return super()._check_can_update_message_content(new_messages)
|
|
66
87
|
|
|
67
88
|
def _message_update_content(
|
|
68
|
-
self,
|
|
89
|
+
self,
|
|
90
|
+
message,
|
|
91
|
+
body,
|
|
92
|
+
attachment_ids=None,
|
|
93
|
+
partner_ids=None,
|
|
94
|
+
strict=True,
|
|
95
|
+
**kwargs,
|
|
69
96
|
):
|
|
70
97
|
result = super()._message_update_content(
|
|
71
|
-
message
|
|
98
|
+
message=message,
|
|
99
|
+
body=body,
|
|
100
|
+
attachment_ids=attachment_ids,
|
|
101
|
+
partner_ids=partner_ids,
|
|
102
|
+
strict=strict,
|
|
103
|
+
**kwargs,
|
|
72
104
|
)
|
|
73
105
|
if body == "":
|
|
74
106
|
# Unlink the message
|
|
75
|
-
for
|
|
76
|
-
|
|
107
|
+
for gateway_msg in message.gateway_message_ids:
|
|
108
|
+
gateway_msg.gateway_message_id = False
|
|
77
109
|
self.env["bus.bus"]._sendone(
|
|
78
110
|
self.env.user.partner_id,
|
|
79
111
|
"mail.message/insert",
|
|
80
112
|
{
|
|
81
|
-
"id":
|
|
82
|
-
"gateway_thread_data":
|
|
113
|
+
"id": gateway_msg.id,
|
|
114
|
+
"gateway_thread_data": gateway_msg.sudo().gateway_thread_data,
|
|
83
115
|
},
|
|
84
116
|
)
|
|
85
117
|
return result
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright 2024 Dixmit
|
|
2
2
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
3
3
|
|
|
4
|
-
from odoo import fields, models
|
|
4
|
+
from odoo import api, fields, models
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class ResPartner(models.Model):
|
|
@@ -30,13 +30,13 @@ class ResPartner(models.Model):
|
|
|
30
30
|
def _get_channels_as_member(self):
|
|
31
31
|
channels = super()._get_channels_as_member()
|
|
32
32
|
if self.env.user.has_group("mail_gateway.gateway_user"):
|
|
33
|
-
channels |= self.env["
|
|
33
|
+
channels |= self.env["discuss.channel"].search(
|
|
34
34
|
[
|
|
35
35
|
("channel_type", "=", "gateway"),
|
|
36
36
|
(
|
|
37
37
|
"channel_member_ids",
|
|
38
38
|
"in",
|
|
39
|
-
self.env["
|
|
39
|
+
self.env["discuss.channel.member"]
|
|
40
40
|
.sudo()
|
|
41
41
|
._search(
|
|
42
42
|
[
|
|
@@ -66,24 +66,16 @@ class ResPartnerGatewayChannel(models.Model):
|
|
|
66
66
|
"res.company", related="gateway_id.company_id", store=True
|
|
67
67
|
)
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
@api.depends_context("mail_gateway_partner_info")
|
|
70
|
+
def _compute_display_name(self):
|
|
70
71
|
# Be able to tell to which partner belongs the gateway partner channel
|
|
71
72
|
# e.g.: picking it from a selector
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
for record in self:
|
|
78
|
-
result.append(
|
|
79
|
-
(
|
|
80
|
-
record.id,
|
|
81
|
-
"{} ({})".format(
|
|
82
|
-
record.partner_id.display_name, origin_dict[record.id]
|
|
83
|
-
),
|
|
84
|
-
)
|
|
73
|
+
if not self.env.context.get("mail_gateway_partner_info"):
|
|
74
|
+
return super()._compute_display_name()
|
|
75
|
+
for gateway_channel in self:
|
|
76
|
+
gateway_channel.display_name = (
|
|
77
|
+
f"{gateway_channel.partner_id.display_name} ({gateway_channel.name})"
|
|
85
78
|
)
|
|
86
|
-
return result
|
|
87
79
|
|
|
88
80
|
_sql_constraints = [
|
|
89
81
|
(
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
|
2
|
+
from odoo import fields, models
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ResUsersSettings(models.Model):
|
|
6
|
+
_inherit = "res.users.settings"
|
|
7
|
+
|
|
8
|
+
is_discuss_sidebar_category_gateway_open = fields.Boolean(
|
|
9
|
+
string="Gateway Category Open",
|
|
10
|
+
default=True,
|
|
11
|
+
help="The gateway category in the sidebar will be open",
|
|
12
|
+
)
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
This work has been funded by AEOdoo (Asociación Española de Odoo -
|
|
1
|
+
This work has been funded by AEOdoo (Asociación Española de Odoo -
|
|
2
|
+
<https://www.aeodoo.org>)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
This module will allow you to integrate an external chat system in your
|
|
2
|
+
Odoo system. It requires extra modules with the specific configuration
|
|
3
|
+
of each chat system, like mail_gateway_telegram or
|
|
4
|
+
mail_gateway_whatsapp.
|
|
5
|
+
|
|
6
|
+
This way, a group of users can respond customers or any other set of
|
|
7
|
+
partners within Odoo, but the messages will be sent through the external
|
|
8
|
+
chat system.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
When external messages are received, they will be directly sent to the
|
|
2
|
+
discuss menu. Answering to these messages will send the answer to the
|
|
3
|
+
external contact. We can assign this messages to any record using the
|
|
4
|
+
message actions. Also, we can assign the sender to a partner using the
|
|
5
|
+
followers menu and selecting the partner.
|
|
6
|
+
|
|
7
|
+
On a standard record associated to a partner with external chat, we can
|
|
8
|
+
send messages to the external contact directly selecting the methods of
|
|
9
|
+
the partner. To use this, we just need to use the
|
|
10
|
+
|
|
11
|
+
It is recomended to enable chatter notification to all users that will
|
|
12
|
+
receive messages from gateways.
|
|
@@ -3,8 +3,10 @@ access_res_partner_gateway_channel_portal,res.partner.gateway.channel.portal,mod
|
|
|
3
3
|
access_res_partner_gateway_channel_user,res.partner.gateway.channel,model_res_partner_gateway_channel,base.group_user,1,0,0,0
|
|
4
4
|
manage_res_partner_gateway_channel_user,res.partner.gateway.channel,model_res_partner_gateway_channel,gateway_user,1,1,1,1
|
|
5
5
|
access_mail_message_gateway_send_user,mail.message.gateway.send,model_mail_message_gateway_send,base.group_user,1,1,1,0
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
access_mail_gateway_portal,mail.gateway.portal,model_mail_gateway,base.group_portal,1,0,0,0
|
|
7
|
+
access_mail_gateway_public,mail.gateway.public,model_mail_gateway,base.group_public,1,0,0,0
|
|
8
|
+
access_mail_gateway_user,mail.gateway.user,model_mail_gateway,base.group_user,1,0,0,0
|
|
9
|
+
access_mail_guest_manage,mail.gateway.internal,model_mail_guest_manage,base.group_user,1,1,1,1
|
|
8
10
|
access_mail_message_gateway_link,mail.message.link.all,model_mail_message_gateway_link,base.group_user,1,1,1,1
|
|
9
11
|
access_mail_gateway_system,mail_gateway,model_mail_gateway,base.group_system,1,1,1,1
|
|
10
12
|
access_mail_compose_gateway_message,access.mail.compose.gateway.message,model_mail_compose_gateway_message,base.group_user,1,1,1,0
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"
|
|
12
12
|
/>
|
|
13
13
|
</record>
|
|
14
|
-
<record id="
|
|
15
|
-
<field name="name">
|
|
16
|
-
<field name="model_id" ref="mail.
|
|
14
|
+
<record id="discuss_channel_gateway_rule" model="ir.rule">
|
|
15
|
+
<field name="name">discuss.channel: access gateway</field>
|
|
16
|
+
<field name="model_id" ref="mail.model_discuss_channel" />
|
|
17
17
|
<field name="groups" eval="[(4, ref('mail_gateway.gateway_user'))]" />
|
|
18
18
|
<field
|
|
19
19
|
name="domain_force"
|
|
20
|
-
>[('channel_type', '=', 'gateway'),
|
|
20
|
+
>[('channel_type', '=', 'gateway'), ('company_id', 'in', company_ids + [False]) ]</field>
|
|
21
21
|
<field name="perm_read" eval="True" />
|
|
22
22
|
<field name="perm_create" eval="False" />
|
|
23
23
|
<field name="perm_write" eval="True" />
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<field name="model_id" ref="mail_gateway.model_mail_gateway" />
|
|
29
29
|
<field
|
|
30
30
|
name="domain_force"
|
|
31
|
-
>[
|
|
31
|
+
>[('company_id', 'in', company_ids + [False]) ]</field>
|
|
32
32
|
<field name="perm_read" eval="True" />
|
|
33
33
|
<field name="perm_create" eval="True" />
|
|
34
34
|
<field name="perm_write" eval="True" />
|
|
@@ -39,17 +39,17 @@
|
|
|
39
39
|
<field name="model_id" ref="mail_gateway.model_res_partner_gateway_channel" />
|
|
40
40
|
<field
|
|
41
41
|
name="domain_force"
|
|
42
|
-
>[
|
|
42
|
+
>[('company_id', 'in', company_ids + [False]) ]</field>
|
|
43
43
|
<field name="perm_read" eval="True" />
|
|
44
44
|
<field name="perm_create" eval="True" />
|
|
45
45
|
<field name="perm_write" eval="True" />
|
|
46
46
|
<field name="perm_unlink" eval="True" />
|
|
47
47
|
</record>
|
|
48
|
-
<record id="
|
|
48
|
+
<record id="ir_rule_discuss_channel_partner_group_user" model="ir.rule">
|
|
49
49
|
<field
|
|
50
50
|
name="name"
|
|
51
|
-
>
|
|
52
|
-
<field name="model_id" ref="mail.
|
|
51
|
+
>discuss.channel.member: write its own entries on gateway channels members</field>
|
|
52
|
+
<field name="model_id" ref="mail.model_discuss_channel_member" />
|
|
53
53
|
<field name="groups" eval="[(4, ref('mail_gateway.gateway_user'))]" />
|
|
54
54
|
<field name="domain_force">[('channel_id.channel_type', '=', 'gateway')]</field>
|
|
55
55
|
<field name="perm_read" eval="False" />
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
5
5
|
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
|
|
6
|
-
<title>
|
|
6
|
+
<title>README.rst</title>
|
|
7
7
|
<style type="text/css">
|
|
8
8
|
|
|
9
9
|
/*
|
|
@@ -360,20 +360,28 @@ ul.auto-toc {
|
|
|
360
360
|
</style>
|
|
361
361
|
</head>
|
|
362
362
|
<body>
|
|
363
|
-
<div class="document"
|
|
364
|
-
<h1 class="title">Mail Gateway</h1>
|
|
363
|
+
<div class="document">
|
|
365
364
|
|
|
365
|
+
|
|
366
|
+
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
|
|
367
|
+
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
|
|
368
|
+
</a>
|
|
369
|
+
<div class="section" id="mail-gateway">
|
|
370
|
+
<h1>Mail Gateway</h1>
|
|
366
371
|
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
367
372
|
!! This file is generated by oca-gen-addon-readme !!
|
|
368
373
|
!! changes will be overwritten. !!
|
|
369
374
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
370
|
-
!! source digest: sha256:
|
|
375
|
+
!! source digest: sha256:090c115a21a87266ff44c47592dc84c631afe5c2d4780e17abc731f918ae6c38
|
|
371
376
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
|
372
|
-
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/
|
|
373
|
-
<p>This module will allow you to integrate an external chat system in your
|
|
374
|
-
It requires extra modules with the specific configuration
|
|
375
|
-
|
|
376
|
-
|
|
377
|
+
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/social/tree/17.0/mail_gateway"><img alt="OCA/social" src="https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/social-17-0/social-17-0-mail_gateway"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
|
378
|
+
<p>This module will allow you to integrate an external chat system in your
|
|
379
|
+
Odoo system. It requires extra modules with the specific configuration
|
|
380
|
+
of each chat system, like mail_gateway_telegram or
|
|
381
|
+
mail_gateway_whatsapp.</p>
|
|
382
|
+
<p>This way, a group of users can respond customers or any other set of
|
|
383
|
+
partners within Odoo, but the messages will be sent through the external
|
|
384
|
+
chat system.</p>
|
|
377
385
|
<p><strong>Table of contents</strong></p>
|
|
378
386
|
<div class="contents local topic" id="contents">
|
|
379
387
|
<ul class="simple">
|
|
@@ -389,45 +397,49 @@ of partners within Odoo, but the messages will be sent through the external chat
|
|
|
389
397
|
</ul>
|
|
390
398
|
</div>
|
|
391
399
|
<div class="section" id="usage">
|
|
392
|
-
<
|
|
393
|
-
<p>When external messages are received, they will be directly sent to the
|
|
394
|
-
Answering to these messages will send the answer to the
|
|
395
|
-
We can assign this messages to any record using the
|
|
396
|
-
Also, we can assign the sender to a partner using the
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
+
<h2><a class="toc-backref" href="#toc-entry-1">Usage</a></h2>
|
|
401
|
+
<p>When external messages are received, they will be directly sent to the
|
|
402
|
+
discuss menu. Answering to these messages will send the answer to the
|
|
403
|
+
external contact. We can assign this messages to any record using the
|
|
404
|
+
message actions. Also, we can assign the sender to a partner using the
|
|
405
|
+
followers menu and selecting the partner.</p>
|
|
406
|
+
<p>On a standard record associated to a partner with external chat, we can
|
|
407
|
+
send messages to the external contact directly selecting the methods of
|
|
408
|
+
the partner. To use this, we just need to use the</p>
|
|
409
|
+
<p>It is recomended to enable chatter notification to all users that will
|
|
410
|
+
receive messages from gateways.</p>
|
|
400
411
|
</div>
|
|
401
412
|
<div class="section" id="bug-tracker">
|
|
402
|
-
<
|
|
413
|
+
<h2><a class="toc-backref" href="#toc-entry-2">Bug Tracker</a></h2>
|
|
403
414
|
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/social/issues">GitHub Issues</a>.
|
|
404
415
|
In case of trouble, please check there if your issue has already been reported.
|
|
405
416
|
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
|
406
|
-
<a class="reference external" href="https://github.com/OCA/social/issues/new?body=module:%20mail_gateway%0Aversion:%
|
|
417
|
+
<a class="reference external" href="https://github.com/OCA/social/issues/new?body=module:%20mail_gateway%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
|
407
418
|
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
|
408
419
|
</div>
|
|
409
420
|
<div class="section" id="credits">
|
|
410
|
-
<
|
|
421
|
+
<h2><a class="toc-backref" href="#toc-entry-3">Credits</a></h2>
|
|
411
422
|
<div class="section" id="authors">
|
|
412
|
-
<
|
|
423
|
+
<h3><a class="toc-backref" href="#toc-entry-4">Authors</a></h3>
|
|
413
424
|
<ul class="simple">
|
|
414
425
|
<li>Creu Blanca</li>
|
|
415
426
|
<li>Dixmit</li>
|
|
416
427
|
</ul>
|
|
417
428
|
</div>
|
|
418
429
|
<div class="section" id="contributors">
|
|
419
|
-
<
|
|
430
|
+
<h3><a class="toc-backref" href="#toc-entry-5">Contributors</a></h3>
|
|
420
431
|
<ul class="simple">
|
|
421
432
|
<li>Enric Tobella</li>
|
|
422
433
|
<li>Olga Marco</li>
|
|
423
434
|
</ul>
|
|
424
435
|
</div>
|
|
425
436
|
<div class="section" id="other-credits">
|
|
426
|
-
<
|
|
427
|
-
<p>This work has been funded by AEOdoo (Asociación Española de Odoo -
|
|
437
|
+
<h3><a class="toc-backref" href="#toc-entry-6">Other credits</a></h3>
|
|
438
|
+
<p>This work has been funded by AEOdoo (Asociación Española de Odoo -
|
|
439
|
+
<a class="reference external" href="https://www.aeodoo.org">https://www.aeodoo.org</a>)</p>
|
|
428
440
|
</div>
|
|
429
441
|
<div class="section" id="maintainers">
|
|
430
|
-
<
|
|
442
|
+
<h3><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h3>
|
|
431
443
|
<p>This module is maintained by the OCA.</p>
|
|
432
444
|
<a class="reference external image-reference" href="https://odoo-community.org">
|
|
433
445
|
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
|
|
@@ -435,10 +447,11 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
|
|
435
447
|
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
|
436
448
|
mission is to support the collaborative development of Odoo features and
|
|
437
449
|
promote its widespread use.</p>
|
|
438
|
-
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/social/tree/
|
|
450
|
+
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/social/tree/17.0/mail_gateway">OCA/social</a> project on GitHub.</p>
|
|
439
451
|
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
|
|
440
452
|
</div>
|
|
441
453
|
</div>
|
|
442
454
|
</div>
|
|
455
|
+
</div>
|
|
443
456
|
</body>
|
|
444
457
|
</html>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** @odoo-module **/
|
|
2
|
+
import {Chatter} from "@mail/core/web/chatter";
|
|
3
|
+
import {patch} from "@web/core/utils/patch";
|
|
4
|
+
import {GatewayFollower} from "../gateway_follower/gateway_follower.esm";
|
|
5
|
+
|
|
6
|
+
patch(Chatter, {
|
|
7
|
+
components: {...Chatter.components, GatewayFollower},
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
patch(Chatter.prototype, {
|
|
11
|
+
toggleComposer(mode = false) {
|
|
12
|
+
this.state.thread.composer.isGateway = mode === "gateway";
|
|
13
|
+
super.toggleComposer(mode);
|
|
14
|
+
},
|
|
15
|
+
});
|
|
@@ -3,38 +3,52 @@
|
|
|
3
3
|
|
|
4
4
|
<t
|
|
5
5
|
t-name="mail_gateway.ChatterTopbar"
|
|
6
|
-
t-inherit="mail.
|
|
6
|
+
t-inherit="mail.Chatter"
|
|
7
7
|
t-inherit-mode="extension"
|
|
8
|
-
owl="1"
|
|
9
8
|
>
|
|
10
|
-
<xpath
|
|
11
|
-
expr="//button[hasclass('o_ChatterTopbar_buttonSendMessage')]"
|
|
12
|
-
position="attributes"
|
|
13
|
-
>
|
|
14
|
-
<attribute name="t-att-class">{
|
|
15
|
-
'o-active btn-odoo': chatterTopbar.chatter.composerView and !chatterTopbar.chatter.composerView.composer.isLog and !chatterTopbar.chatter.composerView.composer.isGateway,
|
|
16
|
-
'btn-odoo': !chatterTopbar.chatter.composerView,
|
|
17
|
-
'btn-light': chatterTopbar.chatter.composerView and (chatterTopbar.chatter.composerView.composer.isLog or chatterTopbar.chatter.composerView.composer.isGateway),
|
|
18
|
-
}</attribute>
|
|
19
|
-
</xpath>
|
|
20
|
-
<xpath
|
|
21
|
-
expr="//button[hasclass('o_ChatterTopbar_buttonLogNote')]"
|
|
22
|
-
position="after"
|
|
23
|
-
>
|
|
9
|
+
<xpath expr="//button[hasclass('o-mail-Chatter-logNote')]" position="after">
|
|
24
10
|
<button
|
|
25
|
-
class="
|
|
11
|
+
class="o-mail-Chatter-gateway btn text-nowrap me-1"
|
|
26
12
|
type="button"
|
|
27
13
|
t-att-class="{
|
|
28
|
-
'
|
|
29
|
-
'btn-
|
|
30
|
-
'
|
|
14
|
+
'btn-primary active': state.composerType === 'gateway',
|
|
15
|
+
'btn-secondary': state.composerType !== 'gateway',
|
|
16
|
+
'my-2': !props.compactHeight
|
|
31
17
|
}"
|
|
32
|
-
t-
|
|
33
|
-
|
|
18
|
+
t-on-click="() => this.toggleComposer('gateway')"
|
|
19
|
+
data-hotkey="shift+w"
|
|
34
20
|
>
|
|
35
21
|
<i class="fa fa-plane" role="img" aria-label="gateway" />
|
|
36
22
|
<span> Gateway message</span>
|
|
37
23
|
</button>
|
|
38
24
|
</xpath>
|
|
25
|
+
<xpath expr="//SuggestedRecipientsList" position="before">
|
|
26
|
+
<t
|
|
27
|
+
t-if="state.composerType === 'gateway' and state.thread.gateway_followers.length"
|
|
28
|
+
>
|
|
29
|
+
<div
|
|
30
|
+
class="flex-shrink-0 px-3 pt-3 text-truncate small mb-2"
|
|
31
|
+
style="margin-left:48px"
|
|
32
|
+
>
|
|
33
|
+
<span class="fw-bold">To:</span>
|
|
34
|
+
<t
|
|
35
|
+
t-foreach="state.thread.gateway_followers"
|
|
36
|
+
t-as="gateway_follower"
|
|
37
|
+
t-key="gateway_follower.id"
|
|
38
|
+
>
|
|
39
|
+
<GatewayFollower
|
|
40
|
+
follower="gateway_follower"
|
|
41
|
+
composer="state.thread.composer"
|
|
42
|
+
/>
|
|
43
|
+
</t>
|
|
44
|
+
</div>
|
|
45
|
+
</t>
|
|
46
|
+
<t t-set="type" t-value="type === 'gateway' ? 'gateway' : type" />
|
|
47
|
+
</xpath>
|
|
48
|
+
<xpath expr="//SuggestedRecipientsList" position="attributes">
|
|
49
|
+
<attribute
|
|
50
|
+
name="t-if"
|
|
51
|
+
>props.hasFollowers and state.composerType !== 'note' and state.composerType !== 'gateway'</attribute>
|
|
52
|
+
</xpath>
|
|
39
53
|
</t>
|
|
40
54
|
</templates>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/** @odoo-module **/
|
|
2
|
+
import {patch} from "@web/core/utils/patch";
|
|
3
|
+
import {Composer} from "@mail/core/common/composer";
|
|
4
|
+
import {_t} from "@web/core/l10n/translation";
|
|
5
|
+
import {prettifyMessageContent} from "@mail/utils/common/format";
|
|
6
|
+
|
|
7
|
+
patch(Composer.prototype, {
|
|
8
|
+
get SEND_TEXT() {
|
|
9
|
+
if (this.props.type === "gateway" && !this.props.composer.message) {
|
|
10
|
+
return _t("Send gateway");
|
|
11
|
+
}
|
|
12
|
+
return super.SEND_TEXT;
|
|
13
|
+
},
|
|
14
|
+
get placeholder() {
|
|
15
|
+
if (
|
|
16
|
+
this.thread?.model !== "discuss.channel" &&
|
|
17
|
+
!this.props.placeholder &&
|
|
18
|
+
this.props.type === "gateway"
|
|
19
|
+
) {
|
|
20
|
+
return _t("Send a message to a gateway...");
|
|
21
|
+
}
|
|
22
|
+
return super.placeholder;
|
|
23
|
+
},
|
|
24
|
+
get isSendButtonDisabled() {
|
|
25
|
+
const isSendButtonDisabled = super.isSendButtonDisabled;
|
|
26
|
+
if (this.props.type !== "gateway") {
|
|
27
|
+
return isSendButtonDisabled;
|
|
28
|
+
}
|
|
29
|
+
return isSendButtonDisabled || !this.thread?.gateway_notifications.length;
|
|
30
|
+
},
|
|
31
|
+
onFocusin() {
|
|
32
|
+
super.onFocusin();
|
|
33
|
+
if (this.props.type !== "gateway") {
|
|
34
|
+
this.thread.gateway_notifications = [];
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
async onClickFullComposer() {
|
|
38
|
+
if (this.props.type !== "gateway") {
|
|
39
|
+
return super.onClickFullComposer(...arguments);
|
|
40
|
+
}
|
|
41
|
+
const attachmentIds = this.props.composer.attachments.map(
|
|
42
|
+
(attachment) => attachment.id
|
|
43
|
+
);
|
|
44
|
+
const body = this.props.composer.textInputContent;
|
|
45
|
+
const validMentions = this.store.user
|
|
46
|
+
? this.messageService.getMentionsFromText(body, {
|
|
47
|
+
mentionedChannels: this.props.composer.mentionedChannels,
|
|
48
|
+
mentionedPartners: this.props.composer.mentionedPartners,
|
|
49
|
+
})
|
|
50
|
+
: undefined;
|
|
51
|
+
// Debugger
|
|
52
|
+
const context = {
|
|
53
|
+
default_attachment_ids: attachmentIds,
|
|
54
|
+
default_body: await prettifyMessageContent(body, validMentions),
|
|
55
|
+
default_model: this.thread.model,
|
|
56
|
+
default_partner_ids: this.thread.suggestedRecipients
|
|
57
|
+
.filter((recipient) => recipient.checked)
|
|
58
|
+
.map((recipient) => recipient.persona.id),
|
|
59
|
+
default_res_ids: [this.thread.id],
|
|
60
|
+
default_subtype_xmlid: "mail.mt_comment",
|
|
61
|
+
mail_post_autofollow: this.thread.hasWriteAccess,
|
|
62
|
+
default_wizard_partner_ids: Array.from(
|
|
63
|
+
new Set(
|
|
64
|
+
this.thread.gateway_followers.map((follower) => {
|
|
65
|
+
return follower.id;
|
|
66
|
+
})
|
|
67
|
+
)
|
|
68
|
+
),
|
|
69
|
+
default_wizard_channel_ids: Array.from(
|
|
70
|
+
new Set(
|
|
71
|
+
this.thread.gateway_followers
|
|
72
|
+
.map((follower) => {
|
|
73
|
+
return follower.gateway_channels.map(
|
|
74
|
+
(channel) => channel?.id
|
|
75
|
+
);
|
|
76
|
+
})
|
|
77
|
+
.flat()
|
|
78
|
+
)
|
|
79
|
+
),
|
|
80
|
+
};
|
|
81
|
+
const action = {
|
|
82
|
+
name: _t("Gateway message"),
|
|
83
|
+
type: "ir.actions.act_window",
|
|
84
|
+
res_model: "mail.compose.gateway.message",
|
|
85
|
+
view_mode: "form",
|
|
86
|
+
views: [[false, "form"]],
|
|
87
|
+
target: "new",
|
|
88
|
+
context: context,
|
|
89
|
+
};
|
|
90
|
+
const options = {
|
|
91
|
+
onClose: (...args) => {
|
|
92
|
+
// Args === [] : click on 'X'
|
|
93
|
+
// args === { special: true } : click on 'discard'
|
|
94
|
+
const isDiscard = args.length === 0 || args[0]?.special;
|
|
95
|
+
// Otherwise message is posted (args === [undefined])
|
|
96
|
+
if (!isDiscard && this.props.composer.thread.type === "mailbox") {
|
|
97
|
+
this.notifySendFromMailbox();
|
|
98
|
+
}
|
|
99
|
+
this.clear();
|
|
100
|
+
this.props.messageToReplyTo?.cancel();
|
|
101
|
+
if (this.thread) {
|
|
102
|
+
this.threadService.fetchNewMessages(this.thread);
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
await this.env.services.action.doAction(action, options);
|
|
107
|
+
},
|
|
108
|
+
});
|