DDL files created: - 01-transport-schema-ddl.sql: OT, embarques, viajes, paradas, POD, incidencias - 02-fleet-schema-ddl.sql: unidades, remolques, operadores, documentos, asignaciones - 03-tracking-schema-ddl.sql: posiciones GPS, eventos, geocercas, alertas, ETA - 04-fuel-schema-ddl.sql: cargas combustible, peajes, gastos, anticipos, rendimiento - 05-maintenance-schema-ddl.sql: planes, programacion, ordenes trabajo, checklist - 06-carriers-schema-ddl.sql: carriers, documentos, unidades, operadores, scorecard - 07-billing-transport-ddl.sql: lanes, tarifas, recargos, facturas, fuel surcharge - 08-compliance-schema-ddl.sql: carta porte CFDI 3.1, HOS NOM-087, inspecciones Features: - All tables with tenant_id and RLS policies - ENUMs for all status and type fields - Proper indexes for common queries - PostGIS for geospatial data - Partitioned tables for high-volume GPS data - CFDI Carta Porte 3.1 compliant structure Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
345 lines
10 KiB
SQL
345 lines
10 KiB
SQL
-- =============================================================================
|
|
-- ERP TRANSPORTISTAS - Schema Carriers DDL
|
|
-- =============================================================================
|
|
-- Archivo: 06-carriers-schema-ddl.sql
|
|
-- Version: 1.0.0
|
|
-- Fecha: 2026-01-25
|
|
-- Descripcion: Transportistas subcontratados, documentos, scorecard
|
|
-- =============================================================================
|
|
|
|
-- =============================================================================
|
|
-- TIPOS ENUMERADOS
|
|
-- =============================================================================
|
|
|
|
CREATE TYPE carriers.estado_carrier AS ENUM (
|
|
'PROSPECTO',
|
|
'EN_VALIDACION',
|
|
'ACTIVO',
|
|
'SUSPENDIDO',
|
|
'BAJA'
|
|
);
|
|
|
|
CREATE TYPE carriers.tipo_contrato AS ENUM (
|
|
'SPOT',
|
|
'DEDICADO',
|
|
'PREFERENTE'
|
|
);
|
|
|
|
-- =============================================================================
|
|
-- TABLA: carriers (Transportistas terceros)
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE carriers.carriers (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES public.tenants(id),
|
|
|
|
-- Identificación
|
|
codigo VARCHAR(20) NOT NULL,
|
|
razon_social VARCHAR(200) NOT NULL,
|
|
nombre_comercial VARCHAR(200),
|
|
|
|
-- Fiscal
|
|
rfc VARCHAR(13) NOT NULL,
|
|
regimen_fiscal VARCHAR(100),
|
|
|
|
-- SCT
|
|
permiso_sct VARCHAR(50),
|
|
tipo_permiso_sct VARCHAR(10),
|
|
permiso_vigencia DATE,
|
|
|
|
-- Contacto
|
|
contacto_nombre VARCHAR(200),
|
|
contacto_telefono VARCHAR(30),
|
|
contacto_email VARCHAR(255),
|
|
|
|
-- Dirección
|
|
direccion TEXT,
|
|
codigo_postal VARCHAR(10),
|
|
ciudad VARCHAR(100),
|
|
estado VARCHAR(100),
|
|
|
|
-- Operación
|
|
cobertura_estados TEXT[], -- Estados donde opera
|
|
tipos_equipo fleet.tipo_unidad[], -- Tipos de unidad disponibles
|
|
capacidad_unidades INT,
|
|
|
|
-- Tipo de relación
|
|
tipo_contrato carriers.tipo_contrato DEFAULT 'SPOT',
|
|
|
|
-- Términos comerciales
|
|
dias_pago INT DEFAULT 30,
|
|
porcentaje_retencion DECIMAL(5, 2) DEFAULT 4.00,
|
|
|
|
-- Seguros
|
|
poliza_seguro_carga VARCHAR(100),
|
|
poliza_vigencia DATE,
|
|
suma_asegurada DECIMAL(15, 2),
|
|
|
|
-- Evaluación
|
|
calificacion DECIMAL(3, 2) DEFAULT 0,
|
|
total_viajes INT DEFAULT 0,
|
|
viajes_a_tiempo INT DEFAULT 0,
|
|
incidentes INT DEFAULT 0,
|
|
|
|
-- Estado
|
|
estado carriers.estado_carrier DEFAULT 'PROSPECTO',
|
|
fecha_alta DATE,
|
|
fecha_baja DATE,
|
|
motivo_baja TEXT,
|
|
|
|
-- Datos bancarios
|
|
banco VARCHAR(100),
|
|
cuenta_bancaria VARCHAR(30),
|
|
clabe VARCHAR(18),
|
|
|
|
-- Auditoría
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
created_by_id UUID NOT NULL,
|
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
|
updated_by_id UUID,
|
|
|
|
CONSTRAINT uq_carrier_codigo UNIQUE (tenant_id, codigo),
|
|
CONSTRAINT uq_carrier_rfc UNIQUE (tenant_id, rfc)
|
|
);
|
|
|
|
CREATE INDEX idx_carrier_tenant ON carriers.carriers(tenant_id);
|
|
CREATE INDEX idx_carrier_estado ON carriers.carriers(tenant_id, estado);
|
|
|
|
-- =============================================================================
|
|
-- TABLA: documentos_carrier
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE carriers.documentos_carrier (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES public.tenants(id),
|
|
carrier_id UUID NOT NULL REFERENCES carriers.carriers(id),
|
|
|
|
-- Documento
|
|
tipo_documento VARCHAR(50) NOT NULL,
|
|
nombre VARCHAR(200) NOT NULL,
|
|
descripcion TEXT,
|
|
|
|
-- Vigencia
|
|
fecha_emision DATE,
|
|
fecha_vencimiento DATE,
|
|
|
|
-- Archivo
|
|
archivo_url TEXT,
|
|
archivo_nombre VARCHAR(255),
|
|
|
|
-- Verificación
|
|
verificado BOOLEAN DEFAULT FALSE,
|
|
verificado_por UUID,
|
|
verificado_fecha TIMESTAMPTZ,
|
|
|
|
-- Estado
|
|
activo BOOLEAN DEFAULT TRUE,
|
|
|
|
-- Auditoría
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
created_by_id UUID NOT NULL
|
|
);
|
|
|
|
CREATE INDEX idx_doc_carrier ON carriers.documentos_carrier(carrier_id);
|
|
CREATE INDEX idx_doc_vencimiento ON carriers.documentos_carrier(fecha_vencimiento);
|
|
|
|
-- =============================================================================
|
|
-- TABLA: unidades_carrier
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE carriers.unidades_carrier (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES public.tenants(id),
|
|
carrier_id UUID NOT NULL REFERENCES carriers.carriers(id),
|
|
|
|
-- Unidad
|
|
numero_economico VARCHAR(20) NOT NULL,
|
|
tipo fleet.tipo_unidad NOT NULL,
|
|
marca VARCHAR(50),
|
|
modelo VARCHAR(50),
|
|
anio INT,
|
|
placa VARCHAR(15),
|
|
|
|
-- SCT
|
|
configuracion_vehicular VARCHAR(10),
|
|
|
|
-- Capacidad
|
|
capacidad_peso_kg DECIMAL(10, 2),
|
|
capacidad_volumen_m3 DECIMAL(10, 4),
|
|
|
|
-- GPS
|
|
tiene_gps BOOLEAN DEFAULT FALSE,
|
|
gps_proveedor VARCHAR(50),
|
|
|
|
-- Estado
|
|
activa BOOLEAN DEFAULT TRUE,
|
|
|
|
-- Auditoría
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_unidad_carrier ON carriers.unidades_carrier(carrier_id);
|
|
|
|
-- =============================================================================
|
|
-- TABLA: operadores_carrier
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE carriers.operadores_carrier (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES public.tenants(id),
|
|
carrier_id UUID NOT NULL REFERENCES carriers.carriers(id),
|
|
|
|
-- Operador
|
|
nombre_completo VARCHAR(300) NOT NULL,
|
|
telefono VARCHAR(30),
|
|
|
|
-- Licencia
|
|
tipo_licencia fleet.tipo_licencia,
|
|
numero_licencia VARCHAR(30),
|
|
licencia_vigencia DATE,
|
|
|
|
-- Estado
|
|
activo BOOLEAN DEFAULT TRUE,
|
|
|
|
-- Auditoría
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_operador_carrier ON carriers.operadores_carrier(carrier_id);
|
|
|
|
-- =============================================================================
|
|
-- TABLA: asignaciones_carrier (Viajes asignados a carriers)
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE carriers.asignaciones_carrier (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES public.tenants(id),
|
|
|
|
-- Carrier
|
|
carrier_id UUID NOT NULL REFERENCES carriers.carriers(id),
|
|
unidad_carrier_id UUID REFERENCES carriers.unidades_carrier(id),
|
|
operador_carrier_id UUID REFERENCES carriers.operadores_carrier(id),
|
|
|
|
-- Viaje/OT
|
|
viaje_id UUID,
|
|
ot_id UUID,
|
|
|
|
-- Tarifa acordada
|
|
tarifa_acordada DECIMAL(15, 2) NOT NULL,
|
|
moneda VARCHAR(3) DEFAULT 'MXN',
|
|
|
|
-- Fechas
|
|
fecha_asignacion TIMESTAMPTZ DEFAULT NOW(),
|
|
fecha_confirmacion TIMESTAMPTZ,
|
|
|
|
-- Estado
|
|
estado VARCHAR(20) DEFAULT 'PENDIENTE',
|
|
-- PENDIENTE, CONFIRMADA, EN_PROCESO, COMPLETADA, CANCELADA
|
|
|
|
-- Facturación
|
|
factura_carrier VARCHAR(50),
|
|
fecha_factura DATE,
|
|
monto_facturado DECIMAL(15, 2),
|
|
fecha_pago DATE,
|
|
|
|
-- Evaluación del viaje
|
|
calificacion INT, -- 1-5
|
|
comentarios TEXT,
|
|
|
|
-- Auditoría
|
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
created_by_id UUID NOT NULL
|
|
);
|
|
|
|
CREATE INDEX idx_asignacion_carrier ON carriers.asignaciones_carrier(carrier_id);
|
|
CREATE INDEX idx_asignacion_viaje ON carriers.asignaciones_carrier(viaje_id);
|
|
CREATE INDEX idx_asignacion_estado ON carriers.asignaciones_carrier(tenant_id, estado);
|
|
|
|
-- =============================================================================
|
|
-- TABLA: scorecard_carrier
|
|
-- =============================================================================
|
|
|
|
CREATE TABLE carriers.scorecard (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL REFERENCES public.tenants(id),
|
|
carrier_id UUID NOT NULL REFERENCES carriers.carriers(id),
|
|
|
|
-- Período
|
|
periodo_inicio DATE NOT NULL,
|
|
periodo_fin DATE NOT NULL,
|
|
|
|
-- Métricas de servicio
|
|
total_viajes INT DEFAULT 0,
|
|
viajes_a_tiempo INT DEFAULT 0,
|
|
viajes_retrasados INT DEFAULT 0,
|
|
viajes_cancelados INT DEFAULT 0,
|
|
|
|
-- Porcentajes
|
|
otif_porcentaje DECIMAL(5, 2), -- On Time In Full
|
|
puntualidad_porcentaje DECIMAL(5, 2),
|
|
|
|
-- Incidentes
|
|
total_incidentes INT DEFAULT 0,
|
|
incidentes_graves INT DEFAULT 0,
|
|
|
|
-- Calificación
|
|
calificacion_servicio DECIMAL(3, 2),
|
|
calificacion_documentacion DECIMAL(3, 2),
|
|
calificacion_comunicacion DECIMAL(3, 2),
|
|
calificacion_general DECIMAL(3, 2),
|
|
|
|
-- Financiero
|
|
monto_total_servicios DECIMAL(15, 2),
|
|
monto_penalizaciones DECIMAL(15, 2),
|
|
|
|
-- Auditoría
|
|
calculado_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX idx_scorecard_carrier ON carriers.scorecard(carrier_id);
|
|
CREATE INDEX idx_scorecard_periodo ON carriers.scorecard(periodo_inicio, periodo_fin);
|
|
|
|
-- =============================================================================
|
|
-- RLS POLICIES
|
|
-- =============================================================================
|
|
|
|
ALTER TABLE carriers.carriers ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE carriers.documentos_carrier ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE carriers.unidades_carrier ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE carriers.operadores_carrier ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE carriers.asignaciones_carrier ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE carriers.scorecard ENABLE ROW LEVEL SECURITY;
|
|
|
|
CREATE POLICY tenant_isolation_carriers ON carriers.carriers
|
|
USING (tenant_id = current_setting('app.tenant_id')::uuid);
|
|
|
|
CREATE POLICY tenant_isolation_docs ON carriers.documentos_carrier
|
|
USING (tenant_id = current_setting('app.tenant_id')::uuid);
|
|
|
|
CREATE POLICY tenant_isolation_unidades ON carriers.unidades_carrier
|
|
USING (tenant_id = current_setting('app.tenant_id')::uuid);
|
|
|
|
CREATE POLICY tenant_isolation_operadores ON carriers.operadores_carrier
|
|
USING (tenant_id = current_setting('app.tenant_id')::uuid);
|
|
|
|
CREATE POLICY tenant_isolation_asignaciones ON carriers.asignaciones_carrier
|
|
USING (tenant_id = current_setting('app.tenant_id')::uuid);
|
|
|
|
CREATE POLICY tenant_isolation_scorecard ON carriers.scorecard
|
|
USING (tenant_id = current_setting('app.tenant_id')::uuid);
|
|
|
|
-- =============================================================================
|
|
-- COMENTARIOS
|
|
-- =============================================================================
|
|
|
|
COMMENT ON TABLE carriers.carriers IS 'Transportistas subcontratados';
|
|
COMMENT ON TABLE carriers.documentos_carrier IS 'Documentos de carriers';
|
|
COMMENT ON TABLE carriers.unidades_carrier IS 'Unidades de carriers';
|
|
COMMENT ON TABLE carriers.operadores_carrier IS 'Operadores de carriers';
|
|
COMMENT ON TABLE carriers.asignaciones_carrier IS 'Asignaciones de viajes a carriers';
|
|
COMMENT ON TABLE carriers.scorecard IS 'Evaluación periódica de carriers';
|
|
|
|
-- =============================================================================
|
|
-- FIN DDL CARRIERS
|
|
-- =============================================================================
|