Pular para o conteúdo principal

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.

CampoValores
periodicity1 = Mensal, 2 = Anual
contractType1 = Por serviço (PerService), 2 = Por tempo (PerTime)
Contrato por serviço vs por tempo

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

EndpointPara quê
GET /gateway/entity-contract?page=&pageSize=Listagem paginada
GET /gateway/entity-contract/{id}Detalhe
GET /gateway/entity-contract/{id}/hours-availableHoras ainda disponíveis (totalHours, availableHours, contractType)
GET /gateway/entity-contract/{id}/has-documentsVerificar dependências antes de apagar
GET /gateway/entity-contract/next-idPróximo número livre
GET /gateway/intervention/by-contract/{contractId}Intervenções imputadas ao contrato
Apagar contratos em uso

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.