Documentación

Optimroute

Integración para la importación de puntos de entrega y productos

1. Introducción

Este documento especifica las diferentes opciones que ofrece Optimroute para importar puntos de entrega y productos en la aplicación, lo cual es responsabilidad del usuario de la misma. Los siguientes apartados definen el concepto de punto de entrega y producto y los diferentes métodos que ofrece Optimroute para su importación.

2. Punto de entrega

Un punto de entrega, en el contexto de la aplicación Optimroute, se define como una localización con un identificador único en la que hay que realizar la entrega de uno o más pedidos.
Es necesario marcar la distinción entre punto entrega y pedido, ya que Optimroute no hace distinción entre pedidos, sólo recibe puntos de entrega. Esto significa que, en caso que un punto de entrega haya realizado más de un pedido, se deben agregar todos los pedidos en uno solo, el del punto de entrega.
Esto significa también que no puede existir en ninguno de los métodos de integración una importación que contenga dos puntos de entrega con el mismo identificador. Sí que se permite,por lo contrario, que dos puntos de entrega compartan la misma localización geográfica (coordenadas y/o dirección).

3. Producto

Un producto, en el contexto de la aplicación Optimroute, se define como un objeto con un identificador único que se reparte para cada cliente de cada ruta.
Cada cliente tendrá un listado de todos y cada uno de los productos (incluyendo cantidades) que tenga que recibir en el pedido.
Cuando se cargue el fichero con los productos se deberá indicar a qué ruta pertenece esa lista de productos. Esta ruta se indicará en las sección de correspondiente en el panel de control de la aplicación.

4. Punto de entrega - Campos

Todos los formatos de archivo que veremos más delante deberán tener la misma información sobre los puntos de entrega de cada ruta. Los campos son los siguientes:


• deliveryPoints
   • id
   • address
   • coordinates
     • latitude
     • longitude
   • name
   • deliveyZoneId
   • deliveryWindow
   • start
   • end
   • demand
• serviceTime
• requiredSignature
• email
• phone

4.1. Punto de entrega - Especificación de campos

A continuación se especifica para cada uno de los campos descritos en el anterior apartado su definición y sus restricciones. Los campos marcados con el símbolo indicarán la obligatoriedad del mismo. Por el contrario, los campos que no lleven dicho símbolo serán tratados como información opcional. En caso de tener dependencia entre campos, se indicará en cada una de las especificaciones; así como los campos a los que se debe esa dependencia (obligatoriedad).

1. Identificador del punto de entrega [id] (✱):

• Identificador: id
• Descripción: Identifica el punto de entrega. No pueden existir dos puntos de entrega con el mismo identificador en el fichero de importación.
• Restricciones: Cadena de caracteres (string). Valor máximo: 100 caracteres.


• Ejemplos:
  • dp23767
  • 738
  • bcn_32

2. Dirección de entrega [address] (✱ ver campo obligatoriedad):

• Identificador: address
• Descripción: Dirección del punto de entrega. El valor de este campo se usa para obtener las coordenadas de la dirección mediante Google Maps. Debería incluir la dirección (junto al tipo de calle), la ciudad y el código postal (en ese orden).
• Restricciones: Cadena de caracteres (string). Valor máximo: 200 caracteres.
Obligatoriedad: Este campo será obligatorio si se dejan en blanco los campos de coordinates.


• Ejemplos:
  • Calle Pintor Fortuny 21 08840 Viladecans
  • Calle Londres 34 08029 Barcelona

3. Coordenadas: Latitud [coordinates.latitude] (✱ ver campo obligatoriedad):

• Identificador: coordinates.latitude
• Descripción: Coordenada de latitud del punto de entrega. Si esta campo se especifica, también se debe especificar el campo coordinates.longitude. En caso de omitir el campo y dejarlo en blanco, este campo será rellenado con las coordenadas de latitud de la dirección marcada en el campo address.
• Restricciones: Número decimal (number). Valor: Entre -90 y 90 incluidos. El separador decimal será un punto (43.3242).
Obligatoriedad: Este campo será obligatorio si se deja en blanco el campo de address. Este campo será obligatorio si se rellena el campo coordinates.longitude.


• Ejemplos: 
  • 40.321 
  • -88.123213
  • 1.12

4. Coordenadas: Longitud [coordinates.longitude] (✱ ver campo obligatoriedad):

• Identificador: coordinates.longitude
• Descripción: Coordenada de longitud del punto de entrega. Si esta campo se especifica, también se debe especificar el campo coordinates.latitude.
En caso de omitir el campo y dejarlo en blanco, este campo será rellenado con las coordenadas de longitud de la dirección marcada en el campo address.
• Restricciones: Número decimal (float). Valor: Entre -180 y 180 incluidos. El separador decimal será un punto (43.3242).
Obligatoriedad: Este campo será obligatorio si se deja en blanco el campo de address. Este campo será obligatorio si se rellena el campo coordinates.latitude.


• Ejemplos:
  • -45.361
  • -88.123213
  • 156.654

5. Nombre del punto de entrega [name] (✱):

• Identificador: name
• Descripción: Nombre del punto de entrega (cliente) que aparecerá en la aplicación.
No hace falta que sea único, es decir, puede haber dos puntos de entrega con el mismo nombre pero con diferente dirección o localidad.
• Restricciones: Cadena de caracteres (string). Valor máximo: 100 caracteres.


• Ejemplos:
  • Dispoll S.A.
  • BooleanWork
  • Punto de entrega B

6. Identificador de la zona de reparto [deliveryZoneId] (✱):

• Identificador: deliveryZoneId
• Descripción: Zona de reparto a la que pertenece el punto de entrega (cliente). Una zona de reparto agrupa un conjunto de puntos de entrega. Un mismo vehículo no puede realizar entregas en zonas de reparto diferentes, pero sí pueden realizar entregas en una misma zona de reparto diferentes vehículos.
• Restricciones: Cadena de caracteres (string). Valor máximo: 30 caracteres.


• Ejemplos:
  • BCN-1
  • GIR
  • MADRID002

7. Horario de entrega: Inicio [deliveryWindow.start]:

• Identificador: deliveryWindow.start
• Descripción: Especifica la hora del día en la que se puede empezar a realizar el reparto en el punto de entrega. En caso de no existir hora de inicio, se debe especificar con un valor negativo o dejando el campo vacío que indicará que se puede realizar la entrega del producto en el punto de entrega en cualquier momento. El campo se debe indicar en segundos para marcar la hora inicial siendo su valor mínimo 0 (00:00:00) y 86.399 su valor máximo (23:59:59). La tabla de equivalencias (algunos ejemplos) entre segundos y horas es la siguiente:

• Restricciones: Número entero (int). Valor mínimo: 0. Valor máximo: 86.399. El número no debe contener separadores en los millares.


• Ejemplos:
  • 37800
  • 46800
  • -1

8. Horario de entrega: Final [deliveryWindow.end]:

• Identificador: deliveryWindow.end
• Descripción: Especifica la hora del día en la que ya no se puede realizar el reparto en el punto de entrega. En caso de no existir hora de fin de reparto, se debe especificar con un valor negativo o dejando el campo vacío que indicará que se puede realizar la entrega del producto en el punto de entrega en cualquier momento. El campo se debe indicar en segundos para marcar la hora final siendo su valor mínimo 0 (00:00:00) y 86.399 su valor máximo (23:59:59). La tabla de equivalencias (algunos ejemplos) entre segundos y horas es la siguiente:

• Restricciones: Número entero (int). Valor mínimo: 0. Valor máximo: 86.399. El número no debe contener separadores en los millares.


• Ejemplos:
  • 75600 
  • 45000 
  • 36900 

9. Carga total [demand] (✱):

• Identificador: demand
• Descripción: Cantidad de carga (cajas o unidades) que ocupan todos los pedidos de un punto de entrega en el vehículo de transporte. Su valor cobra sentido en relación a la capacidad que se defina en los vehículos de la empresa. Por ejemplo, si una ruta tiene 3 puntos de entrega con demand=30, demand= 320 y demand=16, el vehículo que realizará la ruta debe tener como mínimo una capacidad mayor que 366 (30 + 320 +16 = 366). Si se marca el valor como 0, no se tendrá en cuenta este campo.
• Restricciones: Número entero (int). Valor mínimo: 0. Valor máximo: <= capacidad del vehículo.


• Ejemplos:
  • 350 
  • 720 
  • 20  

10. Tiempo estimado del servicio [serviceTime]:

• Identificador: serviceTime
• Descripción: Tiempo estimado para realizar la descarga de los productos en un punto de entrega. Contabiliza la suma del tiempo que pasa entre que se estaciona el vehículo y se reanuda la ruta una vez realizada la entrega. Este valor se debe indicar en segundos. Si se marca el valor como 0, no se tendrá en cuenta este campo La tabla de equivalencias (algunos ejemplos) entre segundos y minutos es la siguiente:

• Restricciones: Número entero (int). Valor mínimo: 0. Valor máximo: 86.399.


• Ejemplos:
   • 300
   • 922 
   • 1902 

11. Firma [requiredSignature]:

• Identificador: requiredSignature
• Descripción: Indica si aparecerá o no el campo de firma en la aplicación. En caso de marcador como True, aparecerá el campo firma para poder firmar directamente desde la aplicación. En caso contrario, False, no aparecerá dicho campo en la aplicación. Dejar este campo vacío equivaldrá al valor False.
• Restricciones: Booleano (boolean).


• Ejemplos:
   • True 
   • False  

12. Correo electrónico [email]:

• Identificador: email
• Descripción: Correo electrónico del punto de entrega. En caso de tener un valor correcto, será la dirección donde se enviarán los albaranes, las firmas o los datos del chófer que está realizando la ruta, entre otros. En caso de dejar este campo vacío, no se tendrá en cuenta ninguna dirección de correo electrónico para ese punto de entrega.
• Restricciones: Cadena de caracteres (string). Valor máximo: 30 caracteres. Deberá tener el formato correcto de correo electrónico (con los símbolos @ y .).


• Ejemplos:
   • prueba_12@gmail.com 
   • fruteriainvent@frutas.es 
   • restauranteIT@grupores.es  

13. Número de teléfono [phone]:

• Identificador: phone
• Descripción: Número de teléfono referente al punto de entrega. Este número estará presente en la aplicación que llevaran los chóferes para poder ponerse en contacto en cualquier momento con el responsable del punto de entrega de dicho teléfono.
• Restricciones: Cadena de caracteres (string). Valor máximo: 30 caracteres. Deberá tener el formato correcto de teléfono (únicamente símbolos numéricos).


• Ejemplos:
   • 608123481 
   • 658124390 
   • 936581213  

5. Productos - Campos

Todos los formatos de archivo que veremos más delante deberán tener la misma información sobre los productos de cada punto de entrega. Los campos son los siguientes:


• deliveryPoints
  • id
  • deliveryNoteCode
  • taxPercent 
  • products 
    • code 
    • name 
    • quantity 
    • price 
    • measureQuantity 

5.1. Productos - Especificación de los campos

A continuación se especifica para cada uno de los campos descritos en el anterior apartado su definición y sus restricciones. Los campos marcados con el símbolo indicarán la obligatoriedad del mismo. Por el contrario, los campos que no lleven dicho símbolo serán tratados como información opcional. En caso de tener dependencia entre campos, se indicará en cada una de las especificaciones; así como los campos a los que se debe esa dependencia (obligatoriedad).

1. Identificador del punto de entrega [id] (✱):

• Identificador: id
• Descripción: Identifica el punto de entrega. No pueden existir dos puntos de entrega con el mismo identificador en el fichero de importación.
• Restricciones: Cadena de caracteres (string). Valor máximo: 100 caracteres.


• Ejemplos:
   • dp23767 
   • 738 
   • bcn_32 

2. Código del albarán [deliveryNoteCode] (✱):

• Identificador: deliveryNoteCode
• Descripción: Este campo hace referencia al número o código de albarán que será firmado por la persona responsable del punto de entrega en el momento de la entrega de los productos.
• Restricciones: Cadena de caracteres (string). Valor máximo: 30 caracteres.


• Ejemplos:
   • 45466770 
   • 12398 
   • 8743726 

3. Porcentaje del Impuesto sobre el Valor Añadido [taxPercent] (✱):

• Identificador: taxPercent
• Descripción: Indica el porcentaje del Impuesto sobre el Valor Añadido (IVA) de cada una de las comandas de un punto de entrega. Se debe tener en cuenta que un punto de entrega utiliza un mismo valor de IVA para todo el pedido de productos; así, si el cliente tiene diferentes productos con diferente IVA a aplicar, se debería introducir un nuevo fichero con los productos que tengan un IVA diferente. Este campo será usado para calcular el montante final que aparecerá en el albarán del punto de entrega.
• Restricciones: Número entero (int). Valor máximo: 100.


• Ejemplos:
   • 10 
   • 21 
   • 36 

4. Productos: Código del producto [products.code] (✱):

• Identificador: products.code
• Descripción: Código alfanumérico del producto que se está repartiendo. Este campo será único para cada uno de los productos del que se conforma el reparto de un punto de entrega. El valor del
campo podrá repetirse en diferentes puntos de entrega o en el mismo punto de entrega en cualquier otro grupo de productos.
• Restricciones: Cadena de caracteres (string). Valor máximo: 100 caracteres.


• Ejemplos:
   • X8912PPO9 
   • 0032 
   • FRU-003A 

5. Productos: Nombre del producto [products.name] (✱):

• Identificador: products.name
• Descripción: Nombre del producto referente el código del producto. No hace falta que sea único, es decir, puede haber dos productos con el mismo nombre pero con diferente código de producto (products.code).
• Restricciones: Cadena de caracteres (string). Valor máximo: 50 caracteres.


• Ejemplos:
   • Naranja sanguina 
   • Bolígrafo BIC Azul 
   • Pechuga de pollo 

6. Productos: Cantidad del producto [products.quantity] (✱):

• Identificador: products.quantity
• Descripción: Cantidad en valor entero del producto referente al código del producto. Este campo será usado para calcular el montante final que aparecerá en el albarán del punto de entrega.
• Restricciones: Número entero (int). Valor mínimo: 1.


• Ejemplos:
   • 10 
   • 1 
   • 125  

7. Productos: Precio del producto [products.price] (✱):

• Identificador: products.price
• Descripción: Valor decimal que marca el precio del producto por unidad. Esta valor será introducido en euros (€). Este campo será usado para calcular el montante final que aparecerá en el albarán del punto de entrega.
• Restricciones: Número decimal (float). Número máximo de decimales: 2. El separador decimal será un punto (0.96).


• Ejemplos:
   • 0.18 
   • 2 
   • 16.02 

8. Productos: Cantidad del producto [products.measureQuantity] (✱):

• Identificador: products.measureQuantity
• Descripción: Cantidad en valor entero del producto referente al código del producto. Este campo será usado para calcular el montante final que aparecerá en el albarán del punto de entrega.
• Restricciones: Número entero (int). Valor mínimo: 1.


• Ejemplos:
   • ?? 
   • ?? 
   • ??   

6. Importación mediante fichero

La importación mediante fichero requiere de la generación por parte del usuario de un fichero. Este fichero contiene la información de los puntos de entrega en un día concreto o de los productos a repartir en los diferentes puntos de entrega. Esta información puede representarse en cualquiera de los siguientes formatos:


• JSON 
• CSV (con una cabecera y con separación por comas)    

La codificación de caracteres del fichero debe ser UTF-8. Cualquier otra codificación puede causar problemas de representación de caracteres especiales.

Ambos formatos se utilizan para representar un conjunto de campos, y las reglas sobre los valores que pueden tener estos campos son las mismas para cualquiera de los formatos. Anteriormente ya hemos descrito cómo y dónde se especifican cada uno de los campos, indicando el significado y las restricciones de cada uno de los campos con independencia del formato de representación.

En los siguientes apartados se detallará el formato de los ficheros JSON y CSV pero no su forma de cargarlos dentro de la plataforma. Eso se explica en su correspondiente sección.

6.1. JSON

El formato JSON (Javascript Object Notation) sigue la siguiente estructura; una única propiedad deliveryPoints de tipo array. Cada uno de los elementos del array representa un punto de entrega o los productos de dicho punto de entrega. Todas las propiedades del punto de entrega y de los productos tienen definido el tipo con el que deben ser representadas (number, string o boolean). Es importante clarificar que para aquellos campos que son de tipo int o float no se aceptan valores de tipo string, incluso aunque estos sean representaciones de valores numéricos.

Punto de Entrega


{      
“deliveryPoints”: [           
   {               
       “id”: string,
       “address”: string,
       “coordinates”: {
          “latitude”: float,
          “longitude”: float
     },
       “name”: string,
       “deliveryZoneId”: string,
       “deliveryWindow”: {
          “start”: int,
          “end”: int
     },      
       “demand”: int,
       “serviceTime”: int,
       “requiredSignature”: boolean,
       “email”: string,
       “phone”: string 
    } 
 ] 
}

Productos


{      
     “deliveryPoints”: [
        {                
           “id”: string,
           “deliveryNoteCode”: string,
           “taxPercent”: int,
           “products”: {
              “code”: string,
              “name”: string, 
              “quantity”: int,
              “price”: float,  
              “measureQuantity”: int 
           }
         }
     ]
}

Algunos de los campos son obligatorios y otros son opcionales (especificado anteriormente). En el caso de los campos opcionales, si no tiene ningún valor se pueden omitir en el JSON, tener valor null o un valor por defecto. Es necesario aclarar que los campos anidados se considera que no tienen valor aún cuando el padre sí lo tiene. Por ejemplo, los dos siguientes JSON son equivalentes:


{      
   “deliveryPoints”: [
           {
                “id”: “1”,
                “deliveryWindow”: {},
            }
      ]
 }

{      
     “deliveryPoints”: [
           {
                “id”: “1”,
           }
      ]
}

El siguiente JSON es un pequeño ejemplo de como debería ser dicho fichero. En el enlace que acompaña a este pequeño código, se puede descargar un ejemplo completo de JSON para observar como sería un archivo para su uso y subida a Optimroute.

Ejemplo JSON - Punto de entrega


{
     "deliveryPoints": [
         {
             "id": "ay_bcn",
             "name": "Ajuntament de Barcelona",
             "address": "Plaza Sant Jaume, 1, 08002 Barcelona",
             "coordinates": {
                 "latitude": 41.382574,
                 "longitude": 2.17715
             },
             "demand": 40,
             "serviceTime": 50,
             "deliveryZoneId": “bcn",
             "deliveryWindow": {
                 "start": 39233
             },
             “email": “ajuntament@bcn.com”,
             "phone": "666777888"
         },
         {
             "id": "sagrada_familia",
             "name": "La Sagrada Família",
             "deliveryZoneId": "bcn",
             "address": "Carrer de Mallorca, 401, 08013 Barcelona",
             "serviceTime": 277
         },
         {
             "id": "castell_montjuic",
             "deliveryZoneId": "bcn",
             "address": "Ctra. de Montjuïc, 66, 08038 Barcelona"
         }
     ]
}

Ejemplo JSON - Productos


{
     "deliveryPoints": [
         {
             "id": “GIR-021",
             "deliveryNoteCode": “J432902",
             “taxPercent”: 16,
             "products": {
                 "code": “PL321319”,
                 "name": “Ibuprofeno 400 mg”,
                 “quantity”: 200,
                  "price": 1.5,
                 “measureQuantity”: 1,
             },
             {
                 "code": “PK002134”,
                 "name": “Acetaminofén 650 mg",
                 “quantity”: 50,
                  "price": 2,
                 “measureQuantity”: 1,
             },
              {
                 "code": “WT3221”,
                 "name": “Loratidina 100 mg",
                 “quantity”: 20,
                  "price": 0.72,
                 “measureQuantity”: 1,
             }
         }
     ]
 }

Fichero JSON de ejemplo de puntos de entrega descargable: Clica aquí. Fichero JSON de ejemplo de productos descargable: Clica aquí.

6.2. CSV

El formato CSV debe contener cabecera y los valores de los campos deben aparecer separados por el carácter , (una coma).

Esto significa que aquellos campos que tengan comas en su valor, como podría ser la dirección (address) o el nombre del punto de entrega (name), deberán aparecer delimitados por el carácter “ (comillas dobles) en el caso que dichos campos ontengan comas, tal como se define en su propia especificación anteriormente xpuesta.

Los identificadores de la cabecera de los puntos de entrega están especificados en sus correspondientes apartados. Por ello, estas deberían ser las cabeceras el fichero CSV para los puntos de entrega.

Cabecera CSV - Punto de entrega


id,address,coordinates.latitude,coordinates.longitude,name,deliveryZoneId,deliveryWindow.start,deliveryWindow.end,demand,serviceTime,requiredSignature,email,phone

Los campos opcionales, en caso de no tener valor, deberán aparecer vacíos, indicando únicamente la coma que los delimitan. Si un campo no se utiliza en ninguna de sus filas del fichero, se podrá omitir ese campo en la cabecera y las comas de todo el fichero que delimitarían dicho campo omitido.

Ejemplo CSV - Punto de entrega


id,address,coordinates.latitude,coordinates.longitude,name,deliveryZoneId,deliveryWindow.start,deliveryWindow.end,demand,serviceTime,requiredSignature,email,phone
ay_bcn,"Plaza Sant Jaume, 1, 08002 Barcelona",41.382574,2.17715,Ajuntament de Barcelona,bcn,39233,,40,False,ajuntament@bcn.cat,689123742 sagrada_familia,"Carrer de Mallorca, 401, 08013 Barcelona",,,La Sagrada Família,bcn,,,,277,True,,

Fichero CSV de ejemplo de puntos de entrega descargable: Clica aquí.

7. Importación mediante API

La importación mediante API requiere de la generación por parte del usuario de un token. Este token contiene la información de los puntos de entrega en un día concreto o de los productos a repartir en los diferentes puntos de entrega. Hay que decir que esta opción nos creará un fichero JSON como el que hemos detallado en su correspondiente apartado, y que tendremos que cargar en la plataforma.

7.1.Creación del AccessToken

Para la integración de cualquier contenido vía API se necesitará la creación de un token de acceso. Este token es una string aleatorio que identifica a un usuario dentro de una aplicación o servicio, para realizar llamadas a la API.

Para los que no estén familiarizados con el término, una API es un conjunto de funciones que se usan para que una aplicación pueda usar otro software por encima. Hablando concretamente de OptimRoute, se debe crear un token de acceso para conectar vuestro propio software con nuestra API para poder utilizar nuestro servicio sin modificar en ningún momento el vuestro propio.

Para obtener este token de acceso tendrá que tener un usuario creado en nuestra plataforma con el perfil de técnico. Este primer usuario se lo creará uno de nuestros propios técnicos y se os enviará a vuestro cuenta de correo de contacto en el momento del inicio de la integración. En caso de querer crear otra cuenta de usuario de tipo técnico, debes dirigiros a la sección de Gestión y en la pestaña de Usuarios clicar en Agregar usuario y rellenar todos los campos; indicando el tipo de usuario como técnico. Las siguiente imágenes muestran estos pasos gráficamente:

Una vez se tenga el usuario o usuarios de perfil técnico, llega el momento de conectarse a nuestra API para realizar el envío de los datos. Los parámetros de la conexión son los siguientes:

URL: https://restapi.resetsign.com/api/oauth/token_integrator
• MÉTODO: POST
• CONTENIDO: application/json

Para obtener el token de acceso se deberá hacer una petición a la API con el siguiente esquema de código:

Petición a la API


{
    “client_id”: 1,
    “client_secret”: “tT96kecNtYVf92dvRfQ1Ikj6sjsx5tKZzaCCpHun”,
    “username”: “integration@company.com”,
    “password”: “secret_password”,
    “grant_type”: “password”
}

Los campos client_id, client_secret y grant_type son constantes, es decir, no deben modificarse en ningún caso. Por otra parte, los campos username y password sí que son modificables, y deberán rellenarse con los datos del usuario creado anteriormente como técnico.
Una vez establecida la conexión y hecha la petición a la API, se recibirá la respuesta por parte de nuestro sistema con el token de acceso.

Respuesta de la petición a la API


{
    “access_token”: “eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiI”,
    “refresh_token”: “def50200388a50a45925d65”,
    “expires_in”: 86400,
    “token_type”: “Bearer”,
    “username”: “integration@company.com”
}

La parte más importante de esta respuesta es el valor del token de acceso (access_token), que eslo que se tendrá que usar para la integración de los datos que veremos a continuación.

7.2. Creación de puntos de entrega por API

Una vez se tenga el usuario o usuarios de perfil técnico, y el token de acceso para la conexión a la API, ya se podrá cargar las datos en la plataforma. Los parámetros de la conexión para la carga de datos son los siguientes:

URL: https://restapi.resetsign.com/api/integration
• MÉTODO: POST
• CONTENIDO: application/json

El esquema de código el mismo que se usa para integración de los datos mediante JSON o CSV.
Sólo se incluyen tres campos nuevos (automáticamente) que únicamente sirven para diferenciar las diferentes integraciones hechas vía API, así como información adicional acerca de ésta. A continuación se especifica para cada uno de los tres campos su definición y sus restricciones. Los campos marcados con el símbolo indicarán la obligatoriedad del mismo. Por el contrario, los campos que no lleven dicho símbolo serán tratados como información opcional. En caso de tener dependencia entre campos, se indicará en cada una de las especificaciones; así como los campos a los que se debe esa dependencia (obligatoriedad).

1. Nombre de la integración [name] (✱):

• Identificador: name
• Descripción: Nombre de la integración que se está llevando a cabo. No hace falta que sea único, es decir, puede haber dos integraciones diferentes con el mismo nombre pero con diferente fecha de creación.
• Restricciones: Cadena de caracteres (string). Valor máximo: 100 caracteres.


• Ejemplos:
  • Prueba0012
  • X1266
  • BCN_int003

2. Observaciones sobre la integración [description]:

• Identificador: description
• Descripción: Este campo permite indicar las observaciones o comentarios respecto a la integración que se está llevando a cabo.
• Restricciones: Cadena de caracteres (string). Valor máximo: 255 caracteres.


• Ejemplos:
  • Todo correcto

3. Fecha de la integración [dateSession] (✱):

• Identificador: dateSession
• Descripción: Indica la fecha en la que se lleva a cabo la integración.
• Restricciones: Fecha (datetime). Formato: YYYY-MM-DD


• Ejemplos:
  • 2020-01-12
  • 2020-01-25
  • 2020-02-01

Junto con estos nuevos tres campos, y como ya se ha dicho, hay que añadir los campos anteriormente especificados en su apartado.

Punto de entrega vía API


{
      “name”: string,
      “description”: string,
      “dateSession”: datetime,
      “deliveryPoints”: [
           {
                “id”: string,
                “address”: string,
                “coordinates”: {
                     “latitude”: float,
                     “longitude”: float
                },
                “name”: string,
                “deliveryZoneId”: string,
                “deliveryWindow”: {
                     “start”: int,
                     “end”: int
                },
                “demand”: int,
                “serviceTime”: int,
                “requiredSignature”: boolean,
                “email”: string,
                “phone”: string
           }
      ]
 }

Ejemplo - Punto de entrega vía API


{      
      “name”: “MAD-00123”,
      “dateSession”: ”2020-11-24”,
      “deliveryPoints”: [
           {
                “id”: “1",
                “address”: ”Carrer Mallorca, 591 08026 Barcelona”,
                “name”: “Farmacia Anna”,
                “deliveryZoneId”: ”BCN”,
                “deliveryWindow”: {
                     “start”: 28800,
                     “end”: 36000
                },
                “demand”: 12,
                “serviceTime”: 480,
                “requiredSignature”: false,
                “phone”: “638901266”
           }
      ]
 }

7.3. Creación de productos por API

Una vez se tenga el usuario o usuarios de perfil técnico, el token de acceso para la conexión a la API y las rutas correspondientes cargadas, ya se podrán cargar las datos de los productos en la plataforma. Los parámetros de la conexión para la carga de los productos son los siguientes:

URL: https://restapi.resetsign.com/api/integration/route/products
• MÉTODO: POST
• CONTENIDO: application/json

El esquema de código el mismo que se usa para integración de los datos mediante JSON o CSV. Solo se incluye un campo nuevo que sirve para identificar a que ruta pertenecen los productos a añadir. A continuación se especifica para dicho campo su definición y sus restricciones. Los campos marcados con el símbolo indicarán la obligatoriedad del mismo. Por el contrario, los campos que no lleven dicho símbolo serán tratados como información opcional. En caso de tener dependencia entre campos, se indicará en cada una de las especificaciones; así como los campos a los que se debe esa dependencia (obligatoriedad).

1. Identificador de la ruta [routeId] (✱):

• Identificador: routeId
• Descripción: Identificador de la ruta a la que se le asignarán los productos que se están añadiendo.
• Restricciones: Número entero (int). Valor mínimo: 1.


• Ejemplos:
  • 12 
  • 234 
  • 3

Junto con este nuevo campo, y como ya se ha dicho, hay que añadir los campos anteriormente especificados en su apartado.

Productos vía API


{
      “routeId”: int,
      “deliveryPoints”: [
           {
                “id”: string,
                “deliveryNoteCode”: string,
                “taxPercent”: int,
                “products”: {
                     “code”: string,
                     “name”: string,
                     “quantity”: int,
                     “price”: float,
                     “measureQuantity”: int
                }
           }
      ]
}

Ejemplo - Productos vía API


{      
      “routeId”: 6,
      “deliveryPoints”: [
           {
                “id”: “BCN12",
                “deliveryNoteCode”: “6736",
                “taxPercent”: 21,
                “products”: {
                     “code”: “PP9032",
                     “name”: “Ibuprofeno 400 mg",
                     “quantity”: 200,
                     “price”: 1.5,
                     “measureQuantity”: 1
                },
                {
                     “code”: “LX3212",
                     “name”: “Acetaminofén 650 mg",
                     “quantity”: 500,
                     “price”: 2.0,
                     “measureQuantity”: 1
                }
           }
      ]
}

7.4. Creación de puntos de entrega y productos por API

Hay la posibilidad de cargar en la plataforma los datos sobre los puntos de entrega y los productos en la misma conexión. Una vez se tenga el usuario o usuarios de perfil técnico, y el token de acceso para la conexión a la API, ya se podrá cargar las datos en la plataforma. Los parámetros de la conexión para la carga de datos son los siguientes:

URL: https://restapi.resetsign.com/api/integration
• MÉTODO: POST
• CONTENIDO: application/json

El esquema de código el mismo que se usa para integración de los datos mediante JSON o CSV. En este caso, no hay nuevos campos a añadir a los vistos en las secciones de puntos de entrega y productos por API.

Punto de entrega y productos vía API


{
      “name”: string,
      “description”: string,
      “dateSession”: datetime,
      “deliveryPoints”: [
           {
                “id”: string,
                “address”: string,
                “coordinates”: {
                     “latitude”: float,
                     “longitude”: float
                },
                “name”: string,
                “deliveryZoneId”: string,
                “deliveryWindow”: {
                     “start”: int,
                     “end”: int
                },
                “demand”: int,
                “serviceTime”: int,
                “requiredSignature”: boolean,
                “email”: string,
                “phone”: string,
                “deliveryNoteCode”: string,
                “taxPercent”: int,
                “products”: {
                     “code”: string,
                     “name”: string,
                     “quantity”: int,
                     “price”: float,
                     “measureQuantity”: int
                }
           }
      ]
}

Ejemplo - Punto de entrega y producto vía API


{      
      “name”: “MAD-00123”,
      “dateSession”: ”2020-11-24”,
      “deliveryPoints”: [
           {
                “id”: “1",
                “address”: ”Carrer Mallorca, 591 08026 Barcelona”,                “name”: “Farmacia Anna”,
                “deliveryZoneId”: ”BCN”,
                “deliveryWindow”: {
                     “start”: 28800,
                     “end”: 36000
                },
                “demand”: 12,
                “serviceTime”: 480,
                “requiredSignature”: false,
                “phone”: “638901266”,
                “deliveryNoteCode”: “6736",
                “taxPercent”: 21,
                “products”: {
                     “code”: “PP9032",
                     “name”: “Ibuprofeno 400 mg",
                     “quantity”: 200,
                     “price”: 1.5,
                     “measureQuantity”: 1
                },
                {
                     “code”: “LX3212",
                     “name”: “Acetaminofén 650 mg",
                     “quantity”: 500,
                     “price”: 2.0,
                     “measureQuantity”: 1
                }
           }
      ]
}

8. Importación mediate SFTP

La importación mediante SFTP requiere de una conexión particular de cada cliente a nuestro servidor SFTP. Este usuario se lo creará uno de nuestros propios técnicos y se os enviará a vuestra cuenta de correo de contacto en el momento del inicio de la integración. Hay que decir que esta opción necesita de varios ficheros JSON como los que se han detallado en su correspondiente apartado, y que se tendrán que cargar con la conexión SFTP indicada a continuación.

8.1.Datos de para la conexión SFTP

Las credenciales necesarias para la integración mediante SFTP son las siguientes:


  • USUARIO: Usuario creado por nuestros técnicos. 
  • CONTRASEÑA: Contraseña del usuario creada por nuestros técnicos. 
  • SERVIDOR: Dirección a la que conectarse con el usuario asignado.
  • PUERTO: Puerto por el cual se conectará el cliente a nuestro servidor. 

Nuestro técnico se encargará de crear toda la estructura de directorios personalizada que se explica a continuación. Antes de eso, se debe tener claro que hay dos tipos de directorio dentro del Servidor SFTP de OptimRoute.

Directorios de envío de ficheros: Estos directorios serán los que el cliente utilizará para cargar sus propios JSON a nuestra plataforma (importaciones). 
  • Directorios de recogida de ficheros: Estos directorios serán los que el cliente utilizará para recoger los ficheros descargados desde nuestra plataforma (recuperaciones). 

Es muy importante tener esto claro ya que sino pueden ocurrir errores a la hora de cargar ficheros a nuestra plataforma o, en el caso de los clientes, de leer los datos de forma equivocada.

Una vez vista esta distinción, vamos a especificar los directorios en cada uno de los dos casos nombrados

 Directorio Rutas (Envío de ficheros): En esta carpeta el cliente dejará sus ficheros JSON de las rutas a cargar en nuestra plataforma. 
  • Directorio Productos (Envío de ficheros): En esta carpeta el cliente dejará sus ficheros JSON de los productos a cargar en nuestra plataforma. 
  • Directorio Rutas con productos (Envío de ficheros): En esta carpeta el cliente dejará sus ficheros JSON de las rutas con productos a cargar en nuestra plataforma. 
  • Directorio Ordenación (Recogida de ficheros): En esta carpeta el cliente recogerá los ficheros JSON descargados desde nuestra plataforma con las rutas evaluadas y/o optimizadas (ver apartado de Recuperación de rutas evaluadas y/o calculadas). 
  • Directorio Firmas (Recogida de ficheros): En esta carpeta el cliente recogerá los ficheros JSON descargados desde nuestra plataforma con las firmas de los albaranes de los sus clientes (ver apartado de Recuperación de albaranes firmados). 

9. Carga de un fichero en la plataforma JSON o CSV

Una vez tengamos el fichero en de puntos de entrega o de productos (cabe decir, que es obligatorio cargar primero el fichero de puntos de entrega, ya que los productos van asociados a cada uno de los puntos de entrega de una ruta) ya podremos subir dichos archivos a nuestra plataforma para su visualización y tratamiento. Como se ha dicho en sus correspondientes apartados, podemos tener un fichero JSON creado por nosotros mismos o por el software propio de la empresa o resultado de la petición vía API, o bien un fichero CSV.
Para cargar dichos ficheros, en la parte superior izquierda de nuestra aplicación se encuentran los botones que permiten su carga. Para ello, elegiros la opción de subida deseada; importar fichero o importar fichero desde la nube. En cualquier caso, no hará falta indicar si se trata de un fichero JSON o de un CSV ya que será nuestra propia plataforma la que lidie con ello.

Una vez cargado el fichero a la plataforma, ésta misma se encargará de distribuir los diferentes puntos de entrega establecidos en dicho fichero según sus parámetros. En el caso de cargar un fichero de productos, funcionaría exactamente igual que la subida descrita.
La siguiente imagen corresponde a un ejemplo de carga de un fichero y del resultado final al hacerlo.

10. Recuperación de contenido de la plataforma

De tal forma que se usa OptimRoute para la integración de puntos de entrega y de productos para su uso y evaluación, también se puede usar la plataforma para, una vez cargadas y evaluadas dichas opciones, descargar los ficheros con las optimizaciones realizadas para su uso en la propia plataforma del cliente. Esta opción de se puede dividir en tres tipos de recuperación; recuperación de rutas evaluadas y/ o calculadas por API, recuperación de rutas evaluadas y/o calculadas por JSON y recuperación de los albaranes firmados por JSON.

10.1.Recuperación de rutas evaluadas o calculadas por API

Este tipo de recuperación de datos de la plataforma se basa en los puntos de entrega que conforman la ruta una vez avaluada y optimizada. Una vez se tenga el usuario o usuarios de perfil técnico, y el token de acceso para la conexión a la API, ya se podrá recuperar la ruta evaluada. Los parámetros de la conexión son los siguientes:

URL: https://restapi.resetsign.com/api/integration/route/history
• MÉTODO: POST
• CONTENIDO: application/json

Junto a estos parámetros, también se añade un nuevo campo de tipo fecha para mantener un registro de cuando se ha realizado esta recuperación de los datos. A continuación se especifica para dicho campo su definición y sus restricciones. Los campos marcados con el símbolo indicarán la obligatoriedad del mismo. Por el contrario, los campos que no lleven dicho símbolo serán tratados como información opcional. En caso de tener dependencia entre campos, se indicará en cada una de las especificaciones; así como los campos a los que se debe esa dependencia (obligatoriedad).

1. Fecha de la recuperación [dateDeliveryStart] (✱):

• Identificador: dateDeliveryStart
• Descripción: Indica la fecha en la que se lleva a cabo la recuperación.
• Restricciones: Fecha (datetime). Formato: YYYY-MM-DD


• Ejemplos:
  • 2020-01-12
  • 2020-01-25
  • 2020-02-01

Parámetro de recuperación de rutas evaluadas


{
      “dateDeliveryStart”: “2020-04-18”
}

Una vez enviada la petición, tan solo se tendrá que esperar la respuesta de nuestro servidor. En ésta, encontraremos los campos que seguidamente se definen.


• routes 
  • vehicleId 
  • routeId 
  • deliveryZoneId 
  • deliveryPoints 
    • id 
    • order 
    • estimatedArrivalTime 
    • requiredSignature 
    • driverArrivalTime 
    • signature 
    • signatureTime 
    • dniDeliveryNote 
    • nameDeliveryNote 
    • deliveredBoxes 
    • devolutionDeliveryNote 

La especificación de los campos es la siguiente:

1. Identificador del vehículo [vehicleId]:

• Identificador: vehicleId
• Descripción: Identificador del vehículo que ha realizado la ruta en nuestra plataforma.

2. Identificador de la ruta [routeId]:

• Identificador: routeId
• Descripción: Identificador de la ruta a recuperar.

3. Identificador de la zona de reparto [deliveryZoneId]:

• Identificador: deliveryZoneId
• Descripción: Zona de reparto a la que pertenece el punto de entrega (cliente). Una zona de reparto agrupa un conjunto de puntos de entrega. Un mismo vehículo no puede realizar entregas en zonas de reparto diferentes, pero sí pueden realizar entregas en una misma zona de reparto diferentes

4. Identificador del punto de entrega [deliveryPoints.id]:

• Identificador: deliveryPoints.id
• Descripción: Identifica el punto de entrega. No pueden existir dos puntos de entrega con el mismo identificador.

5. Identificador del punto de entrega ya evaluado y/o calculado [deliveryPoints.order]:

• Identificador: deliveryPoints.order
• Descripción: Identifica el punto de entrega en la nueva posición una vez evaluada y/o calculada la ruta. No pueden existir dos puntos de entrega con el mismo identificador. .

6. Hora estimada de llegada calculada del chófer [deliveryPoints.estimatedArrivalTime]:

• Identificador: deliveryPoints.estimatedArrivalTime
• Descripción: Especifica la hora del día, calculada por nuestra plataforma, en la que llegará el chófer al punto de entrega.

7. Firma requerida [deliveryPoints.requieredSignature]:

• Identificador: deliveryPoints.requiredSignature
• Descripción: Identifica el punto de entrega en la nueva posición una vez evaluada y/o calculada la ruta. No pueden existir dos puntos de entrega con el mismo identificador.

8. Hora de llegada calculada del chófer [deliveryPoints.driverArrivalTime]:

• Identificador: deliveryPoints.driverArrivalTime
• Descripción: Especifica la hora del día en la que el chófer ha llegado al punto de entrega.

9. Imagen de la firma del cliente [deliveryPoints.signature]:

• Identificador: deliveryPoints.signature
• Descripción: Imagen (en base64) de la firma del albarán del cliente a la hora de la entrega de los productos en su establecimiento.

10. Hora de la firma del cliente [deliveryPoints.signatureTime]:

• Identificador: deliveryPoints.signatureTime
• Descripción: Fecha y hora en la que el cliente firmo la entrega del pedido.

11. Documento de identificación del cliente [deliveryPoints.dniDeliveryNote]:

• Identificador: deliveryPoints.dniDeliveryNote
• Descripción: Documento de identificación personal del cliente al que se le entrega el pedido.

12. Nombre y apellido/s del cliente [deliveryPoints.nameDeliveryNote]:

• Identificador: deliveryPoints.nameDeliveryNote
• Descripción: Nombre y apellidos del cliente al que se le entrega el pedido.

13. Número de cajas entregadas [deliveredBoxes]:

• Identificador: deliveredBoxes
• Descripción: Número total de cajas que el chófer deposita en el punto de entrega. En caso de no tener ningún valor, aparecerá como null.

14. Notas de la entrega [devolutionDeliveryNote]:

• Identificador: devolutionDeliveryNote
• Descripción: Notas opcionales del cliente respecto a la entrega de los productos en el caso que haya alguna devolución. En caso de no tener ningún valor, aparecerá como null.

En cuanto al fichero JSON descargado el formato será el siguiente:

Ejemplo JSON - Recuperación de rutas evaluadas y/o calculadas


{
     "routes": [
         {
             "vehicleId": 2,
             “routeId”: 1,
             "deliveryZoneId": "BCN",
             "deliveryPoints": [
             {
                 "id": "X032",
                 "order": 1,
                 "estimatedArrivalTime": 27000
                 "requiredSignature": false,
                 "driverArrivalTime": “2020-01-28 15:42:29",
                 "signature": “data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/ 2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwS ExIQEw8QEBD2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB AQEBAQEBAQEBAQEBAQEBAQEBDwAARCADmAPoDASIAAhEBAxEB8QAHQABAAIDAQEBAQAAAAAAAAAAAA YHAwQFAgEICfAD0QAAIBAwMDAgMFBAcJAAAAAAABAgMEBQYREgchMRNBFFFhFSJxgZEIFzJSFiQzU2KCoTQ 1QkNykrGy0f/EABQBAQAAAAAAAAAAAAAAAAAAAAD/ /9k=",
                 "signatureTime": "2019-11-07 15:42:50”,
                 "dniDeliveryNote": "12345678P",
                 "nameDeliveryNote": “Cliente de prueba",
                 "deliveredBoxes": 3,
                 “devolutionDeliveryNote": null
             }
           ]
         }
     ]
}

10.2. Recuperación de rutas evaluadas o calculadas por JSON o CSV

Esta opción le permite realizar la descarga de las rutas evaluadas y optimizadas desde la sección panel de control una vez se haya evaluado o calculado la ruta. Así, aparecerá un botón de descarga en la parte superior derecha al darle clic al botón de descarga aparecerá un cuadro de dialogo que le permitirá elegir las rutas que desea obtener y el formato deseado entre JSON y CSV.

Como se puede observar en la imagen siguiente, se debe indicar si la extracción de datos de la plataforma se hace de una ruta evaluada o de una ruta calculada.

El fichero resultante de esta operación será un JSON o un CSV con los siguientes campos:


• routes 
  • vehicleId 
  • deliveryZoneId 
  • deliveryPoints 
    • id 
    • order 
    • estimatedArrivalTime

En el caso del fichero CSV se sustituye el campo deliveryPoint y el campo deliveryPoint.id por un campo que fusiona estos dos llamado deliveryPointId que hace la misma función (como se puede ver en el ejemplo CSV de debajo). Como estos campos se extraen de la propia plataforma OptimRoute, no tendrán restricciones ya que tendrán ya una salida correcta.

1. Identificador del vehículo [vehicleId]:

• Identificador: vehicleId
• Descripción: Identificador del vehículo que ha realizado la ruta en nuestra plataforma.

2. Identificador de la zona de reparto [deliveryZoneId]:

• Identificador: deliveryZoneId
• Descripción: Zona de reparto a la que pertenece el punto de entrega (cliente). Una zona de reparto agrupa un conjunto de puntos de entrega. Un mismo vehículo no puede realizar entregas en zonas de reparto diferentes, pero sí pueden realizar entregas en una misma zona de reparto diferentes vehículos.

3. Identificador del punto de entrega [deliveryPoints.id]:

• Identificador: deliveryPoints.id
• Descripción: Identifica el punto de entrega. No pueden existir dos puntos de entrega con el mismo identificador.

4. Identificador del punto de entrega ya evaluado y/o calculado [deliveryPoints.order]:

• Identificador: deliveryPoints.order
• Descripción: Identifica el punto de entrega en la nueva posición una vez evaluada y/o calculada la ruta. No pueden existir dos puntos de entrega con el mismo identificador.

5. Hora de llegada calculada del chófer [deliveryPoints.estimatedArrivalTime]:

• Identificador: deliveryPoints.estimatedArrivalTime
• Descripción: Especifica la hora del día, calculada por nuestra plataforma, en la que llegará el chófer al punto de entrega.

En cuanto al fichero CSV descargado el formato será el mismo que el usado a la hora de subir un archivo CSV de puntos de entrega normal con los campos especificados en este apartado. El formato CSV contendrá una cabecera y los valores de los campos separados por el carácter , (una coma).

Cabecera CSV - Recuperación de rutas evaluadas y/o calculadas


deliveryPointId,deliveryZoneId,vehicleId,order,estimatedArrivalTime

Ejemplo CSV - Recuperación de rutas evaluadas y/o calculadas


deliveryPointId,deliveryZoneId,vehicleId,order,estimatedArrivalTime “1”,”BCN”,”12”,1,27000 

En cuanto al fichero JSON descargado el formato será el mismo que el usado a la hora de subir un archivo JSON de puntos de entrega normal con los campos especificados en este apartado.

Ejemplo JSON - Recuperación de rutas evaluadas y/o calculadas


{
     "routes": [
         {
             "vehicleId": 12,
             "deliveryZoneId": "BCN",
             "deliveryPoints": [
             {
                 "id": "X032",
                 "order": 1,
                 "estimatedArrivalTime": 27000
             },
             {
                 "id": "PD213",
                 "order": 2,
                 "estimatedArrivalTime": 32400
             }
             ]
         }
     ]
 }

10.3. Recuperación de albaranes firmados por JSON

Esta opción le permite realizar la descarga de los datos obtenidos por los chóferes de todos los puntos de entrega que ha visitado desde la sección de Panel de control. En esta sección, veremos todo el histórico de rutas y de los puntos de entrega que pertenecen a cada una de ellas. Para descargar el fichero JSON hay un botón en la parte superior derecha de la página web. También se puede descargar el fichero de un único punto de entrega desde el botón de descarga que tienen cada uno de los clientes. Ambos casos, se ven reflejados en la siguiente imagen:

El fichero resultante de esta operación será un JSON con los siguientes campos:


• id 
• signature 
• deliveredBoxes 
• devolutionDeliveryNote 

La especificación de los campos es la siguiente:

1. Identificador del punto de entrega [id]:

• Identificador: id
• Descripción: Identifica el punto de entrega. No pueden existir dos puntos de entrega con el mismo identificador.

2. Imagen de la firma del cliente [signature]:

• Identificador: signature
• Descripción: Imagen (en base64) de la firma del albarán del cliente a la hora de la entrega de los productos en su establecimiento.

3. Número de cajas entregadas [deliveredBoxes]:

• Identificador: deliveredBoxes
• Descripción: Número total de cajas que el chófer deposita en el punto de entrega. En caso de no tener ningún valor, aparecerá como null.

4. Notas de la entrega [devolutionDeliveryNote]:

• Identificador: devolutionDeliveryNote
• Descripción: Notas opcionales del cliente respecto a la entrega de los productos en el caso que haya alguna devolución. En caso de no tener ningún valor, aparecerá como null.

En cuanto al fichero JSON descargado el formato será el siguiente:

Ejemplo JSON - Recuperación de albaranes firmados


{
     "routes": [
         {
             "id": “BCN”,
             "signature": “data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/ 2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwS ExIQEw8QEBD/ wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE BAQEBAQEBAQEBD/wAARCADmAPoDASIAAhEBAxEB/8QAHAABAQACAwEBAAAAAAAAAAAAAAYFBwIDBAEJ/ 8QAORAAAQMEAAQEAggDCQAAAAAAAAECAwQFBhESITFBBxNRYRQiFSMyQlJxgZEkU7EWFzNEYoKSssL/ xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A/ VMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPNcLjQ2mhnuVyqo6alpmLJLLI7TWNTuqgekhLh4t2Z1bNZ8Ptdwym4wrw uZbo9wRu9Hzr8jU99qYqKC==“,
             "deliveredBoxes": “4”,
             "devolutionDeliveryNote": null
         }
     ]
}