Sincronización de Guías (Dispatch)
Importante: A diferencia de los demás endpoints de sync,
/transportes/sync/dispatchtrabaja con IDs internos de Smartfleet (driver_id,vehicle_id,hub_id,receipt_id). Esto significa que chofer, vehículo, sede y facturas deben estar ya sincronizados antes de crear la guía.
Crea o actualiza una guía de despacho con chofer, vehículo y paradas.
Caso de uso
- Crear guía desde un sistema externo cuando ya se eligieron chofer, vehículo y stops.
- Actualizar una guía existente pasando
dispatch_id. - Crear guías normales o de solo recolección.
Campos del Payload
Requeridos
| Campo | Tipo | Descripción |
|---|---|---|
driver_id | int | ID del chofer |
vehicle_id | int | ID del vehículo |
total_weight | number | Peso total del despacho |
dispatch_steps | object | Mapa de paradas de la guía |
Opcionales
| Campo | Tipo | Descripción |
|---|---|---|
dispatch_id | int | Para actualizar una guía existente |
hub_id | int | Sede de salida |
user | string | Usuario que crea la guía |
uber / is_uber | boolean | Indica si es despacho por Uber |
default_pickup_notes | string | Notas de recolección por defecto |
extra_pickup_notes | string | Notas adicionales de recolección |
dropoff_notes / return_detail | string | Notas de entrega o devolución |
removed_receipts_ids / removed_receipt_ids | int[] | Facturas a remover de la guía |
removed_returns_ids / removed_return_ids | int[] | Devoluciones a remover |
removed_transfers_ids / removed_transfer_ids | int[] | Traslados a remover |
dispatch_mode | string | NORMAL_DELIVERY (default) o PICKUP_ONLY |
validate_hub_pickups_on_create / validate_pickups_on_create | boolean | Valida pickups al crear |
source_id | string | ID externo de la guía (máx. 128 chars). Permite luego lookups por GET /sync/dispatch/{sourceId} e identificación vía dispatch_source_id en /sync/dispatch/start |
source_system | string | Sistema externo (ej. external_erp). Requerido junto con source_id |
Tipos permitidos en dispatch_steps
Cada stop tiene order (entero), type y item. Los campos requeridos en item según tipo:
| Tipo | Campos requeridos en item | Descripción |
|---|---|---|
hub | hub_id, name, latitude, longitude | Parada en sede |
receipt | receipt_id, receipt_code, hub_id, latitude, longitude | Parada de entrega de factura |
pickup | pickup_type, document_id, receipt_id | Parada de recolección |
return | return_id, receipt_id | Parada de devolución |
transfer | pickup_type: "TRANSFER", document_id, receipt_id | Parada de traslado |
Todos los IDs en
item(receipt_id,hub_id,return_id, etc.) son IDs internos de Smartfleet, nosource_id.
Notas Importantes
- Para
PICKUP_ONLY, el stop final de entrega de recolecciones usaENT_RECcuando corresponde. - Si se intenta crear otra guía
PICKUP_ONLYcon pickups ya procesados, el backend bloquea la operación. - Si se crea una guía normal posterior, los pickups ya procesados no se vuelven a crear como stops de recolección.
ENT_REC vs ENT_FAC: cómo derivar el stop de factura
type en dispatch_steps solo acepta los 5 valores listados arriba — no existe ent_rec. Cuando una guía es solo recolección y la mercadería se deposita en una sede en lugar de entregarse al cliente, el integrador envía el step de la factura con type: "receipt" y deliver_to_hub: true en item. El backend convierte ese step en un stop ENT_REC durante buildStopsToCreate con esta regla:
deliverToHub = item.deliver_to_hub === true
|| item.latitude == null
|| item.longitude == null
stop_type_id = deliverToHub ? ENT_REC : ENT_FAC| Caso | type | item.deliver_to_hub | item.latitude/longitude | Stop generado |
|---|---|---|---|---|
| Entrega normal al cliente | receipt | omitir | coords del cliente | ENT_FAC |
| Depósito en sede tras recolección | receipt | true | coords del hub destino (recomendado) | ENT_REC |
| Depósito en sede sin coords | receipt | omitir | omitir ambos | ENT_REC (fallback) |
Cuando el chofer ejecuta el stop:
POST /transportes/sync/dispatch/task/startcontask_type: "ENT_REC",document_id=receipt_id.POST /transportes/sync/dispatch/task/completecontask_type: "ENT_REC". Las cantidades reportadas enlines[*]se acumulan enreturned_quantity(vuelven al hub) en lugar dedelivered_quantity.
Efecto al cerrar el stop ENT_REC:
receipts.status_idqueda enSIN_ASIGNAR (1)— la entrega al cliente queda pendiente.- Se setean
pickup_stored_hub_id(=item.hub_idenviado en el step) ypickup_stored_at. - En una guía posterior se podrá crear un step
receiptENT_FAC normal para entregar al cliente final.
Ejemplos
Request — Guía Normal
{
"hub_id": 3,
"driver_id": 1,
"vehicle_id": 12,
"total_weight": 25.5,
"user": "erp-sync",
"dispatch_mode": "NORMAL_DELIVERY",
"dispatch_steps": {
"1": {
"order": 1,
"type": "hub",
"item": {
"hub_id": 3,
"name": "Cedi",
"latitude": 9.9797944160071,
"longitude": -84.1408946228684
}
},
"2": {
"order": 2,
"type": "receipt",
"item": {
"receipt_id": 2108,
"receipt_type_id": 1,
"receipt_code": "FAC-10001",
"receipt_type_code": "FAC",
"hub_id": 3,
"latitude": 9.93,
"longitude": -84.14
}
}
}
}Request — Solo Recolección (Pickup Only)
{
"hub_id": 3,
"driver_id": 1,
"vehicle_id": 12,
"total_weight": 10,
"user": "erp-sync",
"dispatch_mode": "PICKUP_ONLY",
"dispatch_steps": {
"1": {
"order": 1,
"type": "hub",
"item": {
"hub_id": 2,
"name": "Alajuela",
"latitude": 10.01064731315831,
"longitude": -84.21583404686814
}
},
"2": {
"order": 2,
"type": "pickup",
"item": {
"pickup_type": "OC",
"document_id": 371,
"receipt_code": "FAC-10001",
"receipt_id": 2108,
"origin_description": "Acme Manufacturing",
"latitude": 9.93276239628712,
"longitude": -84.08577070478509
}
},
"3": {
"order": 3,
"type": "hub",
"item": {
"hub_id": 3,
"name": "Cedi",
"latitude": 9.9797944160071,
"longitude": -84.1408946228684
}
}
}
}Response
{
"ok": true,
"code": "SYNC_OK",
"message": "Sync processed successfully.",
"data": {
"statusOk": true,
"message": "Dispatch created successfully.",
"dispatch_id": 501
},
"meta": {
"route": "/transportes/sync/dispatch",
"method": "PostDispatchSync",
"operation": "upsert",
"upsert_action": "created",
"timestamp": "2026-04-07T12:00:00.000Z"
}
}Cancelación de guías desde sistema externo
El mismo endpoint POST /transportes/sync/dispatch maneja el flujo de solicitud y aprobación de cancelación usando el campo sync_operation.
Paso 1 — Solicitar cancelación
{
"dispatch_id": 501,
"sync_operation": "CANCELLATION_REQUEST",
"reason": "El cliente canceló el pedido",
"detail": "Detalle opcional adicional",
"user": "erp-sync"
}Response:
{
"ok": true,
"code": "SYNC_OK",
"meta": {
"upsert_action": "cancellation_requested",
"sync_operation": "CANCELLATION_REQUEST"
}
}Paso 2 — Reenviar solicitud (si está pendiente)
{
"dispatch_id": 501,
"sync_operation": "CANCELLATION_RESEND"
}Paso 3 — Aprobar o rechazar la cancelación
{
"dispatch_id": 501,
"sync_operation": "CANCELLATION_DECISION",
"action": "APPROVED",
"comment": "Confirmado por supervisor"
}{
"dispatch_id": 501,
"sync_operation": "CANCELLATION_DECISION",
"action": "REJECTED",
"comment": "No procede la cancelación"
}Aliases de sync_operation
El campo acepta múltiples variantes para facilitar la integración:
| Alias | Operación |
|---|---|
CANCELLATION_REQUEST, CANCEL_REQUEST, REQUEST_CANCELLATION, REQUESTED, CREATE | Solicitar cancelación |
CANCELLATION_RESEND, CANCEL_RESEND, RESEND | Reenviar solicitud |
CANCELLATION_DECISION, CANCEL_DECISION, DECISION, APPROVED, REJECTED | Aprobar / rechazar |
Nota: La cancelación de guía es distinta de la cancelación de un stop (
task/cancel). La cancelación de stop revierte el dispatch aASIGNADApara reprogramarlo; la cancelación de guía la lleva aANULADAtras aprobación.
Ubicación del chofer en lote
Un sistema de telemetría externo puede empujar los puntos GPS que recolectó mientras el chofer estaba en ruta. Es la ruta que usa un adapter de flota cuando la app del chofer no es la fuente de la ubicación.
POST /transportes/sync/dispatch/location/batch
Authorization: Bearer YOUR_SYNC_TOKEN_HERE
Content-Type: application/json{
"driver_id": "1",
"locations": [
{
"lat": 9.93,
"lng": -84.08,
"speed": 42.5,
"heading": 180,
"gps_precision": 8,
"route_id": "R-2026-08-19-01",
"status": "EN_RUTA",
"recorded_at": "2026-08-19T16:00:00.000Z"
}
]
}| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
driver_id | string | number | sí | Chofer en Smartfleet. |
locations | array | sí | Entre 1 y 1000 puntos por request. Más de 1000 → 400. |
locations[].lat | number -90..90 | sí | Latitud. |
locations[].lng | number -180..180 | sí | Longitud. |
locations[].recorded_at | string ISO 8601 | sí | Instante de la lectura. |
locations[].speed | number | no | Velocidad reportada. |
locations[].heading | number | no | Rumbo. |
locations[].gps_precision | number | no | Precisión del GPS, en metros. |
locations[].route_id | string | no | Identificador de la ruta en el sistema de origen. |
locations[].status | string | no | Estado reportado por el origen. |
Los puntos se ordenan por recorded_at antes de guardarse, así que un lote que
llega desordenado no deja el rastro invertido.