Catálogos Maestros
Choferes y Licencias

Sincronización de Choferes y Licencias

En esta sección se documentan los endpoints para sincronizar el catálogo de choferes y los tipos de licencia que poseen o requieren.


1. Tipos de Licencia

POST/transportes/sync/drivers/licenses/types

Crea o actualiza tipos de licencia requeridos para choferes y vehículos.

Caso de uso

  • Crear catálogo de licencias requeridas para choferes y vehículos.

Campos del Payload

Requeridos

CampoTipoDescripción
source_idstringID único en el sistema de origen
source_systemstringSistema externo (ej. external_erp)
license_type_codestringCódigo del tipo de licencia (ej. B2)
license_type_descriptionstringDescripción del tipo de licencia

Opcionales

CampoTipoDescripción
is_activebooleanEstado activo
license_type_idintID interno del tipo

Ejemplos

Request

{
  "source_id": "fleet.license.type:B2",
  "source_system": "external_erp",
  "license_type_code": "B2",
  "license_type_description": "Licencia B2"
}

Response

{
  "ok": true,
  "code": "SYNC_OK",
  "message": "Sync processed successfully.",
  "data": 2,
  "meta": {
    "route": "/transportes/sync/drivers/licenses/types",
    "method": "PostLicenseTypeSync",
    "operation": "upsert",
    "upsert_action": "created",
    "timestamp": "2026-04-07T12:00:00.000Z"
  }
}

2. Choferes

POST/transportes/sync/drivers

Crea o actualiza choferes y los asocia a sede y vehículo.

Caso de uso

  • Crear/actualizar choferes desde RRHH u el sistema externo.
  • Asociar chofer a sede y vehículo por source_id.

Dependencias

  • hub_source_id requiere que la sede exista.
  • vehicle_source_id requiere que el vehículo exista.

Campos del Payload

Requeridos

CampoTipoDescripción
source_idstringID único en el sistema de origen
source_systemstringSistema externo
employee_codestringCódigo del empleado
national_idstringCédula o identificación nacional

Opcionales

CampoTipoDescripción
is_activebooleanEstado activo
driver_idintID interno del chofer
driver_namestringNombre completo
hub_id / hub_source_idint/stringSede asignada
hub_modelstringModelo del hub
vehicle_id / vehicle_source_idint/stringVehículo asignado
vehicle_modelstringModelo del vehículo
driver_status_idintEstado del chofer
phonestringTeléfono
licensesarrayLicencias del chofer (ver estructura abajo)
is_externalbooleanEs chofer externo
is_enabledbooleanEstá habilitado para operar

Campos opcionales al actualizar (desde 2026-10-27): un campo opcional que no viene en el payload no se toca al actualizar un chofer existente: la sede, el vehículo, el estado, el nombre, el teléfono, is_external, is_enabled y las licencias quedan como estaban en SmartFleet. Para limpiar un campo, mandalo en null explícito. En el alta, lo que no viene toma los valores por defecto (estado Disponible, habilitado, sin sede ni vehículo). Con is_active: false el chofer queda sin vehículo y deshabilitado. El chofer existente se busca también por el código de empleado con y sin ceros a la izquierda ("0123" encuentra al "123").

Estructura de cada objeto en licenses:

CampoTipoDescripción
license_type_codestringCódigo de tipo de licencia (ej. "B1")
license_expiration_datestring (ISO 8601)Fecha de vencimiento (ej. "2027-12-31T00:00:00.000Z")

Ejemplos

Request

{
  "source_id": "hr.employee:401",
  "source_system": "external_erp",
  "employee_code": "EMP-401",
  "national_id": "1-1111-1111",
  "driver_name": "Juan Pérez",
  "phone": "555-0400",
  "hub_source_id": "stock.warehouse:1",
  "hub_model": "stock.warehouse",
  "vehicle_source_id": "fleet.vehicle:12",
  "vehicle_model": "fleet.vehicle",
  "is_enabled": true,
  "is_external": false,
  "licenses": [
    {
      "license_type_code": "B1",
      "license_expiration_date": "2027-12-31T00:00:00.000Z"
    }
  ]
}

Response

{
  "ok": true,
  "code": "SYNC_OK",
  "message": "Sync processed successfully.",
  "data": [
    {
      "driver_id": 25
    }
  ],
  "meta": {
    "route": "/transportes/sync/drivers",
    "method": "PostDriverSync",
    "operation": "upsert",
    "upsert_action": "updated",
    "timestamp": "2026-04-07T12:00:00.000Z"
  }
}

3. Ausencias de choferes

POST/transportes/sync/driver-absences

Crea, actualiza o anula una ausencia (incapacidad, vacaciones, permiso…) de un chofer.

Caso de uso

  • Avisar a SmartFleet que un chofer está ausente en un rango de fechas. Mientras la ausencia está vigente (de date_from a date_to, los dos días incluidos, en la fecha local de la empresa), el chofer no puede recibir guías: la asignación responde 409 DRIVER_ABSENT.
  • La ausencia no desasigna guías que el chofer ya tiene: si las tiene, meta.assigned_dispatch_ids las lista.
  • Una ausencia sincronizada que cubre entera una ausencia cargada a mano en SmartFleet la reemplaza (meta.superseded_absence_ids). Si sólo se superponen en parte, las dos quedan.

Campos del Payload

CampoTipoRequeridoDescripción
source_systemstring (1–30)síSistema externo (se guarda en minúsculas)
source_idstring (1–128)síID único de la ausencia en el sistema de origen. Clave de idempotencia
statusactive · cancelledsícancelled anula la ausencia; una anulada que vuelve active se reactiva
driver_source_idstring (1–128)uno de los dossource_id del chofer en el sistema de origen
employee_codestring (1–20)uno de los dosCódigo de empleado (con o sin ceros a la izquierda)
absence_type_codestring (1–40)con activesick_leave, vacation, leave, parental_leave, suspension u other
date_from, date_toYYYY-MM-DDcon activedate_to >= date_from, 366 días como máximo
source_type_codestring (1–60)noCódigo o nombre del tipo en el origen, sólo para auditoría

No mandes diagnósticos ni datos médicos: SmartFleet guarda sólo la categoría de la ausencia.

Respuesta

meta.upsert_action es uno de:

ValorSignifica
createdAusencia nueva
updatedYa existía (mismo source_system + source_id); reenviar el mismo payload da updated sin cambios
cancelledSe anuló
noop_unknown_driverEl chofer no existe en SmartFleet: no se guarda nada y no hay que reintentar
noop_cancel_unknownSe pidió anular una ausencia que SmartFleet no conoce
{
  "ok": true,
  "code": "SYNC_OK",
  "message": "Sync processed successfully.",
  "data": [{ "absence_id": 70 }],
  "meta": {
    "route": "/transportes/sync/driver-absences",
    "method": "PostDriverAbsenceSync",
    "operation": "upsert",
    "upsert_action": "created",
    "superseded_absence_ids": [],
    "assigned_dispatch_ids": [4501],
    "timestamp": "2026-10-27T12:00:00.000Z"
  }
}

Errores: 400 ABSENCE_TYPE_UNKNOWN (tipo inexistente o inactivo) y 400 SYNC_VALIDATION_ERROR (payload inválido; el mensaje no repite el valor recibido).

4. Roster de choferes

POST/transportes/sync/drivers/roster

Manda el estado de todos los empleados para dar de baja choferes que ya no trabajan, con red de seguridad.

Caso de uso

  • El sistema de RRHH manda, periódicamente, todos sus empleados (entre 1 y 20 000) con su estado: active_driver, inactive o not_driver, y marca roster_complete: true cuando la lista es completa. Sin esa marca (o en false), la corrida nunca da de baja a nadie.

  • SmartFleet calcula los candidatos a baja: choferes activos, no externos, cuyo código figura como inactive o not_driver y que no tienen guías asignadas ni en tránsito. Los códigos que no cruzan con ningún empleado del roster no se tocan.

  • Si dos choferes (o dos empleados del roster) quedan con el mismo código después de normalizarlo ("123" y "0123"), ninguno de los dos se toca: se cuentan en excluded.duplicate_code.

  • Qué se hace con los candidatos lo decide la configuración de la empresa: off (nada), dry_run (sólo se registra la lista; es el valor por defecto) o apply (se dan de baja). En apply, la baja ocurre sólo si se cumplen las tres condiciones:

    1. roster_complete es true;
    2. el roster incluye al menos el 80 % de los choferes activos y no externos de ese source_system;
    3. los candidatos de esta corrida, sumados a los dados de baja en las últimas 24 horas, no pasan de 10.

    Si falla 1 o 2, la corrida queda como dry_run con reason: "roster_incomplete"; si falla 3, como dry_run con reason: "threshold_exceeded". En los dos casos no se da de baja a nadie.

Respuesta

{
  "ok": true,
  "code": "SYNC_OK",
  "message": "Sync processed successfully.",
  "data": [{ "reconciliation_id": 12 }],
  "meta": {
    "route": "/transportes/sync/drivers/roster",
    "method": "PostDriversRosterSync",
    "mode": "dry_run",
    "candidates_count": 3,
    "deactivated_count": 0,
    "reason": null,
    "timestamp": "2026-10-27T12:00:00.000Z"
  }
}

Con la empresa en off la respuesta trae meta.mode: "off" y data: [].