Skip to main content

Overview

The Solicitud Transporte system manages two parallel workflows: Transport Requests (Solicitud) and Missions (Mision). Each has its own state machine with specific transition rules and business logic.
All state transitions are tracked in historical tables for audit purposes and can be retrieved via dedicated endpoints.

Request Lifecycle

A transport request flows through several states from creation to completion.

State Diagram

Request States

The EstadoSolicitud table defines all possible states with specific attributes (DevSolicitudTransporte:35):
Description: Initial state when a request is createdCharacteristics:
  • EsEstadoFinal: false
  • Orden: 1
  • Default color: Orange/Yellow
Allowed Operations:
  • Update request details (solicitud_service.py:609)
  • Approve request (solicitud_service.py:703)
  • Reject request (solicitud_service.py:752)
  • Cancel request (solicitud_service.py:805)
  • Delete request (solicitud_service.py:932)
Business Rules:
  • Only the requester can update or cancel
  • Only the approver can approve or reject
  • Requester and approver must be different people (solicitud_service.py:314)
Description: Request has been approved and awaits mission assignmentCharacteristics:
  • EsEstadoFinal: false
  • Orden: 2
  • Default color: Green
Allowed Operations:
  • Create missions for this request
  • Cancel request (solicitud_service.py:805)
Automatic Transitions:
  • EN_PROCESO when first mission is assigned
  • CANCELADA via cancel operation
Notifications:
  • Email sent to requester confirming approval
Description: Request was rejected by approverCharacteristics:
  • EsEstadoFinal: true
  • Orden: 3
  • Default color: Red
Business Rules:
  • Rejection reason is mandatory (solicitud_service.py:761)
  • No further operations allowed
  • Historical record preserved (solicitud_service.py:108)
Notifications:
  • Email sent to requester with rejection reason
Description: One or more missions are activeCharacteristics:
  • EsEstadoFinal: false
  • Orden: 4
  • Default color: Blue
Allowed Operations:
  • View mission status
  • Cancel request (only if no missions are currently executing)
Automatic Transitions:
  • COMPLETADA when all missions reach final state
Description: All missions completed successfullyCharacteristics:
  • EsEstadoFinal: true
  • Orden: 5
  • Default color: Dark Green
Business Rules:
  • No modifications allowed
  • All associated missions must be in final state
  • Historical data retained indefinitely
Description: Request was cancelledCharacteristics:
  • EsEstadoFinal: true
  • Orden: 6
  • Default color: Gray
Business Rules:
  • Cancellation reason is mandatory (solicitud_service.py:816)
  • Cannot cancel if missions are currently executing (solicitud_service.py:833)
  • Non-executing missions are soft-deleted (solicitud_service.py:853)
Notifications:
  • Email sent to both requester and approver

State Transition Rules

# From: PENDIENTE_APROBACION → APROBADA
def aprobar(self, id_solicitud: int, motivo: Optional[str] = None) -> Dict:
    # 1. Validate request exists
    # 2. Check current state is PENDIENTE_APROBACION
    # 3. Register state change in HistoricoEstadoSolicitud
    # 4. Update IdEstadoSolicitud in Solicitud table
    # 5. Send approval email to requester
    pass

State History Tracking

Every state change is recorded in HistoricoEstadoSolicitud (DevSolicitudTransporte:408):
CREATE TABLE HistoricoEstadoSolicitud (
    IdEstadoSolicitud INT NOT NULL,
    IdSolicitud INT NOT NULL,
    FechaHoraCreacion DATETIME2 NOT NULL,
    MotivoEstadoSolicitud NVARCHAR(MAX),
    Eliminado BIT NOT NULL,
    PRIMARY KEY (IdSolicitud, FechaHoraCreacion, IdEstadoSolicitud)
)
Historical records are retrieved in chronological order via obtener_historico() endpoint (solicitud_service.py:896)

Mission Lifecycle

Missions represent the actual execution of approved transportation requests.

Mission State Diagram

Mission States

The EstadoMision table defines mission states (DevSolicitudTransporte:18):
Scheduled MissionDescription: Mission has been created and assigned to a driver and vehicleKey Fields Set:
  • IdVehiculoAsignado - Assigned vehicle
  • IdMotoristaAsignado - Assigned driver
  • FechaProgramada - Scheduled date
  • HoraSalidaProgramada - Scheduled departure time
  • IdLugarOrigen / IdLugarDestino - Route information
Transitions:
  • EN_EJECUCION when driver starts trip
  • CANCELADA if mission is cancelled

Mission Data Collection

Missions collect extensive operational data (Mision table, DevSolicitudTransporte:523):

Distance Tracking

  • Initial odometer reading
  • Final odometer reading
  • Calculated distance traveled

Fuel Management

  • Initial fuel level (gallons)
  • Final fuel level (gallons)
  • Total consumption calculation

Time Tracking

  • Scheduled vs. actual departure
  • Estimated vs. actual arrival
  • Total trip duration

Route Information

  • Origin location details
  • Destination location details
  • GPS coordinates tracked

Workflow Integration

Request-Mission Relationship

A single transport request can have multiple missions: Business Rules:
1

Mission Creation

Missions can only be created for requests in APROBADA or EN_PROCESO state
2

Automatic State Updates

Request automatically transitions to EN_PROCESO when first mission is assigned
3

Completion Logic

Request transitions to COMPLETADA only when ALL missions are in final state
4

Cancellation Constraints

Cannot cancel request if any mission is in EN_EJECUCION state (solicitud_service.py:833)

Location Management

Requests can define multiple locations via DetalleLugarSolicitud table:
  • Exactly ONE location must be marked as origin (EsOrigen = true)
  • Origin cannot require return trip
  • If no origin specified, default location (Id=1) is used

State Queries

Retrieve current and historical state information:
def _obtener_estado_actual(self, id_solicitud: int) -> Optional[Dict]:
    """Get latest state from HistoricoEstadoSolicitud"""
    query = """
        SELECT TOP 1 h.IdEstadoSolicitud, e.Codigo, 
               e.Nombre, e.EsEstadoFinal
        FROM HistoricoEstadoSolicitud h
        JOIN EstadoSolicitud e ON h.IdEstadoSolicitud = e.Id
        WHERE h.IdSolicitud = %s AND h.Eliminado = 0
        ORDER BY h.FechaHoraCreacion DESC
    """
    return self.db.select(query, (id_solicitud,))[0]

Notifications

State transitions trigger email notifications:
Recipients: Requester, ApproverContent:
  • Request code and details
  • Link to approval interface (for approver)
  • Confirmation of submission (for requester)
Triggered: On successful request creation (solicitud_service.py:394)
Recipients: RequesterContent:
  • Approval confirmation
  • Optional approval notes
  • Next steps information
Triggered: On approve operation (solicitud_service.py:738)
Recipients: RequesterContent:
  • Rejection notification
  • Rejection reason (mandatory)
  • Instructions for resubmission
Triggered: On reject operation (solicitud_service.py:791)
Recipients: Requester, ApproverContent:
  • Cancellation confirmation
  • Cancellation reason
  • Status of associated missions
Triggered: On cancel operation (solicitud_service.py:882)
Email failures are logged but do not prevent state transitions from completing (solicitud_service.py:403)

Best Practices

Always Check State

Verify current state before allowing operations to prevent invalid transitions

Require Reasons

Always require and store reasons for rejections and cancellations

Track Everything

Maintain complete historical record of all state changes with timestamps

Validate Missions

Check mission states before allowing request state changes

Next Steps

Error Handling

Learn how errors are handled during state transitions

API Reference

Explore endpoints for state management operations

Build docs developers (and LLMs) love