Passo 2 — Contratos de assistência
Opcional, mas define como as horas são faturadas. Um contrato dá ao cliente um plafond de horas que as intervenções vão consumindo.
Hierarquia
entity-contract-group → agrupamento comercial
entity-contract-type → periodicidade, renovável, tipo de serviço
entity-contract → contrato do cliente, com totalHours (plafond)
Crie sempre pela ordem acima: o contrato valida que o grupo e o tipo já existem.
2.1 Grupo de contratos
POST /gateway/entity-contract-group
Content-Type: application/json
Authorization: Bearer {token}
{
"id": 1,
"description": "Avenças anuais"
}
Obrigatórios: id (numérico, definido pelo utilizador, > 0) e description (≤50 car.).
Próximo número livre: GET /gateway/entity-contract-group/next-id.
2.2 Tipo de contrato
POST /gateway/entity-contract-type
Content-Type: application/json
Authorization: Bearer {token}
{
"id": 1,
"description": "Avença mensal por tempo",
"renewable": true,
"periodicity": 1,
"contractType": 2
}
Obrigatórios: id (> 0), description (≤50 car.), periodicity e contractType. Opcional: renewable.
| Campo | Valores |
|---|---|
periodicity | 1 = Mensal, 2 = Anual |
contractType | 1 = Por serviço (PerService), 2 = Por tempo (PerTime) |
O contractType decide se o plafond de horas é relevante: em contratos por serviço não há validação de horas; apenas os contratos por tempo consomem plafond. O endpoint hours-available devolve este valor para o integrador poder ignorar a validação quando aplicável.
2.3 Contrato do cliente
POST /gateway/entity-contract
Content-Type: application/json
Authorization: Bearer {token}
{
"id": 1,
"entityKeyId": "C0001",
"contractGroupId": 1,
"contractTypeId": 1,
"startDate": "2026-01-01T00:00:00Z",
"endDate": "2026-12-31T00:00:00Z",
"totalHours": 40,
"contractValue": 1200.00,
"contractValueRp": 1200.00,
"contractCostValue": 800.00,
"observation": "Avença de manutenção preventiva, 40h/ano.",
"canceled": false
}
Obrigatórios: id (> 0), entityKeyId (≤25 car., o cliente tem de existir), contractGroupId, contractTypeId, startDate e endDate (fim não pode ser anterior ao início — InvalidDateRange).
Opcionais úteis: totalHours, contractValue, contractValueRp, contractCostValue, observation (≤4000 car.), covenantId (≤50 car.; se enviado, o acordo tem de existir) e canceled.
Próximo número livre: GET /gateway/entity-contract/next-id.
Endpoints relevantes
| Endpoint | Para quê |
|---|---|
GET /gateway/entity-contract?page=&pageSize= | Listagem paginada |
GET /gateway/entity-contract/{id} | Detalhe |
GET /gateway/entity-contract/{id}/hours-available | Horas ainda disponíveis (totalHours, availableHours, contractType) |
GET /gateway/entity-contract/{id}/has-documents | Verificar dependências antes de apagar |
GET /gateway/entity-contract/next-id | Próximo número livre |
GET /gateway/intervention/by-contract/{contractId} | Intervenções imputadas ao contrato |
Apagar um contrato com ordens ou intervenções associadas devolve erro (InUse). Verifique primeiro com has-documents.
Como o plafond é consumido
A intervenção liga-se ao contrato por entityContractId e o campo discountTime (horas) é debitado ao contrato. Quando essas horas são efectivamente faturadas, é criada uma referência de documento do tipo ServiceOrderInterventionHours a apontar para a intervenção — ou seja, horas faturadas voltam a libertar plafond, porque deixaram de ser consumo de contrato para passar a ser venda.
Horas disponíveis = totalHours - (horas gastas - horas já faturadas).
Seguinte
Registar o equipamento do cliente.