# Crear servicios

> Cómo crear un servicio con piezas desde su sistema, enviarlo a optimización y seguir el resultado por webhook.

URL canónica: https://apis.cortecloud.com.br/docs/es/guias/integracao-erp/criar-servico/

Su integración puede crear un [servicio](https://apis.cortecloud.com.br/docs/es/comecando/conceitos.md#servico) de la central con las piezas ya definidas en su sistema. Cortecloud registra al carpintero, completa las piezas, envía el servicio a optimización y genera el presupuesto, como en un servicio creado por la app.

Ruta: [`POST /services`](https://apis.cortecloud.com.br/docs/swagger#/Services/createService). Exige autenticación por central ([HMAC](https://apis.cortecloud.com.br/docs/es/comecando/autenticacao.md)); con autenticación Basic, responde `401`.

## Cuerpo {#corpo}

```json
{
  "serviceInternalCode": "PED-123",
  "productionInternalCode": "LINHA-1",
  "carpenterEmail": "carpintero@example.com",
  "carpenterName": "Fulano Carpintero",
  "carpenterInternalCode": "CLI-9",
  "parts": [
    {
      "quantity": 1,
      "c": 500,
      "l": 500,
      "function": "Lateral",
      "complement": "Balcao A",
      "client": "Ana",
      "furniture": "Cocina",
      "material": { "internalCode": "MDF18BR" },
      "c1": { "internalCode": "FT04BR" },
      "c2": null,
      "l1": null,
      "l2": null,
      "machining": {
        "x": 500,
        "y": 500,
        "z": 18,
        "startSide": 0,
        "horizontalDrills": [],
        "verticalDrills": [
          { "corner": 0, "bolthole": false, "x": 25, "y": 37, "depth": 12, "diameter": 15, "face": "i" }
        ],
        "furrowMachining": null,
        "furrowMachiningPair": null
      }
    }
  ]
}
```

| Campo | Regla |
| --- | --- |
| `serviceInternalCode` | [Código interno](https://apis.cortecloud.com.br/docs/es/comecando/conceitos.md#codigo-interno) del servicio, normalmente el número del pedido en el ERP. Opcional, hasta 255 caracteres. Vuelve en los webhooks como `service_internal_code`. |
| `productionInternalCode` | Código interno de la línea de producción. Obligatorio. |
| `carpenterEmail`, `carpenterName` | Correo electrónico y nombre del carpintero. Obligatorios. |
| `carpenterInternalCode` | Código del carpintero (cliente) en su sistema. Obligatorio. |
| `parts` | Piezas del servicio, de 1 a 500. |

Antes de crear el servicio, la ruta registra al carpintero en Cortecloud, si todavía no existe, y lo vincula con la central con `carpenterInternalCode`, como en el [inicio de sesión integrado](https://apis.cortecloud.com.br/docs/es/guias/login-embutido.md#novo-servico-para-um-vendedor). Si el carpintero ya tiene un vínculo activo con la central, se mantiene el código interno de ese vínculo. Si `carpenterEmail` ya pertenece a un usuario de otro perfil (por ejemplo, un vendedor), pasa a ser carpintero y pierde el perfil anterior.

### Piezas {#pecas}

`parts` sigue la [estructura de la importación por archivo JSON](https://apis.cortecloud.com.br/docs/es/guias/importacao-json.md#estrutura-do-arquivo): los mismos campos, las medidas en milímetros y el mismo objeto `machining`, descrito en [Mecanizado](https://apis.cortecloud.com.br/docs/es/guias/importacao-json.md#usinagem). Las diferencias están en los materiales y en la validación:

| Campo | En la importación | Aquí |
| --- | --- | --- |
| `material` | Nombre del tablero en su sistema. | Tablero de la pieza: `{ "internalCode": "..." }`, con el código interno del tablero en la central. Obligatorio. |
| `client`, `furniture` | No existen: el carpintero elige el cliente en la importación. | Cliente del carpintero y ambiente de la pieza (por ejemplo, "Cocina"), hasta 255 caracteres cada uno. Opcionales: las piezas con el mismo par quedan en el mismo cliente del servicio, y las piezas sin ellos quedan en un cliente sin nombre. |
| `c1`, `c2`, `l1`, `l2` | Nombre del tapacanto. | `{ "internalCode": "..." }` con el código interno del tapacanto en la central. Lado sin tapacanto: `null` o ausente. |
| `quantity`, `c`, `l` | La pieza con valor ausente, cero o negativo se descarta. | Un valor ausente, cero o negativo responde `400`. `c` y `l` llegan hasta 9999.99. |

Los códigos internos de tablero y tapacanto, `function` y `complement` tienen hasta 255 caracteres; por encima, la ruta responde `400`.

Como los materiales llegan por el código interno, no existe la etapa de [vínculo de materiales](https://apis.cortecloud.com.br/docs/es/guias/importacao-json.md#vinculo-de-materiais) de la importación.

Valen las mismas reglas de la importación:

- `function` vacío se convierte en "Peça".
- El mecanizado solo se aplica si la línea de producción tiene máquina de mecanizado (ver [Cuando la línea de producción no mecaniza](https://apis.cortecloud.com.br/docs/es/guias/importacao-json.md#quando-a-linha-de-producao-nao-usina)).
- Cada pieza usa como máximo dos tapacantos diferentes. Si la central no acepta dos tapacantos por pieza, los lados con el segundo tapacanto quedan sin tapacanto.

No hay campo para la rotación de la pieza: puede girar en el plano de corte cuando el tablero no tiene veta.

## Respuesta y seguimiento {#resposta-e-acompanhamento}

La respuesta `202` trae el `id` del servicio:

```json
{ "id": 98765 }
```

El `202` confirma el formato del cuerpo y el registro del carpintero. Materiales, línea de producción y piezas se validan después, de forma asíncrona: un código de tablero inexistente, por ejemplo, no cambia la respuesta. El resultado llega por [webhook](https://apis.cortecloud.com.br/docs/es/guias/webhooks.md#criacao-de-servico):

- `service.created`: el servicio fue creado y las piezas fueron guardadas (estado `1`);
- `service.creation_failed`: la creación falló, y `errors` trae los motivos.

El `service.created` sale después de que el servicio se envía a optimización. Cuando el presupuesto está listo, llega el `service.quoted`. Si el envío es rechazado, por ejemplo por una pieza más grande que el tablero, llega `service.creation_failed` con los motivos. Para recibir los tres, solicite el registro de destinos para cada tipo (ver [Cómo activarlo](https://apis.cortecloud.com.br/docs/es/guias/webhooks.md#como-ativar)).

Mientras Cortecloud completa las piezas, el servicio queda bloqueado para edición en las apps.

### Ids de las piezas {#ids-das-pecas}

El presupuesto y las piezas están en [`GET /services/{id}`](https://apis.cortecloud.com.br/docs/swagger#/Services/getService). `parts[].id` es el id de cada pieza en Cortecloud: úselo para correlacionar las piezas con su sistema, por ejemplo con el `DrillCode` de los mecanizados.

## Lo que ve el carpintero {#o-que-o-marceneiro-ve}

El servicio pertenece a la central y queda asociado al carpintero. Aparece en el Cortecloud del carpintero a partir del estado aprobado (`6`), solo para lectura.

## Errores {#erros}

| Estado | Cuándo |
| --- | --- |
| `400` | Cuerpo fuera del formato: campo obligatorio ausente, correo electrónico inválido, `parts` vacío o con más de 500 piezas, pieza sin `material`, cantidad o medida no positiva, `machining` fuera del formato de la importación. |
| `401` | Autenticación Basic. La ruta exige HMAC. |

Los errores en los materiales, en la línea de producción o en las piezas, incluida una pieza más grande que el tablero, llegan por el `service.creation_failed`, no en la respuesta.

:::caution Nuevo intento después de un timeout
`serviceInternalCode` no pasa por control de duplicados. Si la respuesta se pierde y su integración repite la llamada, Cortecloud puede crear el servicio dos veces.
:::
