# Data Model: Contratos MultiCliente MultiPunto

**Feature**: `007-contratos-multicliente-multipunto` | **Date**: 2026-05-28

## Dominio

Contratos con `TipProCom = 3` (MultiCliente MultiPunto). Nodo central de consulta: `PropuestaComercialCups` (una fila por punto de suministro). Titular del puente: **Contacto** (`T_ContactoCliente`). Cliente empresa: **Cliente** vía **ContactoDetalleCliente** (opcional).

## Diagrama ER

```mermaid
erDiagram
    PropuestaComercial ||--o{ PropuestaComercialCliente : tiene
    PropuestaComercialCliente }o--|| Contacto : titular_TipProCom3
    Contacto ||--o{ ContactoDetalleCliente : detalles
    ContactoDetalleCliente }o--o| Cliente : empresa_vinculada
    Contacto }o--|| Localidad : localidadFisica
    Cliente }o--|| Localidad : localidadSocial
    PropuestaComercialCliente ||--o{ PropuestaComercialCups : tiene
    PropuestaComercialCups }o--|| PuntoSuministro : en
    PuntoSuministro }o--|| Localidad : localidad
    PropuestaComercialCups }o--o| CupsElectrico : cupsElectrico
    PropuestaComercialCups }o--o| CupsGas : cupsGas
    PropuestaComercialCups }o--o| TarifaElectrica : tarifaElectrica
    PropuestaComercialCups }o--o| TarifaGas : tarifaGas
```

## Cambios en modelos

| Modelo | Cambio |
|--------|--------|
| `Contacto` | Añadir `localidadFisica()` → `T_Localidad` por `CodLocFis` |
| `PropuestaComercialCliente` | Ya tiene `contacto()` — sin cambios |
| `ContactoDetalleCliente` | Ya tiene `cliente()`, `contacto()` — sin cambios |
| Suministro (005) | Reutilizar sin cambios |

## Columnas de salida (listado / detalle)

| Alias negocio | Origen |
|---------------|--------|
| `CodProCom` | `PropuestaComercial.CodProCom` |
| `fechaContrato` | `PropuestaComercial.FecProCom` |
| `DocumentoIdentidadRepresentanteLegaloContacto` | `Contacto.NIFConCli` |
| `nombreRepresentanteLegaloContacto` | `Contacto.NomConCli` |
| `EmaConCli` | `Contacto.EmaConCli` |
| `TelFijConCli` | `Contacto.TelFijConCli` |
| `nombreCliente` | `Cliente.NomComCli` |
| `direccionCliente` | `Cliente.NomViaDomFis` |
| `emailCliente` | `Cliente.EmaCli` |
| `telefonoFijoCliente` | `Cliente.TelFijCli` |
| `FechaInicioContratoCup` / `FechaVencimientoContratoCup` | CUPs |
| `codigoCupsElectrico` / `codigoCupsGas` | CUPS eléctrico/gas |
| `NombreTarifaElectrica` / `NombreTarifaGas` | Tarifas |
| `consumoGas`, `consumoElectrico`, `PotEleConP1`–`P6` | CUPs |
| `direccionPuntoSuministro` | `PuntoSuministro.NomViaPunSum` |
| `LocalidadPuntoSuministro` | `puntoSuministro.localidad.DesLoc` |
| `direccionRepresentateLegalOContacto` | `Contacto.NomViaDomFis` |
| `localidadRepresentante` | `Contacto.localidadFisica.DesLoc` (equiv. `localidadCliente` en SQL ref.) |

## Dimensiones de agregación (lista blanca)

| Clave | Expresión conceptual |
|-------|---------------------|
| `localidad_suministro` | Localidad del punto de suministro |
| `localidad_representante` | Localidad física del contacto (`CodLocFis`) |
| `localidad_cliente_empresa` | Localidad social del cliente empresa (`CodLocSoc`) |
| `provincia_suministro` | Provincia vía localidad suministro |
| `provincia_representante` | Provincia vía localidad contacto |
| `provincia_cliente_empresa` | Provincia vía localidad cliente |
| `direccion_suministro` | Dirección punto suministro |
| `mes_contrato` / `anio_contrato` | `FecProCom` |
| `tarifa_electrica` / `tarifa_gas` | Tarifas |
| `tipo_energia` | `TipCups` 1/2 |
| `representante` | NIF + nombre contacto (**alta cardinalidad**) |
| `cliente_empresa` | NIF/nombre cliente (**alta cardinalidad**) |
| `estado` | `EstProCom` |
| `bucket_consumo_electrico` / `bucket_consumo_gas` | Rangos (igual 006) |

## Medidas numéricas

Igual que 006: `consumo_electrico`, `consumo_gas`, `potencia_p1`…`potencia_p6`.

## Reglas de agregación

- COUNT → `COUNT(DISTINCT CodProCom)`
- SUM/AVG/MIN/MAX → columnas CUPS; nulos excluidos de AVG
- Máximo 2 dimensiones en `agrupar_por`
- `truncated` siempre `false` en agregados
