erp-transportistas-v2/docs/02-definicion-modulos/MAI-003-ordenes-transporte/historias-usuario/US-MAI003-004.md
Adrian Flores Cortes ec43d9c6cd docs: Add Phase 3 secondary modules specifications (P1/P2/P3)
Modules documented:
- MAI-003 (OT): README, REQUERIMIENTOS, RESUMEN-EPICA, 10 US
- MAI-006 (Tracking): README, REQUERIMIENTOS, RESUMEN-EPICA
- MAI-008 (Incidencias): 3 US (18 SP)
- MAI-011 (Flota): README, REQUERIMIENTOS, RESUMEN-EPICA
- MAI-012 (Combustible): 3 US (18 SP)
- MAI-013 (Mantenimiento): 3 US (18 SP)
- MAI-014 (Carriers): 3 US (18 SP)
- MAI-015 (Portal): 3 US (18 SP)
- MAE-016 (Carta Porte): 10 US
- MAE-017 (HOS): 3 US (16 SP)
- MAE-018 (Reportes): 3 US (18 SP)

Phase 2+3 complete: 13 modules, 50+ User Stories

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 02:24:35 -06:00

5.4 KiB

US-MAI003-004: Agrupar OTs en embarque

Metadata

Campo Valor
ID US-MAI003-004
Epica EPIC-MAI-003 - Ordenes de Transporte
Modulo ordenes-transporte
Prioridad P0
Story Points 8
Sprint Por asignar
Estado Backlog

Historia de Usuario

Como coordinador de trafico de una empresa transportista, quiero agrupar multiples ordenes de transporte en un embarque de consolidacion, para optimizar la capacidad de las unidades, reducir costos operativos y asignar el grupo completo a un viaje.

Descripcion Detallada

Un embarque (shipment) es una agrupacion logica de OTs que se transportaran juntas. La consolidacion es una practica fundamental en el transporte de carga, especialmente en modalidad LTL (Less Than Truckload), donde se combinan cargas parciales de distintos clientes o destinos para aprovechar al maximo la capacidad de la unidad.

La tabla transport.embarques almacena el codigo unico del embarque, una descripcion, el cliente principal, los totales consolidados (total_ots, peso_total_kg, volumen_total_m3), el estado del embarque y la referencia al viaje asignado. Al agregar OTs a un embarque, el sistema actualiza el campo embarque_id en cada OT y recalcula los totales consolidados del embarque.

El coordinador debe poder crear un embarque, buscar OTs confirmadas compatibles (por zona, ventana de tiempo, tipo de carga) y agregarlas al embarque. Al completar la agrupacion, el embarque puede asignarse a un viaje para su ejecucion.

Criterios de Aceptacion

Escenario 1: Crear embarque nuevo

Dado que el coordinador tiene permisos de creacion de embarques, Cuando ingresa codigo, descripcion y selecciona el cliente principal, Entonces el sistema crea el embarque en estado ABIERTO con total_ots = 0 y genera un registro en transport.embarques con constraint uq_embarque_tenant_codigo.

Escenario 2: Agregar OTs al embarque

Dado que existe un embarque en estado ABIERTO y hay OTs en estado CONFIRMADA del mismo tenant, Cuando el coordinador selecciona 3 OTs y las agrega al embarque, Entonces el sistema actualiza embarque_id en cada OT, recalcula total_ots (3), peso_total_kg (suma de peso_kg de las 3 OTs) y volumen_total_m3 (suma de volumen_m3 de las 3 OTs).

Escenario 3: Remover OT de un embarque

Dado que un embarque tiene 3 OTs agrupadas y ninguna esta en estado EN_PROCESO o posterior, Cuando el coordinador remueve una OT del embarque, Entonces el sistema limpia el campo embarque_id de la OT removida, recalcula los totales del embarque (total_ots = 2, peso y volumen actualizados).

Escenario 4: Asignar embarque a viaje

Dado que un embarque tiene al menos una OT agrupada, Cuando el coordinador asigna el embarque a un viaje existente, Entonces el sistema actualiza viaje_id en el embarque, actualiza viaje_id y embarque_id en cada OT del embarque, y cambia el estado de las OTs de CONFIRMADA a ASIGNADA.

Tareas Tecnicas

  • Database: Verificar tabla transport.embarques con campos: codigo (VARCHAR(50)), descripcion (VARCHAR(500)), cliente_id (UUID), total_ots (INT DEFAULT 0), peso_total_kg (DECIMAL(12,2)), volumen_total_m3 (DECIMAL(12,4)), estado (VARCHAR(20) DEFAULT 'ABIERTO'), viaje_id (UUID). Verificar indices idx_embarque_tenant e idx_embarque_cliente. Verificar constraint uq_embarque_tenant_codigo.
  • Backend: Crear entity Embarque mapeada a transport.embarques. Crear EmbarqueService con metodos: create(), addOts(), removeOt(), assignToViaje(), recalcularTotales(). Crear EmbarqueController con endpoints: POST /api/v1/embarques, GET /api/v1/embarques, GET /api/v1/embarques/:id, POST /api/v1/embarques/:id/ots (agregar OTs), DELETE /api/v1/embarques/:id/ots/:otId (remover OT), PATCH /api/v1/embarques/:id/asignar-viaje. Crear DTOs correspondientes.
  • Frontend: Crear pagina EmbarquesListPage con listado de embarques y conteo de OTs. Crear pagina EmbarqueDetailPage con detalle del embarque y lista de OTs agrupadas. Implementar selector de OTs disponibles (CONFIRMADA, sin embarque) con filtros. Incluir resumen visual de capacidad (peso/volumen utilizados).
  • Tests: Tests unitarios de recalculo de totales. Tests de integracion del flujo completo (crear embarque, agregar OTs, asignar a viaje). Tests de validacion de estados permitidos.

Dependencias

  • Depende de: US-MAI003-001 (las OTs deben existir y estar CONFIRMADAS), MAI-002 (datos de clientes para cliente_id del embarque)
  • Bloquea: MAI-004 (Planeacion - el embarque es la unidad de asignacion a viajes), MAI-005 (Despacho - el despacho opera sobre viajes con embarques)

Notas Tecnicas

  • Endpoints: POST /api/v1/embarques, POST /api/v1/embarques/:id/ots, PATCH /api/v1/embarques/:id/asignar-viaje
  • Entity: Embarque -> transport.embarques
  • RLS: Politica tenant_isolation_embarques filtra por tenant_id
  • Recalculo atomico: El metodo recalcularTotales() debe ejecutarse en una transaccion que actualice las OTs y los totales del embarque de forma atomica
  • Generacion de codigo: Formato sugerido: EMB-{YYYY}-{SECUENCIAL:5}
  • Validaciones de negocio: Solo OTs en estado CONFIRMADA pueden agregarse a un embarque. Una OT solo puede pertenecer a un embarque a la vez (embarque_id es nullable pero unico por OT activa). Al asignar a viaje, todas las OTs del embarque pasan a estado ASIGNADA

US-MAI003-004 - ERP Transportistas v1.0.0