Skip to content
Open
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
1 change: 1 addition & 0 deletions mail_gateway_whatsapp/models/mail_gateway_whatsapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ def _send_payload(
"template": {
"name": whatsapp_template.template_name,
"language": {"code": whatsapp_template.language},
"components": whatsapp_template.prepare_value_to_send(),
},
}
)
Expand Down
556 changes: 539 additions & 17 deletions mail_gateway_whatsapp/models/mail_whatsapp_template.py

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions mail_gateway_whatsapp/security/ir.model.access.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_whatsapp_composer,access.whatsapp.composer,model_whatsapp_composer,base.group_user,1,1,1,0
access_mail_whatsapp_template_group_system,mail_whatsapp_template_group_system,model_mail_whatsapp_template,base.group_system,1,1,1,1
access_mail_whatsapp_template_group_user,mail_whatsapp_template_group_user,model_mail_whatsapp_template,base.group_user,1,0,0,0
access_mail_whatsapp_template_button_group_system,access_mail_whatsapp_template_button_group_system,model_mail_whatsapp_template_button,base.group_system,1,1,1,1
access_mail_whatsapp_template_button_group_user,access_mail_whatsapp_template_button_group_user,model_mail_whatsapp_template_button,base.group_user,1,0,0,0
access_mail_whatsapp_template_variable_group_system,access_mail_whatsapp_template_variable_group_system,model_mail_whatsapp_template_variable,base.group_system,1,1,1,1
access_mail_whatsapp_template_variable_group_user,access_mail_whatsapp_template_variable_group_user,model_mail_whatsapp_template_variable,base.group_user,1,0,0,0
162 changes: 162 additions & 0 deletions mail_gateway_whatsapp/tests/test_mail_gateway_whatsapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from markupsafe import Markup

from odoo import Command
from odoo.exceptions import UserError
from odoo.tests import Form, RecordCapturer
from odoo.tests.common import tagged
Expand Down Expand Up @@ -382,3 +383,164 @@ def test_compose(self):
post_mock.assert_called()
channel.invalidate_recordset()
self.assertTrue(channel.message_ids)

def test_send_message_with_variable(self):
ctx = {
"default_res_model": self.partner._name,
"default_res_id": self.partner.id,
"default_number_field_name": "mobile",
"default_composition_mode": "comment",
"default_gateway_id": self.gateway.id,
}
tmpl_with_vars = self.env["mail.whatsapp.template"].create(
{
"name": "Partner Vars",
"category": "utility",
"language": "es",
"header": "Hi {{1}}",
"body": "Name: {{1}} · Tel: {{2}}",
"gateway_id": self.gateway.id,
"variable_ids": [Command.clear()],
"state": "approved",
"is_supported": True,
"model_id": self.env["ir.model"]._get("res.partner").id,
}
)
self.env["mail.whatsapp.template.variable"].create(
{
"name": "{{1}}",
"line_type": "header",
"template_id": tmpl_with_vars.id,
"field_name": "name",
}
)
self.env["mail.whatsapp.template.variable"].create(
{
"name": "{{1}}",
"line_type": "body",
"template_id": tmpl_with_vars.id,
"field_name": "name",
}
)
self.env["mail.whatsapp.template.variable"].create(
{
"name": "{{2}}",
"line_type": "body",
"template_id": tmpl_with_vars.id,
"field_name": "mobile",
}
)
self.env["mail.whatsapp.template.button"].create(
{
"name": "mobile",
"button_type": "phone_number",
"template_id": tmpl_with_vars.id,
"call_number": "+34666555444",
}
)
self.assertEqual(len(tmpl_with_vars.variable_ids), 3)
self.assertEqual(len(tmpl_with_vars.button_ids), 1)
self.gateway.whatsapp_account_id = "123456"
form_composer = Form(self.env["whatsapp.composer"].with_context(**ctx))
form_composer.template_id = tmpl_with_vars
self.assertTrue(form_composer.is_required_template)
self.assertTrue(form_composer._get_modifier("template_id", "required"))
composer = form_composer.save()
channel = self.partner._whatsapp_get_channel(
composer.number_field_name, composer.gateway_id
)
message_domain = [
("gateway_type", "=", "whatsapp"),
("model", "=", channel._name),
("res_id", "=", channel.id),
]
with (
RecordCapturer(self.env["mail.message"], message_domain) as capture,
patch("requests.post") as post_mock,
):
post_mock.return_value = MagicMock()
composer.action_send_whatsapp()
# Assertions
self.assertEqual(len(capture.records), 1)
channel.invalidate_recordset()
self.assertTrue(channel.message_ids)

def test_send_message_with_dynamic_button(self):
ctx = {
"default_res_model": self.partner._name,
"default_res_id": self.partner.id,
"default_number_field_name": "mobile",
"default_composition_mode": "comment",
"default_gateway_id": self.gateway.id,
}
tmpl_with_vars_dynamic = self.env["mail.whatsapp.template"].create(
{
"name": "Dynamic Button",
"category": "utility",
"language": "es",
"body": "Name: {{1}} · Tel: {{2}}",
"gateway_id": self.gateway.id,
"variable_ids": [Command.clear()],
"state": "approved",
"is_supported": True,
"model_id": self.env["ir.model"]._get("res.partner").id,
}
)
self.assertEqual(len(tmpl_with_vars_dynamic.variable_ids), 0)
self.env["mail.whatsapp.template.variable"].create(
{
"name": "{{1}}",
"line_type": "body",
"template_id": tmpl_with_vars_dynamic.id,
"field_name": "name",
}
)
self.env["mail.whatsapp.template.variable"].create(
{
"name": "{{2}}",
"line_type": "body",
"template_id": tmpl_with_vars_dynamic.id,
"field_name": "mobile",
}
)
self.env["mail.whatsapp.template.button"].create(
{
"name": "1",
"button_type": "url",
"url_type": "dynamic",
"template_id": tmpl_with_vars_dynamic.id,
"website_url": "https://www.odoo.com",
}
)
self.assertEqual(len(tmpl_with_vars_dynamic.variable_ids), 3)
button = tmpl_with_vars_dynamic.variable_ids.search(
[
("line_type", "=", "button"),
("template_id", "=", tmpl_with_vars_dynamic.id),
]
)
button.field_name = "name"
self.gateway.whatsapp_account_id = "123456"
form_composer = Form(self.env["whatsapp.composer"].with_context(**ctx))
form_composer.template_id = tmpl_with_vars_dynamic
self.assertTrue(form_composer.is_required_template)
self.assertTrue(form_composer._get_modifier("template_id", "required"))
composer = form_composer.save()
channel = self.partner._whatsapp_get_channel(
composer.number_field_name, composer.gateway_id
)
message_domain = [
("gateway_type", "=", "whatsapp"),
("model", "=", channel._name),
("res_id", "=", channel.id),
]
with (
RecordCapturer(self.env["mail.message"], message_domain) as capture,
patch("requests.post") as post_mock,
):
post_mock.return_value = MagicMock()
composer.action_send_whatsapp()
# Assertions
self.assertEqual(len(capture.records), 1)
channel.invalidate_recordset()
self.assertTrue(channel.message_ids)
74 changes: 72 additions & 2 deletions mail_gateway_whatsapp/tests/test_mail_whatsapp_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import requests

from odoo import Command
from odoo.exceptions import UserError
from odoo.tests.common import tagged

Expand Down Expand Up @@ -121,15 +122,14 @@ def _patch_request_post(url, *args, **kwargs):
template_2 = self.gateway.whatsapp_template_ids.filtered(
lambda t: t.template_uid == "0987654321"
)
self.assertFalse(template_2.is_supported)
self.assertTrue(template_2.is_supported)
self.assertEqual(template_2.template_name, "test_with_buttons")
self.assertEqual(template_2.category, "marketing")
self.assertEqual(template_2.language, "es")
self.assertEqual(template_2.state, "approved")
self.assertEqual(template_2.header, "Header 2")
self.assertEqual(template_2.body, "Body 2")
self.assertFalse(template_2.footer)
self.assertFalse(template_2.is_supported)

def test_export_template(self):
def _patch_request_post(url, *args, **kwargs):
Expand Down Expand Up @@ -168,3 +168,73 @@ def _patch_request_get(url, *args, **kwargs):
with patch.object(requests, "get", _patch_request_get):
new_template.button_sync_template()
self.assertEqual(new_template.footer, "Footer changed")

def test_prepare_values_template_send(self):
partner = self.env["res.partner"].create(
{
"name": "Ada Lovelace",
"mobile": "+34900111222",
}
)
ctx = {
"default_res_model": partner._name,
"default_res_id": partner.id,
}
tmpl = self.env["mail.whatsapp.template"].create(
{
"name": "Test Render",
"category": "utility",
"language": "es",
"header": "Hi {{1}}",
"body": "Name: {{1}} · Tel: {{2}}",
"gateway_id": self.gateway.id,
"variable_ids": [Command.clear()],
"state": "approved",
"is_supported": True,
"model_id": self.env["ir.model"]._get("res.partner").id,
}
)
self.env["mail.whatsapp.template.variable"].create(
{
"name": "{{1}}",
"line_type": "header",
"template_id": tmpl.id,
"field_name": "name",
}
)
self.env["mail.whatsapp.template.variable"].create(
{
"name": "{{1}}",
"line_type": "body",
"template_id": tmpl.id,
"field_name": "name",
}
)
self.env["mail.whatsapp.template.variable"].create(
{
"name": "{{2}}",
"line_type": "body",
"template_id": tmpl.id,
"field_name": "mobile",
}
)
self.env["mail.whatsapp.template.button"].create(
{
"name": "mobile",
"button_type": "phone_number",
"template_id": tmpl.id,
"call_number": "+34666555444",
}
)
components = tmpl.with_context(**ctx).prepare_value_to_send()

header = next(c for c in components if c["type"].upper() == "HEADER")
self.assertEqual([p["type"] for p in header.get("parameters", [])], ["text"])
self.assertEqual(header["parameters"][0]["text"], partner.name)

body = next(c for c in components if c["type"].upper() == "BODY")
self.assertEqual(
[p["type"] for p in body.get("parameters", [])], ["text", "text"]
)
self.assertEqual(body["parameters"][0]["text"], partner.name)
self.assertEqual(body["parameters"][1]["text"], partner.mobile or "")
2 changes: 2 additions & 0 deletions mail_gateway_whatsapp/tools/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,5 @@
("vi", "Vietnamese"),
("zu", "Zulu"),
]

REG_VARIABLE = r"{{[1-9][0-9]*}}"
54 changes: 54 additions & 0 deletions mail_gateway_whatsapp/views/mail_whatsapp_template_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
readonly="state != 'draft'"
options="{'no_create': True}"
/>
<field name="model_id" />
<field name="category" readonly="state != 'draft'" />
<field name="language" readonly="state != 'draft'" />
</group>
Expand All @@ -104,6 +105,59 @@
<page name="body" string="Body">
<field name="body" readonly="state != 'draft'" />
</page>
<page name="buttons" string="Buttons">
<field name="button_ids" readonly="state != 'draft'">
<list editable="bottom">
<field name="sequence" widget="handle" />
<field name="button_type" />
<field
name="url_type"
readonly="button_type != 'url'"
required="button_type == 'url'"
invisible="button_type != 'url'"
/>
<field name="name" required="1" />
<field
name="website_url"
readonly="button_type != 'url'"
required="button_type == 'url'"
invisible="button_type != 'url'"
placeholder="e.g. https://www.example.com"
/>
<field
name="call_number"
readonly="button_type != 'phone_number'"
required="button_type == 'phone_number'"
invisible="button_type != 'phone_number'"
/>
</list>
</field>
</page>
<page name="variables" string="Variables">
<field name="variable_ids">
<list editable="bottom" create="0" delete="0">
<field name="display_name" string="Name" />
<field name="sample_value" required="1" />
<field
name="field_name"
widget="DynamicModelFieldSelectorChar"
required="1"
options="{'model': 'model'}"
/>
<field name="model" column_invisible="True" />
<field
name="line_type"
column_invisible="True"
force_save="1"
/>
<field
name="name"
column_invisible="True"
force_save="1"
/>
</list>
</field>
</page>
</notebook>
</sheet>
</form>
Expand Down
12 changes: 9 additions & 3 deletions mail_gateway_whatsapp/wizards/mail_compose_gateway_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,22 @@ class MailComposeGatewayMessage(models.TransientModel):
"mail.whatsapp.template",
domain="""[
('state', '=', 'approved'),
('is_supported', '=', True)
('is_supported', '=', True),
('model', '=', model)
]""",
)

@api.onchange("whatsapp_template_id")
def onchange_whatsapp_template_id(self):
if self.whatsapp_template_id:
self.body = markupsafe.Markup(self.whatsapp_template_id.body)
self.body = markupsafe.Markup(
self.whatsapp_template_id.render_body_message()
)

def _action_send_mail(self, auto_commit=False):
if self.whatsapp_template_id:
self = self.with_context(whatsapp_template_id=self.whatsapp_template_id.id)
self = self.with_context(
whatsapp_template_id=self.whatsapp_template_id.id,
res_id=int(self.res_ids.strip("[]")),
)
return super()._action_send_mail(auto_commit=auto_commit)
Loading