# Entregas

> Los controles de recepción y las fotografías tomadas al recibir: dos colecciones, cada campo y qué significan sobre el terreno.

Source: https://developers.backresto.com/es/docs/deliveries

Una entrega es un control de recepción: un miembro del personal que recibe un
pedido, registra temperaturas y decide si aceptarlo. Es el registro que pide un
inspector de seguridad alimentaria. Las fotos tomadas en la recepción son una
segunda colección a su lado.

| Colección | Scope | Qué es un registro |
| --- | --- | --- |
| `deliveries` | `deliveries:read` | Un control de recepción, con una lectura de temperatura por producto. |
| `delivery-pictures` | `delivery-pictures:read` | Una fotografía tomada durante una entrega, que apunta de vuelta a ella. |

Las dos son [colecciones](https://developers.backresto.com/es/docs/collections) corrientes: el mismo sobre de
snapshot alrededor de `data`, los mismos endpoints, el mismo cursor, la misma
regla de los 90 días. Llevan el historial de entregas que la aplicación todavía
conservaba cuando se abrieron, no solo lo registrado desde entonces.

## `deliveries`

| Campo | Tipo | Significado |
| --- | --- | --- |
| `timestamp` | string, **obligatorio** | Cuándo ocurrió el control, en milisegundos desde la época Unix como cadena. |
| `isCompliant` | boolean, **obligatorio** | El veredicto del miembro del personal sobre la entrega en su conjunto. |
| `supplierDeliveriesId` | string \| null | El [proveedor](https://developers.backresto.com/es/docs/catalogue) del que venía la mercancía: el `id` de un registro de `suppliers`. |
| `temperatureRecords` | array \| null | Una entrada por producto medido. Véase más abajo. |
| `nonComplianceReasons` | string[] \| null | Por qué se rechazó la entrega o se aceptó con reservas. Texto libre elegido por el miembro del personal; vacío cuando es conforme. |
| `correctiveActions` | string[] \| null | Qué se hizo al respecto. Vacío cuando no hizo falta nada. |
| `commentary` | string \| null | Nota de texto libre. A menudo `null`. |
| `userId` | string \| null | El [miembro del personal](https://developers.backresto.com/es/docs/facilities) que la recibió, cuando la aplicación lo registró. |

### `temperatureRecords[]`

| Campo | Tipo | Significado |
| --- | --- | --- |
| `product` | string | Qué se midió, tal como lo nombró el miembro del personal. Nunca vacío. |
| `lotNumber` | string \| null | El lote, cuando se capturó. |
| `value` | number \| null | La lectura. `null` cuando el producto se registró sin medición. |
| `unit` | `"C"` | Siempre Celsius. Véase más abajo. |

**Las temperaturas están siempre en Celsius.** Un restaurante cuya aplicación
registra en Fahrenheit sigue enviando lecturas en Fahrenheit, y se convierten al
llegar, antes de almacenarse. `unit` es `"C"` en todas las entradas, así que quien
lo consume nunca tiene que convertir ni adivinar.

```json
{
  "id": "8f2c1b04-0d5a-4b7e-9f31-6ad2c0e77a51",
  "collection": "deliveries",
  "deleted": false,
  "capturedAt": "1787932805120",
  "receivedAt": "1787932911004",
  "sequence": "88",
  "data": {
    "timestamp": "1787932800000",
    "isCompliant": false,
    "supplierDeliveriesId": "supplier-7",
    "temperatureRecords": [
      { "product": "Poulet fermier", "lotNumber": "L2291", "value": 6.4, "unit": "C" },
      { "product": "Farine T55", "lotNumber": null, "value": null, "unit": "C" }
    ],
    "nonComplianceReasons": ["Température trop élevée"],
    "correctiveActions": ["Produit refusé", "Fournisseur prévenu"],
    "commentary": "Camion en retard, rupture de chaîne du froid probable",
    "userId": "2774953d-8d9b-4a68-8ec4-1209edd90777"
  }
}
```

## `delivery-pictures`

Una etiqueta, un palé dañado, una sonda apoyada en un expositor: esas fotos son
la prueba que hay detrás de `isCompliant`. Cada una es un registro que apunta a
su entrega, y lleva un archivo, así que los bytes salen del endpoint de archivos
adjuntos.

| Campo | Tipo | Significado |
| --- | --- | --- |
| `timestamp` | string, **obligatorio** | Cuándo se tomó la foto, en milisegundos desde la época Unix como cadena. |
| `deliveryId` | string \| null | El registro de `deliveries` al que pertenece. |
| `part` | number \| null | Posición de este registro dentro de una foto que la aplicación guardó en varias partes. Transmítalo tal cual en lugar de interpretarlo. |
| `groupId` | string \| null | Une esas partes. Los registros que comparten un `groupId` son la misma foto. |
| `asset` | object, **obligatorio** | Nombra el archivo: `objectKey` y `status` siempre, más `contentType`, `byteLength` y `sha256` una vez subido. |

```json
{
  "id": "c61e0a7d-35b2-4f89-a1d4-7e90b2c45f18",
  "collection": "delivery-pictures",
  "deleted": false,
  "capturedAt": "1787932861240",
  "receivedAt": "1787932990517",
  "sequence": "143",
  "data": {
    "timestamp": "1787932860000",
    "deliveryId": "8f2c1b04-0d5a-4b7e-9f31-6ad2c0e77a51",
    "part": 4,
    "groupId": "b4d81f0a-c2e7-4a55-9d10-6f3e8a2b7c91",
    "asset": {
      "objectKey": "delivery-pictures/b4d81f0a/4.jpg",
      "status": "uploaded",
      "contentType": "image/jpeg",
      "byteLength": 902450,
      "sha256": "9f2a…"
    }
  }
}
```

Los bytes son una segunda llamada, sobre el propio id del registro:

```http
GET /v1/restaurants/{restaurantId}/collections/delivery-pictures/records/{recordId}/assets
```

Responde con URL firmadas válidas durante quince minutos, exactamente como se
describe en [la página de colecciones](https://developers.backresto.com/es/docs/collections). Pida cualquier parte
de una foto y obtendrá el mismo archivo: la API resuelve el grupo por usted, así
que no hace falta averiguar qué parte lo contiene.

Para mostrar las fotografías de una entrega, recorra `delivery-pictures` y
quédese con los registros cuyo `deliveryId` sea el `id` de esa entrega, uno por
`groupId`.

## Leerlo correctamente

**`isCompliant` es el registro, no un cálculo.** Es lo que decidió la persona que
recibió la entrega, y puede no coincidir con lo que usted concluiría solo a partir
de las temperaturas: una lectura tomada con una sonda de superficie, un producto
con su propio umbral, un juicio profesional. Preséntelo como el veredicto de esa
persona. Si quiere el suyo, calcúlelo junto al de ella y etiquételo como suyo.

**Los campos de texto libre son texto libre.** `nonComplianceReasons`,
`correctiveActions` y `product` los teclea el personal durante el servicio, en el
idioma del restaurante y con la ortografía de un martes de mucho trabajo. No
construya un enum a partir de ellos, no los use como clave de un join y no dé por
hecho que estén en francés.

**`value` puede ser `null`.** Un producto registrado sin lectura es normal: a
menudo es un producto seco. Trate `null` como "no medido", nunca como `0`.

**Las marcas de tiempo son cadenas.** `timestamp` es una cadena decimal de
milisegundos desde la época Unix, porque toda la plataforma BackResto almacena
así las marcas de tiempo. `Number(timestamp)` es seguro hoy y durante los
próximos cientos de miles de años, pero no deje que un parser de JSON lo
convierta en silencio y luego lo vuelva a escribir con pérdida de precisión.

**Una foto puede llegar después de su entrega.** Un teléfono sube las fotografías
cuando puede, a veces minutos después del propio control. Una entrega que todavía
no tiene foto puede simplemente tener una en camino; vuelva a recorrer más tarde
antes de concluir que no tiene ninguna.
