Passo 4 — Abrir a ordem de serviço
A ordem de serviço é a ficha de oficina: liga o equipamento, o cliente, a avaria, o planeamento e as linhas facturáveis (peças e serviços a debitar).
Criar
POST /gateway/service-order
Content-Type: application/json
Authorization: Bearer {token}
{
"series": 2026,
"status": "RECEB",
"priority": "URG",
"assistanceTypeKeyId": "REP",
"equipmentId": 123,
"entityKeyId": "C0001",
"designation": "Não liga - suspeita de fonte",
"breakdownDescription": "Cliente reporta que o equipamento não liga desde 10/08.",
"deliveryForecast": "2026-08-20T18:00:00Z",
"formatEquipment": false,
"backupEquipment": true,
"details": [
{
"itemKeyId": "SCREEN-7420",
"itemDescription": "Painel LCD de substituição",
"quantity": 1,
"retailPrice": 180.00,
"serialNumber": "SN-LCD-0099"
},
{
"itemKeyId": "MO-HORA",
"itemDescription": "Mão de obra por hora",
"quantity": 2,
"netPrice": 20.00
}
]
}
Resposta: 201 Created com o número atribuído.
Obrigatórios (validação da API): status, priority, assistanceTypeKeyId — os três têm de existir nos catálogos (Passos 1.2 e 1.3) — e series ≥ 1. Se a configuração SAT tiver isEmployeeFillObligatory, o responsibleUserId (> 0) também é obrigatório.
Recomendados: equipmentId, entityKeyId, designation, breakdownDescription.
Passo 4.1 — As linhas facturáveis (details)
É o details que dá conteúdo ao documento: cada linha é uma peça ou serviço a debitar e é ela que aparece na pré-visualização da facturação. As linhas de comentário que a pré-visualização acrescenta ("Intervenção Nº 46", "Horas Gastas") são apenas cabeçalhos de agrupamento, sem valor.
Se a ordem não tiver details e as intervenções ligadas não tiverem horas nem km valorizados, a pré-visualização devolve 400 ServiceOrderInvoice.NothingToInvoice (ou InterventionInvoice.NothingToInvoice no caso da intervenção isolada). E um documento que chegue à emissão apenas com linhas de comentário é rejeitado com Invoice.Details.OnlyComments.
O objecto details é o mesmo na ordem de serviço e na intervenção. Por linha, basta enviar três coisas — o resto é completado pela API:
| Campo | Quem preenche |
|---|---|
itemKeyId | Integrador. Obrigatório; o artigo tem de existir no catálogo de artigos |
quantity | Integrador. Tem de ser > 0 |
retailPrice ou netPrice | Integrador envia um; a API deriva o outro a partir da taxa de imposto |
taxId | Opcional. Se vier a 0 ou omitido, assume o imposto do artigo |
taxValue | API (taxa do imposto correspondente ao taxId) |
itemGroupId | API (grupo do artigo) |
guid | API gera quando vem vazio. Reenvie-o no PUT para preservar a linha |
itemDescription, itemType, serialNumber, imei | Integrador, opcionais |
invoiced | Só leitura: indica que a linha já está referenciada por um documento emitido |
Regras e erros:
- Linhas com
quantity≤ 0 são descartadas em silêncio — não há erro, simplesmente não são gravadas. - Quantidade > 0 sem
itemKeyId→ 400ServiceOrder.InvalidDetailItemKeyId/Intervention.InvalidDetailItemKeyId. itemKeyIdque não existe no catálogo → 404ServiceOrder.ItemNotFound/Intervention.ItemNotFound.- No PUT (da ordem ou da intervenção) o
detailsé substituição integral: as linhas actuais são removidas e recriadas a partir da lista enviada. Reenvie as que quer manter, com o respectivoguid. - Numa ordem de serviço, remover uma linha já facturada devolve 409
ServiceOrder.CannotRemoveInvoicedDetail.
Rastreabilidade na facturação: cada linha facturável origina uma linha da pré-visualização com o originBodyGuid igual ao guid da linha e o relationType correspondente — ServiceOrder (4) para linhas da própria ordem e ServiceOrderIntervention (5) para linhas de intervenção. As horas e os km usam o GUID da intervenção como origem, com ServiceOrderInterventionHours (9) e ServiceOrderInterventionKms (8). Em orçamento, todas passam a ServiceOrderQuote (24).
Consultas úteis
| Endpoint | Para quê |
|---|---|
GET /service-order?page=1&pageSize=20 | Listagem paginada |
GET /service-order/{guid} | Detalhe por GUID |
GET /service-order/{series}/{number} | Detalhe por série+número (o que o cliente lê no talão) |
GET /service-order/next-number/{series} | Próximo número da série |
GET /service-order/{guid}/issued-documents | Documentos já emitidos a partir desta ordem |
GET /service-order/{guid}/has-invoice | Já foi faturada? |
O status de uma ordem muda-se pelo PUT /service-order/{guid} (campo status + stateChangeReason se o estado exigir motivo). O histórico de mudanças de estado é registado automaticamente.
Depois de criar a ordem, registe intervenções. Quando o trabalho estiver concluído, feche a ordem como abaixo.
Fecho
O fecho tem um endpoint de pré-visualização — use-o sempre antes do fecho para saber o que vai acontecer (intervenções abertas, orçamentos pendentes).
Pré-visualizar o fecho (não altera nada):
GET /gateway/service-order/GUID-DA-ORDEM/close-preview
Authorization: Bearer {token}
Fechar:
POST /gateway/service-order/GUID-DA-ORDEM/close
Content-Type: application/json
Authorization: Bearer {token}
{
"reason": "Reparação concluída e testada",
"concludeOpenInterventions": true
}
concludeOpenInterventions: true é obrigatório quando existem intervenções abertas — sem ele o fecho devolve 409 Conflict.
Reabrir
POST /service-order/{guid}/reopen (body opcional com reason). A mudança fica no histórico de estados.
Seguinte
Faturação (dois tempos: preview + emissão genérica).