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>
4.9 KiB
US-MAI003-007: Cancelar OT
Metadata
| Campo | Valor |
|---|---|
| ID | US-MAI003-007 |
| Epica | EPIC-MAI-003 - Ordenes de Transporte |
| Modulo | ordenes-transporte |
| Prioridad | P1 |
| Story Points | 3 |
| Sprint | Por asignar |
| Estado | Backlog |
Historia de Usuario
Como despachador o coordinador de una empresa transportista, quiero cancelar una orden de transporte que ya no sera ejecutada, para liberar los recursos asociados y mantener actualizado el estado de las operaciones con un registro claro del motivo de cancelacion.
Descripcion Detallada
La cancelacion de una OT es una operacion necesaria cuando el cliente retira la solicitud, se duplica una orden, o se presentan circunstancias que impiden la ejecucion del servicio. El sistema debe permitir cancelar OTs en estados previos a la ejecucion (BORRADOR, CONFIRMADA y ASIGNADA), pero no una vez que el viaje esta en proceso o completado.
Al cancelar, el sistema debe registrar el motivo de cancelacion y marcar la OT con estado CANCELADA y deleted_at como fecha de cancelacion logica. Si la OT estaba agrupada en un embarque, debe removerse automaticamente y recalcular los totales del embarque. Si estaba asignada a un viaje, se debe evaluar si el viaje puede continuar sin esa OT.
La cancelacion es una operacion irreversible: una OT cancelada no puede volver a un estado activo. Si se necesita reactivar, se debe crear una nueva OT.
Criterios de Aceptacion
Escenario 1: Cancelar OT en estado BORRADOR
Dado que existe una OT en estado BORRADOR, Cuando el despachador solicita la cancelacion con motivo "Solicitud retirada por el cliente", Entonces el sistema cambia el estado a CANCELADA, registra deleted_at con la fecha actual, registra updated_by_id con el usuario que cancela, y la OT deja de aparecer en listados activos.
Escenario 2: Cancelar OT CONFIRMADA que pertenece a un embarque
Dado que una OT en estado CONFIRMADA esta agrupada en un embarque con 3 OTs, Cuando el coordinador cancela la OT con motivo "Carga no disponible en origen", Entonces el sistema cambia la OT a CANCELADA, la remueve del embarque (limpia embarque_id), recalcula los totales del embarque (total_ots = 2, peso y volumen actualizados).
Escenario 3: Rechazo de cancelacion en estado EN_PROCESO
Dado que una OT se encuentra en estado EN_PROCESO (viaje en curso), Cuando el usuario intenta cancelar la OT, Entonces el sistema rechaza la operacion con error 422 y mensaje "No se puede cancelar una orden de transporte en estado EN_PROCESO. Registre una incidencia en su lugar."
Escenario 4: Motivo de cancelacion obligatorio
Dado que el usuario solicita cancelar una OT en estado valido, Cuando no proporciona un motivo de cancelacion, Entonces el sistema rechaza la operacion indicando que el motivo de cancelacion es obligatorio.
Tareas Tecnicas
- Database: Utilizar campo
estadopara marcar como CANCELADA ydeleted_atpara soft delete. El campodeleted_at(TIMESTAMPTZ) sirve como fecha de cancelacion logica. - Backend: Agregar metodo
cancelar(id, motivo, userId)enOrdenTransporteServicecon validacion de estado: solo permitir cancelacion desde BORRADOR, CONFIRMADA o ASIGNADA. Si la OT tiene embarque_id, invocarEmbarqueService.removeOt()para limpiar la referencia y recalcular totales. Configurar endpoint PATCH/api/v1/ordenes-transporte/:id/cancelar. CrearCancelarOrdenTransporteDtocon campo obligatoriomotivo. - Frontend: Agregar boton "Cancelar OT" visible solo en estados BORRADOR, CONFIRMADA y ASIGNADA. Al presionar, mostrar dialogo de confirmacion con campo obligatorio de motivo. Tras cancelacion exitosa, redirigir al listado con mensaje de confirmacion.
- Tests: Tests unitarios de validacion de estados permitidos para cancelacion. Tests de integracion del flujo con embarque (remocion y recalculo). Tests de motivo obligatorio. Tests de rechazo en estados no cancelables.
Dependencias
- Depende de: US-MAI003-001 (la OT debe existir), US-MAI003-004 (logica de remocion de embarque)
- Bloquea: Ninguno directamente (flujo terminal)
Notas Tecnicas
- Endpoint: PATCH
/api/v1/ordenes-transporte/:id/cancelar - Body:
{ "motivo": "string (requerido)" } - Estados cancelables: BORRADOR, CONFIRMADA, ASIGNADA
- Estados no cancelables: EN_PROCESO, COMPLETADA, FACTURADA, CANCELADA
- Soft delete:
deleted_at = NOW()marca la cancelacion logica. Los listados por defecto filtranWHERE deleted_at IS NULL - Efecto cascada: Si la OT pertenece a un embarque, el servicio debe: 1) limpiar embarque_id de la OT, 2) recalcular totales del embarque, 3) si el embarque queda sin OTs, evaluar si se cierra automaticamente
- Irreversibilidad: No existe endpoint para reactivar una OT cancelada. El motivo de cancelacion se almacena en la columna instrucciones_especiales o en una tabla de auditoria dedicada
US-MAI003-007 - ERP Transportistas v1.0.0