# Feature Specification: Cambio de Titular de Puntos de Suministro con Trazabilidad y Sincronización Contractual

**Feature Branch**: `015-cambio-titular-puntosuministro`

**Created**: 2026-10-08

**Status**: Draft

**Input**: Petición de especificación para el módulo de Cambio de Titular de Puntos de Suministro en el Dashboard:
- Modificación de titularidad en Punto de Suministro (`CodCli`).
- Registro en tabla histórica de cambios con flag de procesamiento.
- Sincronización inmediata para contratos/propuestas pendientes (`NrContratoAudax` nulo o '0') por punto de suministro, marcando flag de cambio de titular, ajustando fecha de activación a la fecha del cambio, y reasignando cliente solo para propuestas comerciales tipo 1 y 2 (no para tipo 3 de representantes legales).
- Aplicación diferida al generar nuevos contratos cuando no hay propuestas pendientes: herencia de fecha de activación (fecha de cambio) y fecha de vencimiento del contrato vigente previo del CUPS, marcando cambio de titular y cerrando el log a procesado.
- Protección ante asignación masiva de fechas en contratos (TipProCom 2 y 3) para preservar las fechas del cambio de titular, con distintivo visual/color para identificar CUPS con cambio de titular activo.

> **Constitution (I. Spec-First)**: Este spec MUST ser agnóstico de stack.
> No mencionar Laravel, React, Inertia.js ni rutas de código. El CÓMO va en `plan.md`.

---

## Resumen del Problema y Propósito

En la gestión de CUPS y Puntos de Suministro dentro del Dashboard, los usuarios necesitan reasignar la titularidad de un punto de suministro de un cliente a otro cliente registrado en el sistema. 

Actualmente, este proceso carece de:
1. Una pista de auditoría e histórico formal que registre quién, cuándo y hacia quién se cambió el titular, incluyendo el estado de absorción/procesamiento de dicho movimiento.
2. Una sincronización automatizada y segura con los contratos y propuestas comerciales, tanto en escenarios inmediatos (cuando ya existen contratos en elaboración/pendientes de tramitación) como en escenarios diferidos (cuando el cambio de titular se produce sin contratos pendientes y debe heredarse de forma obligatoria al generar el siguiente contrato).
3. Respeto por las tipologías de contratación: en propuestas de tipo Representante Legal (tipo 3) el titular contractual global no debe sobreescribirse automáticamente, mientras que en propuestas directas (tipos 1 y 2) sí se actualiza.
4. Protección en la edición y elaboración de contratos multipunto frente a la herramienta de "asignación masiva de fechas", garantizando que las fechas específicas derivadas de un cambio de titular prevalezcan y no sean sobreescritas accidentalmente, acompañadas de una clara distinción visual en la interfaz.

Esta especificación formaliza las reglas de negocio, entidades, comportamientos de sincronización y criterios de aceptación para resolver esta necesidad de forma integral.

---

## User Scenarios & Testing *(mandatory)*

### User Story 1 — Reasignar Titular de Punto de Suministro con Registro Histórico de Auditoría (Priority: P1)

Como gestor energético en el Dashboard, necesito transferir la titularidad de un Punto de Suministro seleccionando un nuevo cliente registrado, de modo que el punto quede formalmente vinculado al nuevo titular y se preserve un registro histórico inmutable de la operación con su estado de procesamiento.

**Why this priority**: Es la operación esencial del ciclo de vida del punto de suministro; sin ella, no se puede cambiar legalmente el cliente de un punto ni auditar los traspasos anteriores.

**Independent Test**: Seleccionar un punto de suministro con un cliente actual, indicar un cliente nuevo diferente, ejecutar el cambio y verificar que el punto refleja el nuevo cliente y que existe un nuevo registro en el histórico con los clientes origen/destino, fecha/hora y flag de procesamiento inicial.

**Acceptance Scenarios**:

1. **Given** un punto de suministro asignado al Cliente A, **When** el usuario selecciona como nuevo titular al Cliente B y confirma la acción, **Then** el punto de suministro actualiza su titular a Cliente B y se crea un registro de histórico con Cliente A (anterior), Cliente B (nuevo), fecha/hora del cambio, usuario responsable y flag `procesado = false` (si no es absorbido inmediatamente).
2. **Given** un punto de suministro asignado al Cliente A, **When** el usuario intenta seleccionar al mismo Cliente A como nuevo titular, **Then** el sistema bloquea la operación informando que el cliente seleccionado ya es el titular actual.
3. **Given** un punto de suministro con múltiples CUPS asociados (ej. suministro dual de electricidad y gas), **When** se confirma el cambio de titular del punto, **Then** la reasignación de titularidad aplica de manera uniforme a todos los suministros vinculados a dicho punto.

---

### User Story 2 — Sincronización Inmediata en Contratos/Propuestas Comerciales Pendientes (Priority: P1)

Como gestor de contratación, cuando realizo un cambio de titular de un punto de suministro que ya forma parte de contratos o propuestas comerciales en elaboración (en estado pendiente / sin tramitación), necesito que el sistema actualice automáticamente dichas líneas marcando el cambio de titular, ajustando la fecha de activación a la fecha del cambio y reasignando el cliente cuando corresponda según el tipo de propuesta.

**Why this priority**: Evita inconsistencias operativas donde se tramita un contrato pendiente con datos obsoletos del titular o fechas desalineadas con la fecha real del traspaso.

**Independent Test**: Realizar un cambio de titular sobre un punto de suministro que posee al menos una propuesta comercial pendiente (sin tramitar). Verificar que en las líneas de contrato del punto se marca el indicador de cambio de titular, la fecha de activación pasa a ser la fecha del cambio, el registro histórico pasa a `procesado = true`, y el cliente de la propuesta solo se reasigna si el tipo de propuesta no es tipo 3 (Representante Legal).

**Acceptance Scenarios**:

1. **Given** un punto de suministro con propuestas comerciales en estado pendiente/no tramitado (identificador de tramitación nulo o en cero), **When** se ejecuta el cambio de titular, **Then** el sistema marca en todas las líneas de ese punto el indicador de cambio de titular en verdadero (`1`), establece su fecha de activación (`FecActCUPs`) igual a la fecha del cambio de titular, y marca el registro de histórico como `procesado = true`.
2. **Given** una propuesta comercial pendiente de Tipo 1 o Tipo 2 vinculada al punto, **When** se procesa la sincronización inmediata del cambio de titular, **Then** el cliente asociado a la propuesta comercial se actualiza al nuevo cliente titular.
3. **Given** una propuesta comercial pendiente de Tipo 3 (contratos por Representante Legal / Gestor), **When** se procesa la sincronización inmediata del cambio de titular, **Then** se marcan las líneas de CUPS y sus fechas pero **NO** se reasigna el cliente de la propuesta comercial, preservando la cabecera del representante legal.
4. **Given** que el punto no posee ninguna propuesta pendiente, **When** se ejecuta el cambio de titular, **Then** el registro de histórico permanece con `procesado = false` para su procesamiento diferido.

---

### User Story 3 — Aplicación Diferida de Cambio de Titular al Generar Nuevos Contratos (Priority: P1)

Como gestor de contratación, cuando genero un nuevo contrato para un punto de suministro que tiene un cambio de titular registrado y no procesado previamente, necesito que el sistema incorpore automáticamente el cambio de titular, heredando la fecha de inicio del cambio y la fecha de vencimiento del último contrato vigente previo de ese CUPS.

**Why this priority**: Garantiza la continuidad contractual y la sincronización correcta entre comercializadoras cuando no existía un borrador previo al momento de realizar el cambio de titular en el punto.

**Independent Test**: Registrar un cambio de titular sobre un punto sin contratos pendientes (dejando log no procesado). Crear posteriormente un nuevo contrato para el CUPS de ese punto que tiene un contrato vigente anterior. Comprobar que el nuevo contrato adopta como fecha de activación la fecha del cambio, como fecha de vencimiento la del contrato vigente anterior, se marca el indicador de cambio de titular y el log histórico pasa a `procesado = true`.

**Acceptance Scenarios**:

1. **Given** un punto de suministro con un registro de cambio de titular no procesado (`procesado = false`) y un contrato previo vigente en el sistema para ese CUPS, **When** se genera una nueva propuesta/contrato para dicho CUPS, **Then** el sistema asigna en la nueva línea:
   - Fecha de activación (`FecActCUPs`) = Fecha del cambio de titular.
   - Fecha de vencimiento (`FecVenCUPs`) = Fecha de vencimiento (`FecVenCUPs`) del contrato vigente previo.
   - Indicador de cambio de titular = Verdadero (`1`).
   - Y actualiza el registro histórico a `procesado = true`.
2. **Given** un punto con cambio de titular no procesado pero cuyo CUPS no tiene ningún contrato previo vigente, **When** se genera el nuevo contrato, **Then** la fecha de activación adopta la fecha del cambio de titular, la fecha de vencimiento se calcula según la vigencia estándar del producto/tarifa contratada, se marca el indicador de cambio de titular y el histórico pasa a `procesado = true`.
3. **Given** un punto sin cambios de titular pendientes (`procesado = true` o sin registros), **When** se genera un nuevo contrato, **Then** las fechas de contratación y el indicador de cambio de titular se determinan por el flujo normal de contratación sin alteraciones.

---

### User Story 4 — Protección frente a Asignación Masiva de Fechas y Señalización Visual en Contratos (Priority: P2)

Como usuario que elabora o edita propuestas comerciales multipunto (Tipos 2 y 3), necesito que la herramienta de asignación masiva de fechas respete y no sobreescriba las fechas de aquellos CUPS que tienen un cambio de titular activo, y que dichos CUPS se identifiquen a simple vista con un distintivo visual claro en la tabla de contratación.

**Why this priority**: Previene errores operativos humanos críticos donde una asignación masiva de fechas sobre 10 o 50 suministros borra inadvertidamente las fechas legales de traspaso de titularidad de los suministros afectados.

**Independent Test**: En una propuesta comercial multipunto con múltiples CUPS donde al menos uno tiene cambio de titular activo:
1. Comprobar que la fila del CUPS con cambio de titular muestra un estilo visual diferenciador (color/distintivo) y un indicador informativo.
2. Aplicar la función de asignación masiva de fechas de inicio/fin a toda la tabla y verificar que los CUPS ordinarios se actualizan mientras que el CUPS con cambio de titular preserva intactas sus fechas.

**Acceptance Scenarios**:

1. **Given** una propuesta comercial con múltiples CUPS donde uno o varios tienen el indicador de cambio de titular activo (`1`), **When** el usuario visualiza la tabla de suministros, **Then** las filas correspondientes se muestran con un color o distintivo visual destacado (ej. borde/fondo temático diferenciado y etiqueta de "Cambio de titular activo").
2. **Given** una tabla de propuesta comercial (Tipo 2 o Tipo 3) con CUPS que tienen cambio de titular activo y CUPS ordinarios, **When** el usuario ejecuta la acción de "Asignación masiva de fechas", **Then** el sistema aplica las nuevas fechas únicamente a los CUPS sin cambio de titular, omitiendo explícitamente y preservando las fechas de los CUPS con cambio de titular activo.
3. **Given** que un usuario intenta modificar manualmente las fechas de un CUPS con cambio de titular en la fila individual, **When** interactúa con los selectores de fecha, **Then** el sistema emite una advertencia confirmatoria informando que dicho suministro tiene un cambio de titular vinculado.

---

## Edge Cases

- **Puntos duales (electricidad y gas combinados)**: Cuando un punto de suministro contiene tanto un CUPS eléctrico como un CUPS de gas bajo el mismo código de punto (`CodPunSum`), la lógica de sincronización (inmediata o diferida) debe procesar ambas ramas de suministro de forma coherente.
- **Múltiples cambios de titular consecutivos sin procesar**: Si un punto sufre más de un cambio de titular antes de que se genere o tramite un contrato, el sistema debe tomar el movimiento más reciente para las fechas y consolidar los registros anteriores.
- **Contratos pendientes cancelados o descartados**: Si una propuesta pendiente se elimina o anula sin tramitar, cualquier cambio de titular posterior debe poder registrarse y resolverse sin bloqueos de integridad referencial.
- **Inexistencia de contrato previo vigente en aplicación diferida**: Si al generar un contrato nuevo el CUPS no tiene histórico de contrato previo vigente, no debe producirse error; se asigna la fecha de cambio como inicio y se calcula el vencimiento estándar (ej. 1 año / 12 meses) según el producto o tarifa seleccionada.
- **CUPS sin punto de suministro asociado**: Si un CUPS no tuviera `CodPunSum` asignado por inconsistencia heredada de datos, la búsqueda de sincronización diferida debe utilizar el identificador propio del CUPS como criterio secundario de resolución.

---

## Requirements *(mandatory)*

### Functional Requirements

- **FR-001**: El sistema DEBE proveer en el Dashboard un módulo o modal accesible desde la gestión de CUPS / Puntos de Suministro para ejecutar la acción de "Cambio de Titular".
- **FR-002**: El sistema DEBE validar que el nuevo titular seleccionado exista en la base de datos de clientes y sea distinto al titular actual del punto de suministro.
- **FR-003**: El sistema DEBE actualizar el titular del punto de suministro (`CodCli`) de forma atómica dentro de una transacción segura.
- **FR-004**: El sistema DEBE registrar en una entidad histórica de auditoría cada movimiento de cambio de titular con: identificador del punto de suministro, cliente anterior, nuevo cliente, fecha/hora del cambio, usuario responsable y estado de procesamiento (`procesado`).
- **FR-005**: El sistema DEBE verificar si existen propuestas comerciales o contratos vinculados al punto de suministro en estado pendiente/no tramitado (identificador de tramitación nulo, vacío o igual a cero).
- **FR-006**: Si existen propuestas pendientes para el punto, el sistema DEBE marcar en sus líneas el indicador de cambio de titular en verdadero (`1`).
- **FR-007**: Si existen propuestas pendientes para el punto, el sistema DEBE establecer la fecha de activación de las líneas (`FecActCUPs`) igual a la fecha del cambio de titular.
- **FR-008**: Si la propuesta comercial pendiente es de Tipo 1 (UniCliente UniPunto) o Tipo 2 (UniCliente MultiPunto), el sistema DEBE reasignar el cliente titular de la propuesta al nuevo cliente.
- **FR-009**: Si la propuesta comercial pendiente es de Tipo 3 (MultiCliente MultiPunto / Representante Legal), el sistema NO DEBE reasignar el cliente titular de la cabecera de la propuesta comercial, manteniendo al representante/gestor.
- **FR-010**: Cuando una propuesta pendiente absorbe el cambio de titular, el sistema DEBE marcar el registro histórico correspondiente como `procesado = true`.
- **FR-011**: Si no existen propuestas pendientes al momento del cambio, el registro histórico DEBE permanecer con `procesado = false`.
- **FR-012**: En el flujo de creación/alimentación de líneas de contrato/propuesta comercial, el sistema DEBE consultar si existen cambios de titular no procesados (`procesado = false`) para el punto de suministro o CUPS.
- **FR-013**: Ante un cambio de titular no procesado en la creación de un contrato, el sistema DEBE buscar el último contrato previo vigente del CUPS (ordenado por fecha de activación y con fecha de vencimiento posterior o vigente).
- **FR-014**: Al encontrar un contrato previo vigente en aplicación diferida, la nueva línea de contrato DEBE adoptar:
  - Fecha de activación = Fecha del cambio de titular.
  - Fecha de vencimiento = Fecha de vencimiento del contrato previo vigente.
  - Indicador de cambio de titular = Verdadero (`1`).
- **FR-015**: Al aplicar el cambio de titular diferido en la nueva línea de contrato, el sistema DEBE actualizar el registro histórico a `procesado = true`.
- **FR-016**: Si no existe contrato previo vigente para el CUPS en aplicación diferida, el sistema DEBE asignar la fecha del cambio de titular como inicio y calcular la fecha de fin según el período contractual estándar del producto/tarifa.
- **FR-017**: En las pantallas de edición y contratación de propuestas comerciales (Tipos 2 y 3), la función de "Asignación masiva de fechas" DEBE excluir explícitamente y no sobreescribir las fechas de los CUPS marcados con cambio de titular activo.
- **FR-018**: En las tablas de CUPS de propuestas y contratos, el sistema DEBE mostrar una indicación visual destacada (color, distintivo o etiqueta) en cada línea que tenga un cambio de titular activo.
- **FR-019**: El sistema DEBE proveer en la vista del punto de suministro una pestaña o sección para consultar el histórico de cambios de titular realizados.

### Key Entities

- **PuntoSuministro**: Entidad que representa la instalación física y agrupa uno o varios suministros (CUPS). Atributos clave: identificador de punto (`CodPunSum`), cliente titular asignado (`CodCli`), dirección y estado.
- **Cliente**: Entidad titular. Atributos clave: identificador de cliente (`CodCli`), razón social o nombre, documento de identidad fiscal.
- **HistoricoCambioTitular**: Entidad de auditoría de traspasos de titularidad. Atributos conceptuales:
  - Identificador único de movimiento.
  - Punto de suministro referenciado (`CodPunSum`).
  - Cliente anterior (`CodCliAnt`).
  - Cliente nuevo (`CodCliNue`).
  - Fecha y hora efectiva del cambio (`FecCambio`).
  - Flag de procesamiento (`procesado`: booleano).
  - Usuario que ejecutó la operación.
- **PropuestaComercialCups**: Línea de suministro dentro de una propuesta o contrato comercial. Atributos conceptuales relevantes: identificador de línea, identificador de punto de suministro, identificador de CUPS, tipo de CUPS (luz/gas), fecha de activación (`FecActCUPs`), fecha de vencimiento (`FecVenCUPs`), bandera de cambio de titular (`CambioTitular`), número de contrato de tramitación (`NrContratoAudax`).
- **PropuestaComercialCliente / PropuestaComercial**: Cabecera de la propuesta o contrato. Atributos clave: tipo de propuesta comercial (`TipProCom`: 1, 2, 3), cliente asignado (`CodCli`).

---

## Success Criteria *(mandatory)*

### Measurable Outcomes

- **SC-001**: El 100% de los cambios de titular realizados desde el Dashboard generan un registro en el histórico con trazabilidad completa (actor, clientes, fechas y flag de procesamiento).
- **SC-002**: El 100% de las propuestas comerciales no tramitadas asociadas a un punto con cambio de titular son actualizadas de inmediato con `CambioTitular = 1`, fecha de activación ajustada y reasignación condicional según `TipProCom`.
- **SC-003**: Cero incidencias de sobreescritura accidental de fechas por la función de "Asignación masiva" en suministros con cambio de titular activo.
- **SC-004**: En aplicación diferida, el 100% de los nuevos contratos generados para puntos con cambios no procesados heredan con exactitud la fecha del cambio y la fecha de vencimiento del contrato previo vigente, cerrando el log a `procesado = true`.
- **SC-005**: El tiempo de ejecución del cambio de titular (incluida la transacción y sincronización de propuestas vinculadas) no excede los 1.5 segundos.

---

## Assumptions

- Se asume que un contrato en estado "Pendiente / Sin tramitar" es aquel cuyo campo de tramitación oficial (`NrContratoAudax` o equivalente) es nulo, vacío o tiene valor numérico cero (`0`).
- Se asume que las propuestas comerciales `TipProCom = 3` corresponden a contrataciones multipunto multicliente gestionadas por un representante legal o gestor común, por lo que la titularidad general del contrato permanece en dicho representante.
- Se asume que un contrato previo se considera "vigente" si posee fecha de activación menor o igual a la actual y fecha de vencimiento mayor o igual a la fecha del cambio de titular (o fecha de vencimiento nula/abierta en contratos indefinidos).
- Se asume que la interfaz de asignación masiva de fechas cuenta con una verificación previa al iterar las filas para saltar aquellas que tengan activa la propiedad `CambioTitular`.
