Validation d'un Cycle
Endpoints pour gérer le workflow de validation multi-niveaux des cycles de paiement.
Niveaux de validation
| Niveau | Rôle | Description |
|---|---|---|
| 0 | Non soumis | Cycle en préparation (brouillon) |
| 1 | Agent | Validation initiale |
| 2 | Superviseur | Validation intermédiaire |
| 3 | Directeur | Validation avancée |
| 4 | Direction Générale | Validation finale |
Le nombre de niveaux requis est configurable par programme (par défaut: 2).
POST /api/cycles/{id}/soumettre
Soumet le cycle pour validation.
Endpoint
POST /api/cycles/{id}/soumettre
Headers
| Header | Valeur | Requis |
|---|---|---|
| Authorization | Bearer {token} | Oui |
Prérequis
- Le cycle doit être en statut
brouillon - Le cycle doit avoir des bénéficiaires calculés
Réponse succès
Code: 200 OK
{
"success": true,
"statutValidation": "en_attente",
"niveauValidation": 0,
"prochainNiveau": "Agent",
"message": "Cycle soumis pour validation"
}
Exemple 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
Valide le cycle au niveau actuel.
Endpoint
POST /api/cycles/{id}/valider
Corps de la requête
{
"commentaire": "Validé après vérification des bénéficiaires"
}
Champs
| Champ | Type | Requis | Description |
|---|---|---|---|
| commentaire | string | Non | Commentaire de validation |
Réponse succès
Code: 200 OK
{
"success": true,
"statutValidation": "valide",
"niveauValidation": 2,
"niveauxRequis": 2,
"estCompletementValide": true,
"message": "Cycle validé - Validation complète"
}
Réponse succès (validation partielle)
{
"success": true,
"statutValidation": "en_attente",
"niveauValidation": 1,
"niveauxRequis": 2,
"estCompletementValide": false,
"prochainNiveau": "Superviseur",
"message": "Cycle validé au niveau Agent - En attente validation Superviseur"
}
Exemple 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
Rejette le cycle.
Endpoint
POST /api/cycles/{id}/rejeter
Corps de la requête
{
"motif": "Incohérence dans le nombre de bénéficiaires"
}
Champs
| Champ | Type | Requis | Description |
|---|---|---|---|
| motif | string | Oui | Motif du rejet |
Réponse succès
Code: 200 OK
{
"success": true,
"statutValidation": "rejete",
"niveauValidation": 1,
"message": "Cycle rejeté"
}
Exemple 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
Récupère l'historique des validations du cycle.
Endpoint
GET /api/cycles/{id}/historique-validations
Réponse succès
Code: 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
Réinitialise la validation (retour au statut brouillon).
Endpoint
POST /api/cycles/{id}/reinitialiser-validation
Prérequis
- Le cycle ne doit pas être en cours d'exécution
- Permission spéciale requise
Réponse succès
Code: 200 OK
{
"success": true,
"statutValidation": "brouillon",
"niveauValidation": 0,
"message": "Validation réinitialisée"
}
Exemples complets
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();
}
}
// Utilisation - Workflow complet
const api = new CycleValidationAPI(token);
const cycleId = '770e8400-e29b-41d4-a716-446655440003';
// 1. Soumettre
await api.soumettre(cycleId);
// 2. Validation niveau 1
let result = await api.valider(cycleId, 'Validé par Agent');
console.log(`Niveau: ${result.niveauValidation}/${result.niveauxRequis}`);
// 3. Validation niveau 2 (si requis)
if (!result.estCompletementValide) {
result = await api.valider(cycleId, 'Validé par Superviseur');
}
// Vérifier l'historique
const historique = await api.getHistorique(cycleId);
historique.historique.forEach(entry => {
console.log(`${entry.date}: ${entry.action} par ${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()
# Utilisation
api = CycleValidationAPI(token)
# Workflow de validation
api.soumettre(cycle_id)
# Valider jusqu'à complétion
while True:
result = api.valider(cycle_id, 'Validation automatique')
print(f"Niveau {result['niveauValidation']}/{result['niveauxRequis']}")
if result['estCompletementValide']:
print("Cycle complètement validé!")
break
# Afficher l'historique
historique = api.get_historique(cycle_id)
for entry in historique['historique']:
print(f"- {entry['niveauLabel']}: {entry['action']} par {entry['userName']}")
Diagramme de workflow
┌─────────────┐ POST /soumettre ┌─────────────┐
│ brouillon │ ──────────────────────▶ │ en_attente │
└─────────────┘ └──────┬──────┘
│
POST /valider │ POST /rejeter
┌────────────────┼────────────────┐
│ │ │
▼ │ ▼
┌─────────────┐ │ ┌───────────┐
│ Niveau N │ │ │ rejete │
│ validé │ │ └───────────┘
└──────┬──────┘ │
│ │
niveauValidation │ │
< niveauxRequis │ │
│ │
┌──────┴──────┐ │
│ │ │
▼ ▼ │
┌─────────────┐ ┌─────────┐ │
│ en_attente │ │ valide │ │
│ niveau N+1 │ │ complet │ │
└─────────────┘ └─────────┘ │
│ │
└────────────────────────┘
Notes
- La validation est multi-niveaux et configurable
- Chaque niveau nécessite un utilisateur avec les permissions appropriées
- L'historique complet des validations est conservé
- Un cycle rejeté peut être modifié et re-soumis
- Le nombre de niveaux requis est défini à la création du cycle