19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:31:39 +01:00
parent 5df8c07b59
commit daa394e8b0
2114 changed files with 564841 additions and 299642 deletions

View file

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import werkzeug
from werkzeug.exceptions import NotFound
from odoo import http, _
@ -28,35 +29,75 @@ class MailingSMSController(http.Controller):
@http.route(['/sms/<int:mailing_id>/<string:trace_code>'], type='http', website=True, auth='public')
def blacklist_page(self, mailing_id, trace_code, **post):
""" Main entry point for unsubscribe links. Verify trace code (should
match mailing and trace), then check number can be sanitized. """
check_res = self._check_trace(mailing_id, trace_code)
if not check_res.get('trace'):
return request.redirect('/web')
found_traces = check_res.get('trace')
if not found_traces:
return request.redirect('/odoo')
valid_trace = request.env['mailing.trace'].sudo()
sanitized_number = False
sms_number = post.get('sms_number', '').strip()
if sms_number:
country = request.env['res.country'].sudo()
if country_code := request.geoip.country_code:
country = request.env['res.country'].search([('code', '=', country_code)], limit=1)
if not country:
country = request.env.company.country_id
try:
# Sanitize the phone number
sanitized_number = phone_validation.phone_format(
sms_number,
country.code,
country.phone_code,
force_format='E164',
raise_exception=True,
)
except Exception: # noqa: BLE001
sanitized_number = False
if sanitized_number:
valid_trace = found_traces.filtered(lambda t: t.sms_number == sanitized_number)
# trace found -> number valid, code matching
if valid_trace:
return request.redirect(
f'/sms/{mailing_id}/unsubscribe/{trace_code}?{werkzeug.urls.url_encode({"sms_number": sanitized_number})}'
)
# otherwise: generate error message, loop on same page
unsubscribe_error = False
if sms_number and not sanitized_number:
unsubscribe_error = _('Oops! The phone number seems to be incorrect. Please make sure to include the country code.')
if sanitized_number and not valid_trace:
unsubscribe_error = _('Oops! Number not found')
return request.render('mass_mailing_sms.blacklist_main', {
'mailing_id': mailing_id,
'sms_number': sms_number,
'trace_code': trace_code,
'unsubscribe_error': unsubscribe_error,
})
@http.route(['/sms/<int:mailing_id>/unsubscribe/<string:trace_code>'], type='http', website=True, auth='public')
def blacklist_number(self, mailing_id, trace_code, **post):
""" Effectively opt-out or enter number in block list. """
check_res = self._check_trace(mailing_id, trace_code)
if not check_res.get('trace'):
return request.redirect('/web')
country_code = request.geoip.get('country_code')
return request.redirect('/odoo')
# parse and validate number
sms_number = post.get('sms_number', '').strip(' ')
sanitize_res = phone_validation.phone_sanitize_numbers([sms_number], country_code, None)[sms_number]
tocheck_number = sanitize_res['sanitized'] or sms_number
trace = check_res['trace'].filtered(lambda r: r.sms_number == tocheck_number)[:1]
mailing_list_ids = trace.mass_mailing_id.contact_list_ids
tocheck_number = sms_number
trace = check_res['trace'].filtered(lambda r: r.sms_number == tocheck_number)[:1] if tocheck_number else False
# compute opt-out / blacklist information
lists_optout = request.env['mailing.list'].sudo()
lists_optin = request.env['mailing.list'].sudo()
unsubscribe_error = False
if tocheck_number and trace:
mailing_list_ids = trace.mass_mailing_id.contact_list_ids
if mailing_list_ids:
subscriptions = request.env['mailing.contact.subscription'].sudo().search([
subscriptions = request.env['mailing.subscription'].sudo().search([
('list_id', 'in', mailing_list_ids.ids),
('contact_id.phone_sanitized', '=', tocheck_number),
])
@ -65,17 +106,13 @@ class MailingSMSController(http.Controller):
else:
blacklist_rec = request.env['phone.blacklist'].sudo().add(tocheck_number)
blacklist_rec._message_log(
body=_('Blacklist through SMS Marketing unsubscribe (mailing ID: %s - model: %s)') %
(trace.mass_mailing_id.id, trace.mass_mailing_id.mailing_model_id.display_name))
lists_optin = request.env['mailing.contact.subscription'].sudo().search([
body=_('Blacklist through SMS Marketing unsubscribe (mailing ID: %(mailing_id)s - model: %(model)s)',
mailing_id=trace.mass_mailing_id.id, model=trace.mass_mailing_id.mailing_model_id.display_name))
lists_optin = request.env['mailing.subscription'].sudo().search([
('contact_id.phone_sanitized', '=', tocheck_number),
('list_id', 'not in', mailing_list_ids.ids),
('opt_out', '=', False),
]).mapped('list_id')
elif tocheck_number:
unsubscribe_error = _('Number %s not found', tocheck_number)
else:
unsubscribe_error = sanitize_res['msg']
return request.render('mass_mailing_sms.blacklist_number', {
'mailing_id': mailing_id,
@ -83,14 +120,12 @@ class MailingSMSController(http.Controller):
'sms_number': sms_number,
'lists_optin': lists_optin,
'lists_optout': lists_optout,
'unsubscribe_error': unsubscribe_error,
})
@http.route('/r/<string:code>/s/<int:sms_sms_id>', type='http', auth="public")
def sms_short_link_redirect(self, code, sms_sms_id, **post):
country_code = request.geoip.get('country_code')
if sms_sms_id:
trace_id = request.env['mailing.trace'].sudo().search([('sms_sms_id_int', '=', int(sms_sms_id))]).id
@http.route('/r/<string:code>/s/<int:sms_id_int>', type='http', auth="public")
def sms_short_link_redirect(self, code, sms_id_int, **post):
if sms_id_int:
trace_id = request.env['mailing.trace'].sudo().search([('sms_id_int', '=', int(sms_id_int))]).id
else:
trace_id = False
@ -98,7 +133,7 @@ class MailingSMSController(http.Controller):
request.env['link.tracker.click'].sudo().add_click(
code,
ip=request.httprequest.remote_addr,
country_code=country_code,
country_code=request.geoip.country_code,
mailing_trace_id=trace_id
)
redirect_url = request.env['link.tracker'].get_url_from_code(code)