Pular para o conteúdo principal

Validacao de um Ciclo

Endpoints para gerir o fluxo de validacao multi-nivel dos ciclos de pagamento.

Niveis de Validacao

NivelFuncaoDescricao
0Nao submetidoCiclo em preparacao (rascunho)
1AgenteValidacao inicial
2SupervisorValidacao intermédia
3DiretorValidacao avancada
4Direcao GeralValidacao final

O numero de niveis necessarios e configuravel por programa (por defeito: 2).


POST /api/cycles/{id}/soumettre

Submete o ciclo para validacao.

Endpoint

POST /api/cycles/{id}/soumettre

Cabecalhos

CabecalhoValorObrigatorio
AuthorizationBearer {token}Sim

Pre-requisitos

  • O ciclo deve estar no estado brouillon
  • O ciclo deve ter beneficiarios calculados

Resposta de Sucesso

Codigo: 200 OK

{
"success": true,
"statutValidation": "en_attente",
"niveauValidation": 0,
"prochainNiveau": "Agent",
"message": "Cycle soumis pour validation"
}

Exemplo cURL

curl -X POST https://sig.ucp-pch.org/api/cycles/770e8400-e29b-41d4-a716-446655440003/soumettre \
-H "Authorization: Bearer TOKEN"

POST /api/cycles/{id}/valider

Valida o ciclo no nivel atual.

Endpoint

POST /api/cycles/{id}/valider

Corpo do Pedido

{
"commentaire": "Validé après vérification des bénéficiaires"
}

Campos

CampoTipoObrigatorioDescricao
commentairestringNaoComentario de validacao

Resposta de Sucesso

Codigo: 200 OK

{
"success": true,
"statutValidation": "valide",
"niveauValidation": 2,
"niveauxRequis": 2,
"estCompletementValide": true,
"message": "Cycle validé - Validation complète"
}

Resposta de Sucesso (validacao parcial)

{
"success": true,
"statutValidation": "en_attente",
"niveauValidation": 1,
"niveauxRequis": 2,
"estCompletementValide": false,
"prochainNiveau": "Superviseur",
"message": "Cycle validé au niveau Agent - En attente validation Superviseur"
}

Exemplo cURL

curl -X POST https://sig.ucp-pch.org/api/cycles/770e8400-e29b-41d4-a716-446655440003/valider \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"commentaire": "Validé"}'

POST /api/cycles/{id}/rejeter

Rejeita o ciclo.

Endpoint

POST /api/cycles/{id}/rejeter

Corpo do Pedido

{
"motif": "Incohérence dans le nombre de bénéficiaires"
}

Campos

CampoTipoObrigatorioDescricao
motifstringSimMotivo da rejeicao

Resposta de Sucesso

Codigo: 200 OK

{
"success": true,
"statutValidation": "rejete",
"niveauValidation": 1,
"message": "Cycle rejeté"
}

Exemplo cURL

curl -X POST https://sig.ucp-pch.org/api/cycles/770e8400-e29b-41d4-a716-446655440003/rejeter \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"motif": "Incohérence dans le nombre de bénéficiaires"}'

GET /api/cycles/{id}/historique-validations

Obtem o historico de validacoes do ciclo.

Endpoint

GET /api/cycles/{id}/historique-validations

Resposta de Sucesso

Codigo: 200 OK

{
"cycle": {
"id": "770e8400-e29b-41d4-a716-446655440003",
"code": "CYC-2024-003",
"nom": "Cycle Mars 2024"
},
"statutValidation": "valide",
"niveauValidation": 2,
"niveauxRequis": 2,
"historique": [
{
"action": "soumission",
"niveau": 0,
"niveauLabel": "Non soumis",
"user": "agent@pch-sig.sn",
"userName": "Agent Terrain",
"date": "2024-02-20T10:00:00+00:00",
"commentaire": null
},
{
"action": "validation",
"niveau": 1,
"niveauLabel": "Agent",
"user": "superviseur@pch-sig.sn",
"userName": "Superviseur PCH",
"date": "2024-02-20T11:00:00+00:00",
"commentaire": "Conforme"
},
{
"action": "validation",
"niveau": 2,
"niveauLabel": "Superviseur",
"user": "directeur@pch-sig.sn",
"userName": "Directeur PCH",
"date": "2024-02-20T14:00:00+00:00",
"commentaire": "Approuvé pour exécution"
}
]
}

POST /api/cycles/{id}/reinitialiser-validation

Reinicializa a validacao (retorna ao estado rascunho).

Endpoint

POST /api/cycles/{id}/reinitialiser-validation

Pre-requisitos

  • O ciclo nao pode estar em execucao
  • Permissao especial necessaria

Resposta de Sucesso

Codigo: 200 OK

{
"success": true,
"statutValidation": "brouillon",
"niveauValidation": 0,
"message": "Validation réinitialisée"
}

Exemplos Completos

JavaScript

class CycleValidationAPI {
constructor(token) {
this.token = token;
this.baseUrl = 'https://sig.ucp-pch.org/api';
}

async getCycle(cycleId) {
const response = await fetch(
`${this.baseUrl}/cycles/${cycleId}`,
{
headers: { 'Authorization': `Bearer ${this.token}` }
}
);
return response.json();
}

async soumettre(cycleId) {
const response = await fetch(
`${this.baseUrl}/cycles/${cycleId}/soumettre`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${this.token}` }
}
);
return response.json();
}

async valider(cycleId, commentaire = null) {
const response = await fetch(
`${this.baseUrl}/cycles/${cycleId}/valider`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ commentaire })
}
);
return response.json();
}

async rejeter(cycleId, motif) {
const response = await fetch(
`${this.baseUrl}/cycles/${cycleId}/rejeter`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ motif })
}
);
return response.json();
}

async getHistorique(cycleId) {
const response = await fetch(
`${this.baseUrl}/cycles/${cycleId}/historique-validations`,
{
headers: { 'Authorization': `Bearer ${this.token}` }
}
);
return response.json();
}
}

// Utilizacao - Fluxo completo
const api = new CycleValidationAPI(token);
const cycleId = '770e8400-e29b-41d4-a716-446655440003';

// 1. Submeter
await api.soumettre(cycleId);

// 2. Validacao nivel 1
let result = await api.valider(cycleId, 'Validado pelo Agente');
console.log(`Nivel: ${result.niveauValidation}/${result.niveauxRequis}`);

// 3. Validacao nivel 2 (se necessario)
if (!result.estCompletementValide) {
result = await api.valider(cycleId, 'Validado pelo Supervisor');
}

// Verificar historico
const historique = await api.getHistorique(cycleId);
historique.historique.forEach(entry => {
console.log(`${entry.date}: ${entry.action} por ${entry.userName}`);
});

Python

import requests

class CycleValidationAPI:
def __init__(self, token):
self.token = token
self.base_url = 'https://sig.ucp-pch.org/api'
self.headers = {'Authorization': f'Bearer {token}'}

def soumettre(self, cycle_id):
response = requests.post(
f'{self.base_url}/cycles/{cycle_id}/soumettre',
headers=self.headers
)
return response.json()

def valider(self, cycle_id, commentaire=None):
response = requests.post(
f'{self.base_url}/cycles/{cycle_id}/valider',
headers={**self.headers, 'Content-Type': 'application/json'},
json={'commentaire': commentaire}
)
return response.json()

def rejeter(self, cycle_id, motif):
response = requests.post(
f'{self.base_url}/cycles/{cycle_id}/rejeter',
headers={**self.headers, 'Content-Type': 'application/json'},
json={'motif': motif}
)
return response.json()

def get_historique(self, cycle_id):
response = requests.get(
f'{self.base_url}/cycles/{cycle_id}/historique-validations',
headers=self.headers
)
return response.json()

# Utilizacao
api = CycleValidationAPI(token)

# Fluxo de validacao
api.soumettre(cycle_id)

# Validar ate conclusao
while True:
result = api.valider(cycle_id, 'Validacao automatica')
print(f"Nivel {result['niveauValidation']}/{result['niveauxRequis']}")
if result['estCompletementValide']:
print("Ciclo completamente validado!")
break

# Mostrar historico
historique = api.get_historique(cycle_id)
for entry in historique['historique']:
print(f"- {entry['niveauLabel']}: {entry['action']} por {entry['userName']}")

Diagrama de Fluxo

+--------------+     POST /soumettre     +--------------+
| brouillon | ----------------------> | en_attente |
+--------------+ +------+-------+
|
POST /valider | POST /rejeter
+-----------------+-----------------+
| | |
v | v
+--------------+ | +----------+
| Nivel N | | | rejete |
| validado | | +----------+
+------+-------+ |
| |
niveauValidation | |
< niveauxRequis | |
| |
+------+------+ |
| | |
v v |
+--------------+ +----------+ |
| en_attente | | valide | |
| nivel N+1 | | completo | |
+--------------+ +----------+ |
| |
+-------------------------+

Notas

  • A validacao e multi-nivel e configuravel
  • Cada nivel requer um utilizador com as permissoes apropriadas
  • O historico completo de validacoes e mantido
  • Um ciclo rejeitado pode ser modificado e re-submetido
  • O numero de niveis necessarios e definido na criacao do ciclo