# ENTITIES.md - MAI-009 Facturacion Transporte **Modulo:** MAI-009 | **Version:** 1.0.0 | **Actualizado:** 2026-01-25 --- ## Resumen | Metrica | Valor | |---------|-------| | Total Entidades | 6 | | Schema BD | billing | | ENUMs | 4 | | Estado | Implementado | --- ## 1. Lane **Archivo:** `lane.entity.ts` **Tabla:** `billing.lanes` **Descripcion:** Rutas/lanes de transporte (origen-destino) para cotizacion. ### Campos | Campo | Tipo | Null | Default | Descripcion | |-------|------|------|---------|-------------| | id | uuid | No | gen | Identificador unico | | tenantId | uuid | No | - | Tenant (empresa) | | codigo | varchar(50) | No | - | Codigo unico del lane | | nombre | varchar(200) | No | - | Nombre descriptivo | | origenCiudad | varchar(100) | No | - | Ciudad de origen | | origenEstado | varchar(100) | No | - | Estado de origen | | origenCodigoPostal | varchar(10) | Si | - | CP origen | | destinoCiudad | varchar(100) | No | - | Ciudad de destino | | destinoEstado | varchar(100) | No | - | Estado de destino | | destinoCodigoPostal | varchar(10) | Si | - | CP destino | | distanciaKm | decimal(10,2) | Si | - | Distancia en km | | tiempoEstimadoHoras | decimal(6,2) | Si | - | Tiempo estimado hrs | | activo | boolean | No | true | Lane activo | | createdAt | timestamptz | No | now() | Fecha creacion | | createdById | uuid | No | - | Usuario creador | ### Indices - `idx_lane_tenant` (tenantId) - `idx_lane_codigo` (tenantId, codigo) UNIQUE ### Helpers - `descripcionCorta`: "Ciudad Origen -> Ciudad Destino" - `descripcionCompleta`: "Ciudad, Estado -> Ciudad, Estado" --- ## 2. Tarifa **Archivo:** `tarifa.entity.ts` **Tabla:** `billing.tarifas` **Descripcion:** Tarifas de transporte por lane, cliente, tipo de servicio. ### Campos | Campo | Tipo | Null | Default | Descripcion | |-------|------|------|---------|-------------| | id | uuid | No | gen | Identificador unico | | tenantId | uuid | No | - | Tenant (empresa) | | codigo | varchar(50) | No | - | Codigo de tarifa | | nombre | varchar(200) | No | - | Nombre descriptivo | | descripcion | text | Si | - | Descripcion detallada | | clienteId | uuid | Si | - | FK a cliente (tarifa especifica) | | laneId | uuid | Si | - | FK a lane | | modalidadServicio | varchar(50) | Si | - | FTL, LTL, etc. | | tipoEquipo | varchar(50) | Si | - | Caja seca, refrigerado, etc. | | tipoTarifa | enum | No | - | Tipo de calculo | | tarifaBase | decimal(15,2) | No | - | Monto base | | tarifaKm | decimal(10,4) | Si | - | Tarifa por km | | tarifaTonelada | decimal(10,4) | Si | - | Tarifa por tonelada | | tarifaM3 | decimal(10,4) | Si | - | Tarifa por m3 | | tarifaPallet | decimal(10,4) | Si | - | Tarifa por pallet | | tarifaHora | decimal(10,4) | Si | - | Tarifa por hora | | minimoFacturar | decimal(15,2) | Si | - | Minimo a facturar | | pesoMinimoKg | decimal(10,2) | Si | - | Peso minimo kg | | moneda | varchar(3) | No | MXN | Moneda (MXN, USD) | | fechaInicio | date | No | - | Inicio vigencia | | fechaFin | date | Si | - | Fin vigencia | | activa | boolean | No | true | Tarifa activa | | createdAt | timestamptz | No | now() | Fecha creacion | | createdById | uuid | No | - | Usuario creador | | updatedAt | timestamptz | No | now() | Fecha actualizacion | ### Relaciones | Relacion | Tipo | Target | Campo FK | |----------|------|--------|----------| | lane | ManyToOne | Lane | laneId | ### Indices - `idx_tarifa_tenant` (tenantId) - `idx_tarifa_cliente` (clienteId) - `idx_tarifa_lane` (laneId) - `idx_tarifa_activa` (tenantId, activa, fechaInicio) ### ENUMs Asociados ```typescript enum TipoTarifa { POR_VIAJE = 'POR_VIAJE', // Monto fijo por viaje POR_KM = 'POR_KM', // Base + km recorridos POR_TONELADA = 'POR_TONELADA', // Base + toneladas POR_M3 = 'POR_M3', // Base + metros cubicos POR_PALLET = 'POR_PALLET', // Base + pallets POR_HORA = 'POR_HORA', // Base + horas MIXTA = 'MIXTA', // Combinacion de criterios } ``` ### Helpers - `vigente`: true si activa y dentro de fechas - `esEspecifica`: true si tiene clienteId - `calcularMonto(params)`: Calcula monto segun tipoTarifa --- ## 3. RecargoCatalogo **Archivo:** `recargo-catalogo.entity.ts` **Tabla:** `billing.recargos_catalogo` **Descripcion:** Catalogo de recargos aplicables (fuel surcharge, detention, etc.). ### Campos | Campo | Tipo | Null | Default | Descripcion | |-------|------|------|---------|-------------| | id | uuid | No | gen | Identificador unico | | tenantId | uuid | No | - | Tenant (empresa) | | codigo | varchar(50) | No | - | Codigo unico | | nombre | varchar(200) | No | - | Nombre del recargo | | tipo | enum | No | - | Tipo de recargo | | descripcion | text | Si | - | Descripcion | | esPorcentaje | boolean | No | false | Es porcentaje o monto fijo | | monto | decimal(15,4) | No | - | Monto o porcentaje | | moneda | varchar(3) | No | MXN | Moneda | | aplicaAutomatico | boolean | No | false | Se aplica automaticamente | | condicionAplicacion | text | Si | - | Condicion para aplicar | | activo | boolean | No | true | Recargo activo | | createdAt | timestamptz | No | now() | Fecha creacion | | createdById | uuid | No | - | Usuario creador | ### Indices - `idx_recargo_tenant` (tenantId) - `idx_recargo_codigo` (tenantId, codigo) UNIQUE ### ENUMs Asociados ```typescript enum TipoRecargo { FUEL_SURCHARGE = 'FUEL_SURCHARGE', // Recargo combustible DETENTION = 'DETENTION', // Tiempo espera carga/descarga MANIOBRAS = 'MANIOBRAS', // Maniobras especiales CUSTODIA = 'CUSTODIA', // Escolta/custodia ESCOLTA = 'ESCOLTA', // Escolta armada PERNOCTA = 'PERNOCTA', // Pernocta de unidad ESTADIAS = 'ESTADIAS', // Dias extra FALSO_FLETE = 'FALSO_FLETE', // Viaje cancelado SEGURO_ADICIONAL = 'SEGURO_ADICIONAL', // Seguro extra OTRO = 'OTRO', // Otros } ``` ### Helpers - `calcularRecargo(base)`: Calcula monto segun esPorcentaje - `descripcionMonto`: "15%" o "$500.00 MXN" --- ## 4. FacturaTransporte **Archivo:** `factura-transporte.entity.ts` **Tabla:** `billing.facturas_transporte` **Descripcion:** Facturas de servicios de transporte (CFDI). ### Campos | Campo | Tipo | Null | Default | Descripcion | |-------|------|------|---------|-------------| | id | uuid | No | gen | Identificador unico | | tenantId | uuid | No | - | Tenant (empresa) | | serie | varchar(10) | Si | - | Serie de factura | | folio | varchar(20) | No | - | Folio de factura | | uuidCfdi | uuid | Si | - | UUID del CFDI timbrado | | clienteId | uuid | No | - | FK a cliente | | clienteRfc | varchar(13) | No | - | RFC del cliente | | clienteRazonSocial | varchar(200) | No | - | Razon social | | clienteUsoCfdi | varchar(10) | Si | - | Uso CFDI SAT | | fechaEmision | timestamptz | No | - | Fecha/hora emision | | fechaVencimiento | date | Si | - | Fecha vencimiento | | subtotal | decimal(15,2) | No | - | Subtotal | | descuento | decimal(15,2) | No | 0 | Descuento | | iva | decimal(15,2) | No | 0 | IVA | | retencionIva | decimal(15,2) | No | 0 | Retencion IVA | | retencionIsr | decimal(15,2) | No | 0 | Retencion ISR | | total | decimal(15,2) | No | - | Total factura | | moneda | varchar(3) | No | MXN | Moneda | | tipoCambio | decimal(10,4) | No | 1 | Tipo de cambio | | formaPago | varchar(10) | Si | - | Forma pago SAT | | metodoPago | varchar(10) | Si | - | Metodo pago SAT | | condicionesPago | varchar(200) | Si | - | Condiciones | | viajeIds | uuid[] | Si | - | IDs de viajes incluidos | | otIds | uuid[] | Si | - | IDs de OTs incluidas | | xmlCfdi | text | Si | - | XML del CFDI | | pdfUrl | text | Si | - | URL del PDF | | estado | enum | No | BORRADOR | Estado de factura | | montoPagado | decimal(15,2) | No | 0 | Monto pagado | | fechaPago | timestamptz | Si | - | Fecha de pago | | fechaCancelacion | timestamptz | Si | - | Fecha cancelacion | | motivoCancelacion | text | Si | - | Motivo cancelacion | | createdAt | timestamptz | No | now() | Fecha creacion | | createdById | uuid | No | - | Usuario creador | | updatedAt | timestamptz | No | now() | Fecha actualizacion | ### Relaciones | Relacion | Tipo | Target | Campo FK | |----------|------|--------|----------| | lineas | OneToMany | LineaFactura | facturaId | ### Indices - `idx_factura_tenant` (tenantId) - `idx_factura_cliente` (clienteId) - `idx_factura_estado` (tenantId, estado) - `idx_factura_fecha` (fechaEmision) - `idx_factura_folio` (tenantId, serie, folio) UNIQUE ### ENUMs Asociados ```typescript enum EstadoFactura { BORRADOR = 'BORRADOR', // En edicion EMITIDA = 'EMITIDA', // Timbrada ENVIADA = 'ENVIADA', // Enviada al cliente PAGADA = 'PAGADA', // Pagada completamente PARCIAL = 'PARCIAL', // Pago parcial VENCIDA = 'VENCIDA', // Vencida sin pago CANCELADA = 'CANCELADA', // Cancelada SAT } ``` ### Helpers - `saldoPendiente`: total - montoPagado - `estaPagada`: true si montoPagado >= total - `estaVencida`: true si paso fechaVencimiento - `diasVencida`: Dias desde vencimiento - `folioCompleto`: "SERIE-FOLIO" --- ## 5. LineaFactura **Archivo:** `linea-factura.entity.ts` **Tabla:** `billing.lineas_factura` **Descripcion:** Lineas/conceptos de una factura. ### Campos | Campo | Tipo | Null | Default | Descripcion | |-------|------|------|---------|-------------| | id | uuid | No | gen | Identificador unico | | tenantId | uuid | No | - | Tenant (empresa) | | facturaId | uuid | No | - | FK a factura | | linea | int | No | - | Numero de linea | | descripcion | text | No | - | Descripcion concepto | | claveProductoSat | varchar(10) | Si | - | Clave prod/serv SAT | | unidadSat | varchar(10) | Si | - | Clave unidad SAT | | cantidad | decimal(12,4) | No | - | Cantidad | | precioUnitario | decimal(15,4) | No | - | Precio unitario | | descuento | decimal(15,2) | No | 0 | Descuento | | importe | decimal(15,2) | No | - | Importe (cant * PU) | | ivaTasa | decimal(5,2) | No | 16 | Tasa IVA % | | ivaMonto | decimal(15,2) | Si | - | Monto IVA | | viajeId | uuid | Si | - | FK a viaje (referencia) | | otId | uuid | Si | - | FK a OT (referencia) | | recargoId | uuid | Si | - | FK a recargo aplicado | ### Relaciones | Relacion | Tipo | Target | Campo FK | |----------|------|--------|----------| | factura | ManyToOne | FacturaTransporte | facturaId | | recargo | ManyToOne | RecargoCatalogo | recargoId | ### Indices - `idx_linea_factura` (facturaId) ### Helpers - `importeNeto`: importe - descuento - `importeConIva`: importeNeto + ivaMonto - `calcularImporte()`: cantidad * precioUnitario - `calcularIva()`: importeNeto * (ivaTasa/100) --- ## 6. FuelSurcharge **Archivo:** `fuel-surcharge.entity.ts` **Tabla:** `billing.fuel_surcharge` **Descripcion:** Tabla de fuel surcharge (recargo por combustible) por periodo. ### Campos | Campo | Tipo | Null | Default | Descripcion | |-------|------|------|---------|-------------| | id | uuid | No | gen | Identificador unico | | tenantId | uuid | No | - | Tenant (empresa) | | fechaInicio | date | No | - | Inicio del periodo | | fechaFin | date | No | - | Fin del periodo | | precioDieselReferencia | decimal(10,4) | Si | - | Precio diesel base | | precioDieselActual | decimal(10,4) | Si | - | Precio diesel actual | | porcentajeSurcharge | decimal(5,2) | No | - | % a aplicar | | activo | boolean | No | true | Periodo activo | | createdAt | timestamptz | No | now() | Fecha creacion | | createdById | uuid | No | - | Usuario creador | ### Indices - `idx_fuel_surcharge_fecha` (tenantId, fechaInicio, fechaFin) ### Helpers - `vigente`: true si fecha actual en rango y activo - `variacionPrecio`: % variacion diesel actual vs referencia - `calcularRecargo(montoBase)`: montoBase * (porcentajeSurcharge/100) - `descripcionPeriodo`: "01/01/2026 - 15/01/2026" --- ## Diagrama de Relaciones ``` +----------------+ +----------------+ | Lane |<------+ Tarifa | +----------------+ +----------------+ | v +----------------+ +------------------+ | RecargoCatalogo|<------+ LineaFactura | +----------------+ +--------+---------+ | v +----------------+ +------------------+ | FuelSurcharge | | FacturaTransporte| +----------------+ +------------------+ | +----> Viajes/OTs (referencias) ``` --- ## Flujo de Facturacion ``` 1. CREAR FACTURA - Seleccionar viajes/OTs a facturar - Sistema calcula totales de servicios 2. AGREGAR LINEAS - Lineas automaticas desde viajes/OTs - Lineas manuales (recargos, ajustes) 3. APLICAR RECARGOS - Fuel surcharge (automatico si activo) - Detention, maniobras, etc. 4. REVISAR TOTALES - Subtotal, descuentos, IVA, retenciones - Total a cobrar 5. TIMBRAR CFDI - Generar XML con Carta Porte (MAE-016) - Enviar a PAC - Obtener UUID y sello 6. ENVIAR AL CLIENTE - PDF + XML por email - Registrar en portal 7. SEGUIMIENTO COBRANZA - Registrar pagos parciales/totales - Alertas de vencimiento ``` --- ## Casos de Uso ### CU-001: Crear Tarifa por Lane 1. Administrador define origen-destino (Lane) 2. Crea tarifa asociada con tipo de calculo 3. Define vigencia y monto minimo 4. Opcionalmente asocia a cliente especifico ### CU-002: Facturar Viajes 1. Operaciones cierra viajes con POD 2. Administracion selecciona viajes a facturar 3. Sistema genera factura con lineas 4. Aplica fuel surcharge vigente 5. Timbra y envia al cliente ### CU-003: Actualizar Fuel Surcharge 1. Administrador obtiene precio diesel actual 2. Compara con precio de referencia 3. Calcula % de incremento 4. Crea nuevo periodo de fuel surcharge 5. Sistema aplica automaticamente a nuevas facturas --- *MAI-009 Facturacion Transporte - ERP Transportistas v1.0.0*