10. Abonos

Sección deshabilitada en este despliegue. La variable de entorno ABONOS_ENABLED=false en el .env del servidor apaga todas las rutas /abonos/*. Los controladores (SeasonController, MemberController, DebtController, EventController, CommunicationController, ReportController, ScanController, SpaceController, TagController, DebtBatchController, DoorController, SeasonPassController, TicketController) y las vistas existen en el código fuente, pero no son accesibles desde este panel. Esta sección documenta la funcionalidad a partir del código y debe validarse cuando la sección se reactive.

Introducción

El módulo de Abonos es el corazón de la web de itesalpremios: gestiona las temporadas del club, los miembros / abonados, las deudas (recibos generados y domiciliados), los eventos (partidos, entrenamientos, actos sociales), las comunicaciones enviadas a los miembros y los reports de asistencia e ingresos. Es el módulo específico del segundo sitio del proyecto (itesalpremios) y solo está activo cuando la variable ABONOS_ENABLED=true en el .env del servidor.

Su modelo de datos está pensado para reflejar el ciclo real de un club: una temporada contiene eventos, los miembros pertenecen a una o varias temporadas, cada miembro puede tener deudas (anuales, puntuales, de abonos extra…) que se cobran vía SEPA, y a cada miembro se le pueden enviar comunicaciones (emails, SMS, notificaciones push) sobre los eventos en los que participa.

Acceso rápido

Pantalla principal

No hay captura disponible: la sección está deshabilitada en este despliegue (ver COVERAGE.md). La descripción que sigue se basa en el código fuente de los controladores (SeasonController, MemberController, DebtController, EventController, CommunicationController, ReportController) y debe validarse visualmente cuando la sección se reactive.

La pantalla principal del módulo, accesible en /abonos/seasons cuando el módulo está activo, es un listado de temporadas con:

El panel de cabecera del módulo (visible en /abonos/*) muestra además contadores agregados: miembros totales de la temporada activa, deudas pendientes, eventos próximos en los próximos 7 días, comunicaciones enviadas en los últimos 30 días.

Tareas habituales

10.1 Crear una temporada nueva

Una temporada es el contenedor principal del módulo: agrupa miembros, eventos, deudas y comunicaciones. Suele corresponder al año natural o a la temporada deportiva.

  1. Entra en /abonos/seasons.
  2. Pulsa Nueva temporada.
  3. Rellena:
    • Nombre (p. ej. Temporada 2026/27).
    • Fecha de inicio y fecha de fin.
    • Espacio principal (relación con Space; ver Referencia técnica).
    • Tipos de abonado que se ofrecerán (relación con SeasonPass). Por cada tipo: nombre, precio base, periodicidad (anual / mensual), descripción, edad mínima, edad máxima, número máximo de miembros.
    • Estado: borrador (no visible) o activa (visible para los flujos de alta).
  4. Guarda. La temporada se crea en estado borrador; actívala cuando esté lista.
  5. Si la temporada es similar a una anterior, usa la acción Clonar sobre la temporada de origen para copiar tipos de abonado y configuración.
Importante: una temporada solo puede ser activa si tiene al menos un tipo de abonado definido. Al activar la temporada, los tipos de abonado quedan disponibles para que los miembros se den de alta.

10.2 Dar de alta un miembro

Los miembros son las personas físicas abonadas al club. Un miembro puede pertenecer a varias temporadas a lo largo del tiempo, y dentro de cada temporada puede tener uno o varios abonos (uno por cada tipo de abonado contratado).

  1. Entra en /abonos/members.
  2. Pulsa Nuevo miembro.
  3. Rellena los datos personales:
    • Nombre, apellidos, DNI / NIE / pasaporte.
    • Email y teléfono (validación de formato).
    • Fecha de nacimiento (necesaria para validar límites de edad de los tipos de abonado).
    • Dirección postal (para correspondencia y, en su caso, para SEPA).
    • Tags / etiquetas (ver /abonos/tags) para segmentar.
  4. Asigna el miembro a una o varias temporadas. Por cada temporada, elige el tipo de abonado (esto genera automáticamente las deudas correspondientes al alta).
  5. Si el miembro paga por domiciliación bancaria (SEPA), añade los datos del titular y el IBAN. La deuda se generará y se cobrará en la fecha de cargo configurada.
  6. Guarda. El miembro queda registrado y, si tiene IBAN, entra en el siguiente lote de remesas SEPA.
Importante: el DNI/NIE/pasaporte debe ser único por miembro. El sistema rechaza duplicados. Si una persona cambia de tipo de abonado a mitad de temporada, se le da de baja en el antiguo y se le da de alta en el nuevo (con prorrateo o no, según la configuración de la temporada).

10.3 Registrar un pago / ver deudas

Las deudas son los recibos que el miembro debe pagar por sus abonos y servicios. Cada deuda tiene un estado: pendiente, cobrada, rechazada, anulada.

  1. Entra en /abonos/debts.
  2. Usa los filtros por temporada, miembro, estado y rango de fechas para localizar las deudas.
  3. Para registrar un pago manual (p. ej. ingreso en cuenta, Bizum, TPV físico), abre la deuda y pulsa Registrar pago. Indica:
    • Fecha del pago.
    • Importe (puede ser parcial).
    • Método de pago (efectivo, transferencia, TPV, Bizum, etc.).
    • Referencia / número de operación (opcional, recomendado para conciliaciones).
  4. Para generar el lote de remesas SEPA del mes:
    • Entra en /abonos/debts/batches (gestionado por DebtBatchController).
    • Pulsa Nuevo lote, selecciona la fecha de cargo y las deudas pendientes a incluir.
    • El sistema genera el fichero SEPA XML y lo deja en estado preparado.
    • Envía el fichero al banco (manualmente o vía integración) y marca el lote como enviado.
    • Cuando el banco devuelve el resultado, el sistema concilia automáticamente: las deudas enviadas pasan a cobradas o rechazadas según respuesta.

Desde la ficha de una deuda puedes ver su historial completo: alta, envío en lote, intentos de cargo, devoluciones, anulaciones.

10.4 Programar eventos (partidos, entrenamientos)

Los eventos representan cualquier acto del club: partidos, entrenamientos, cenas, presentaciones. Se usan para controlar acceso, registrar asistencia, generar comunicaciones y producir reports.

  1. Entra en /abonos/events.
  2. Pulsa Nuevo evento.
  3. Rellena:
    • Nombre (p. ej. Real Madrid — Barça, Entrenamiento infantil).
    • Tipo: partido, entrenamiento, evento social, etc.
    • Espacio (relación con Space) donde se celebra.
    • Fecha y hora de inicio y fin.
    • Aforo (opcional; si se deja vacío, no hay límite).
    • Precio por entrada (opcional, 0 = acceso con abono).
    • Visibilidad: público (aparece en la web), privado (solo gestión interna), solo abonados.
    • Permite scanner: sí / no (activa el módulo ScanController para validar accesos en puerta).
  4. Guarda. El evento aparece en el calendario de la temporada y, según la configuración, se publica en la web pública.
  5. Para eventos con venta de entradas, el módulo TicketController gestiona la compra online (integración con Stripe, ver sección 7) y la asignación de asientos si procede.

10.5 Enviar comunicaciones a miembros

El módulo de comunicaciones permite enviar emails, SMS o notificaciones push a segmentos de miembros o a asistentes concretos de un evento. Internamente delega en el módulo de mailing para el envío, por lo que reutiliza plantillas y contactos.

  1. Entra en /abonos/communications.
  2. Pulsa Nueva comunicación.
  3. Define el segmento objetivo:
    • Todos los miembros de una temporada.
    • Miembros con un tag concreto.
    • Asistentes confirmados a un evento.
    • Asistentes que NO han confirmado.
    • Miembros con deudas pendientes o con pagos rechazados.
    • Filtro libre por cualquier campo del miembro.
  4. Elige la plantilla (ver mailing) o redacta el mensaje.
  5. Selecciona el canal: email, SMS, push, o combinación.
  6. Programa el envío (inmediato, o a una fecha/hora concreta).
  7. Revisa la vista previa y los destinatarios estimados. Confirma y envía.

El envío queda registrado con un report accesible desde la ficha de la comunicación: total enviados, abiertos, clics, rebotes, errores.

10.6 Consultar reports (asistencia, ingresos)

Los reports del módulo (ReportController) ofrecen vistas agregadas sobre los datos:

Cada report admite exportar a CSV / Excel. Los reports se pueden filtrar por temporada y por rango de fechas.

Referencia técnica (webmasters)

Arquitectura del módulo

El módulo se divide en dos mitades:

Espacios (Space)

Un espacio es el lugar físico donde se celebran los eventos: el estadio principal, el campo de entrenamiento, el salón de actos. Permite separar temporadas y eventos por recinto, lo que es útil para clubes con varias instalaciones o para limitar aforos.

Domiciliaciones SEPA — SepaService.php

El fichero serv/src/services/SepaService.php se encarga de generar los ficheros SEPA XML (formato SEPA Direct Debit Core) que se envían al banco para cobrar los recibos de los miembros. Su responsabilidad es:

El flujo SEPA es, en resumen: generar lote → firmar XML → enviar al banco → recibir retorno → conciliar. Cada paso deja registro en el DebtBatch correspondiente.

Esquema de base de datos (tablas principales)

Las migraciones del módulo se encuentran en serv/database/migration_abonos*.sql. Las tablas principales son:

El esquema es relacional, con integridad referencial estricta. Los importes se almacenan en céntimos (enteros) para evitar problemas de redondeo con decimales flotantes.

Relación con otros módulos

Rutas internas relevantes

Estas rutas existen en el código fuente, pero no son accesibles en este despliegue (todas responden vacío/404 mientras ABONOS_ENABLED=false):

Errores frecuentes