odoo18/addons_extensions/whatsapp/models/whatsapp_template_button.py

113 lines
4.5 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from urllib.parse import urlparse
from odoo import api, fields, models, _
from odoo.addons.phone_validation.tools import phone_validation
from odoo.exceptions import UserError, ValidationError
class WhatsAppTemplateButton(models.Model):
_name = 'whatsapp.template.button'
_description = 'WhatsApp Template Button'
_order = 'sequence,id'
sequence = fields.Integer()
name = fields.Char(string="Button Text", size=25)
wa_template_id = fields.Many2one(comodel_name='whatsapp.template', required=True, ondelete='cascade')
button_type = fields.Selection([
('url', 'Visit Website'),
('phone_number', 'Call Number'),
('quick_reply', 'Quick Reply')], string="Type", required=True, default='quick_reply')
url_type = fields.Selection([
('static', 'Static'),
('dynamic', 'Dynamic')], string="Url Type", default='static')
website_url = fields.Char(string="Website URL")
call_number = fields.Char(string="Call Number")
has_invalid_number = fields.Boolean(compute="_compute_has_invalid_number")
variable_ids = fields.One2many(
'whatsapp.template.variable', 'button_id',
compute='_compute_variable_ids', precompute=True, store=True,
copy=True)
_sql_constraints = [
(
'unique_name_per_template',
'UNIQUE(name, wa_template_id)',
"Button names must be unique in a given template"
)
]
@api.depends('button_type', 'call_number')
def _compute_has_invalid_number(self):
for button in self:
if button.button_type == 'phone_number' and button.call_number:
try:
phone_validation.phone_format(
button.call_number,
False,
False,
)
except UserError:
if country := self.env.user.country_id or self.env.company.country_id:
try:
phone_validation.phone_format(
button.call_number,
country.code,
country.phone_code,
)
except UserError:
button.has_invalid_number = True
continue
button.has_invalid_number = False
def _get_button_variable_vals(self, button):
return {
"demo_value": button.website_url + "???",
"line_type": "button",
"name": button.name,
"wa_template_id": button.wa_template_id.id,
}
def _filter_dynamic_buttons(self):
"""
Retrieve buttons filtered by 'dynamic' URL type.
"""
dynamic_urls = self.filtered(lambda button: button.button_type == 'url' and button.url_type == 'dynamic')
return dynamic_urls
@api.depends('button_type', 'url_type', 'website_url', 'name')
def _compute_variable_ids(self):
button_urls = self._filter_dynamic_buttons()
to_clear = self - button_urls
for button in button_urls:
if button.variable_ids:
button.variable_ids = [
(1, button.variable_ids[0].id, self._get_button_variable_vals(button)),
]
else:
button.variable_ids = [
(0, 0, self._get_button_variable_vals(button)),
]
if to_clear:
to_clear.variable_ids = [(5, 0)]
def check_variable_ids(self):
for button in self:
if len(button.variable_ids) > 1:
raise ValidationError(_('Buttons may only contain one placeholder.'))
if button.variable_ids and button.url_type != 'dynamic':
raise ValidationError(_('Only dynamic urls may have a placeholder.'))
elif button.url_type == 'dynamic' and not button.variable_ids:
raise ValidationError(_('All dynamic urls must have a placeholder.'))
if button.variable_ids.name != "{{1}}":
raise ValidationError(_('The placeholder for a button can only be {{1}}.'))
@api.onchange('website_url')
def _onchange_website_url(self):
if self.website_url:
parsed_url = urlparse(self.website_url)
if not (parsed_url.scheme in {'http', 'https'} and parsed_url.netloc):
self.website_url = f"https://{self.website_url}"