bloque 4: campanas por segmentos con medicion (modulo skeen_campanas: segmentos reutilizables con conteo verificado, campanas por WhatsApp y correo con programacion, prueba previa, limite por minuto, pausa por errores, consentimiento por canal y atribucion de citas) + encuesta al salir con NPS (campo propio, envio automatico y recordatorio, reporte con tendencia y desglose); apagado por defecto

This commit is contained in:
2026-10-12 02:34:34 +00:00
parent 705b5a2842
commit a6d6df4ebd
37 changed files with 4619 additions and 44 deletions

View File

@@ -163,6 +163,12 @@ def limpiar_respuestas(campos, respuestas):
out[clave] = int(valor)
except (TypeError, ValueError):
out[clave] = None
elif tipo == 'nps':
try:
n = int(valor)
out[clave] = n if 0 <= n <= 10 else None
except (TypeError, ValueError):
out[clave] = None
elif tipo in ('firma', 'foto', 'archivo'):
out[clave] = bool(valor)
else:
@@ -209,6 +215,18 @@ def validar_respuestas(plantilla, campos, respuestas, fotos_claves,
except (TypeError, ValueError):
errores.append('%s debe ser un número del 1 al 10' % etiqueta)
continue
if tipo == 'nps':
if valor in (None, ''):
if obligatorio:
errores.append('Falta responder: %s' % etiqueta)
else:
try:
n = int(valor)
if not (0 <= n <= 10):
errores.append('%s debe estar entre 0 y 10' % etiqueta)
except (TypeError, ValueError):
errores.append('%s debe ser un número del 0 al 10' % etiqueta)
continue
if tipo == 'numero':
if valor in (None, ''):
if obligatorio:

View File

@@ -15,7 +15,9 @@ from odoo import fields, http
from odoo.http import request
from odoo.addons.skeen_whatsapp.controllers import public_booking as _pb
from odoo.addons.skeen_citas.clinic_settings import brand_dict, get_settings
from odoo.addons.skeen_citas.clinic_settings import (
brand_dict, get_encuestas, get_settings,
)
from odoo.addons.skeen_citas.glosario import resolve as resolver_glosario
from .comun import (
@@ -86,6 +88,17 @@ def _primer_nombre(partner):
return nombre.split(' ')[0] if nombre else ''
def _agradecimiento(env, plantilla):
"""Mensaje de gracias de la encuesta de satisfacción (si es la configurada)."""
try:
cfg = get_encuestas(env)
if cfg.get('plantilla_id') and int(cfg['plantilla_id']) == plantilla.id:
return (cfg.get('agradecimiento') or '').strip()
except Exception:
pass
return ''
class SkeenPublicFormularioController(http.Controller):
# ------------------------------------------------------------------
@@ -118,6 +131,7 @@ class SkeenPublicFormularioController(http.Controller):
} if cita else None,
'estado': respuesta.estado,
'ya_llenado': respuesta.estado == 'llenado',
'agradecimiento': _agradecimiento(request.env, plantilla),
'plantilla': {
'nombre': plantilla.name,
'tipo': plantilla.tipo,