# TMS — Visão Geral

# TMS

Esta seção é voltada para sistemas de gestão de transporte (TMS) que integram com a Abbiamo para enviar rotas fechadas ao aplicativo do motorista (**Abbiamo Go**).

O fluxo garante que a inteligência de roteirização do TMS seja refletida fielmente no app: o TMS define a rota e escala o motorista; a Abbiamo recebe os dados e os exibe no aplicativo; o motorista executa a entrega; e a Abbiamo notifica o TMS sobre cada mudança de status.

---

## Autenticação

Todas as requisições devem conter o header de autenticação do seller group:

| Header | Descrição |
|---|---|
| `x-abbiamo-seller-group-key` | Chave fornecida pela Abbiamo para identificar e autorizar o seller group. |

- **Base URL:** `https://api.abbiamo.io`
- **Rate limit:** 1500 requisições a cada 5 minutos.

---

## Fluxo de integração

```
TMS                →   Abbiamo API   →   Abbiamo Go App
Define rota            Cria pedidos       Motorista visualiza
e motorista            e vincula à        e executa a rota
                       rota no app

                   ←   Webhooks
                       Notifica o TMS sobre
                       mudanças de status
```

---

## Criar rota com pedidos

**`POST /v2/orders/route`**

Cria os pedidos e a rota de uma só vez, já vinculando o motorista. Limite de **50 pedidos por rota**.

Referência oficial: [Create route for new orders](https://abbiamo.readme.io/reference/create-route-for-new-orders)
**Guarde o route.id:** Salve o `route.id` retornado na resposta — ele é necessário para operações de cancelamento ou troca de motorista.

### Campos do objeto `orders[]`

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `order_number` | string | Sim | Identificador do pedido no TMS. |
| `seller_identifier` | string | Sim | CNPJ ou identificador da filial (seller) de origem do pedido. |
| `customer.name` | string | Sim | Nome do destinatário. |
| `destination_address.zip_code` | string | Sim | CEP do endereço de entrega (apenas números). |
| `destination_address.state` | string | Sim | UF do estado de entrega (ex: `SP`). |
| `destination_address.city` | string | Sim | Cidade de entrega. |
| `destination_address.street` | string | Sim | Logradouro de entrega. |
| `destination_address.street_number` | string | Sim | Número do endereço de entrega. |

### Campos do objeto `route`

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `driver_document` | string | Não | CPF do motorista responsável pela rota. Se não informado, a rota é criada sem motorista e pode ser atribuída depois pelo dashboard. |
| `external_name` | string | Não | Nome externo da rota (identificador do TMS). |
| `orders_sequenced` | boolean | Não | Se `true`, a Abbiamo respeita a ordem exata do array `orders`. Use quando o TMS já definiu a sequência otimizada. |
| `start.type` | string | Não | Tipo do ponto de partida. Use `WAREHOUSE_SELLER_IDENTIFIER` para partir de uma filial. |
| `start.value` | string | Não | Identificador da filial de partida (CNPJ ou seller identifier). |
| `end.type` | string | Não | Tipo do ponto de chegada. Use `WAREHOUSE_SELLER_IDENTIFIER` para retornar a uma filial. |
| `end.value` | string | Não | Identificador da filial de chegada (CNPJ ou seller identifier). |

### Exemplo de requisição

```json
{
  "orders": [
    {
      "order_number": "PEDIDO-001",
      "seller_identifier": "71955998000126",
      "customer": { "name": "Cliente Exemplo" },
      "destination_address": {
        "zip_code": "01412100",
        "state": "SP",
        "city": "São Paulo",
        "street": "Rua Exemplo",
        "street_number": "100"
      }
    }
  ],
  "route": {
    "driver_document": "05217304065",
    "external_name": "ROTA_SUL_0502",
    "orders_sequenced": true,
    "start": {
      "type": "WAREHOUSE_SELLER_IDENTIFIER",
      "value": "71955998000126"
    },
    "end": {
      "type": "WAREHOUSE_SELLER_IDENTIFIER",
      "value": "71955998000126"
    }
  }
}
```

### Exemplo de resposta

```json
{
  "status": "success",
  "route": {
    "id": "1d1dfa9c-4fe2-4315-9d65-ec0e8f95d239",
    "cost": 1200
  },
  "orders": [
    {
      "id": "30c24480-8e45-4afa-af35-0231b460e9ed",
      "order_number": "PEDIDO-001",
      "tracking": "abc123#",
      "already_exists": false,
      "mail_label_link": "https://mail-label-api.abbiamo.io/mail-label/v1?trackings=abc123#",
      "tracking_link": "http://meupedido.abbiamolog.com/abc123#"
    }
  ]
}
```

O campo `already_exists` indica se o pedido já existia no sistema e foi apenas vinculado à rota (sem ser recriado).

---

## Trocar motorista da rota

**`PATCH /v1/routes/{route_id}/change-driver`**

Atribui um novo motorista a uma rota já criada. A rota deve estar com status `CREATED`.

```json
{
  "document_number": "17027297623"
}
```

Para mais detalhes, consulte a [referência completa de Rotas](https://abbiamo-guide.netlify.app/tms/rotas).

---

## Cancelar rota

**`PUT /v1/routes/{route_id}`**

Cancela a rota. Os pedidos vinculados retornam ao estado pendente. A rota deve estar com status `CREATED`.

Para mais detalhes, consulte a [referência completa de Rotas](https://abbiamo-guide.netlify.app/tms/rotas).

---

## Gestão de motoristas

Motoristas são vinculados a uma ou mais filiais (sellers). Para que um motorista visualize rotas no app, ele precisa estar associado ao `seller_identifier` correto.

Os endpoints disponíveis são:

| Endpoint | Descrição |
|---|---|
| `POST /v1/drivers` | Cria ou atualiza um motorista. |
| `GET /v1/drivers` | Lista motoristas do seller group (paginado). |
| `GET /v1/drivers/{document_number}` | Retorna os dados de um motorista específico. |

Para mais detalhes, consulte a [referência completa de Motoristas](https://abbiamo-guide.netlify.app/tms/motoristas).

---

## Webhooks de status

A cada mudança no status de um pedido, a Abbiamo envia um `POST` para a URL configurada no TMS.

| Status | Descrição |
|---|---|
| `CREATED` | Pedido recebido no sistema. |
| `DISPATCHED` | Rota planejada e enviada ao app do motorista. |
| `START_DELIVERY` | Motorista iniciou o deslocamento para o cliente. |
| `SUCCESSFUL` | Entrega realizada com sucesso. |
| `FAILED` | Falha na entrega. |

---

## Regras de negócio

- **Idempotência de pedidos:** se o `order_number` já existir e não estiver finalizado, a Abbiamo apenas vincula o pedido à nova rota, sem recriar.
- **Sequenciamento:** se o TMS já define a ordem otimizada, sempre envie `"orders_sequenced": true`.
- **Limite de rota:** rotas com mais de 50 pedidos não são aceitas.
- **Filiais (Sellers):** certifique-se de que as filiais foram criadas antes de criar rotas — o `seller_identifier` deve existir no seller group autenticado.