Okouro doc

Les consultants déclarent les frais qu’ils avancent de leurs deniers ; les opérations les soldent. Un frais possède une catégorie, un montant brut, un montant de TVA facultatif, et un lien vers la mission à laquelle il appartient (qui détermine s’il est facturable au client). Il passe par pending, approved, paid, rejected ou cancelled.

Qui fait quoi

ActionRôle
CréerLe consultant (les siens), un administrateur, ou un chef d’équipe pour son équipe
Modifier ou annulerLe propriétaire ou un administrateur, tant que le statut est pending (annulation aussi depuis approved)
Approuver ou refuserAdministrateur ou chef d’équipe du consultant
PayerAdministrateur ou opérations

1. Créer un frais

POST /expenses HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "date": "2026-01-14",
  "category": "train",
  "description": "Client site visit",
  "amount": "120.00",
  "vat_amount": "24.00",
  "mission_id": "0190a1c2-...",
  "billable": true
}

Renvoie 201 Created avec un ExpenseResponse. Points clés :

  • amount est le montant brut ; net_amount est dérivé et renvoyé automatiquement.
  • category vaut l’une des valeurs train, taxi, fuel, tolls, meal, hotel, office_supplies, software, telephony, other.
  • billable marque le frais pour une refacturation au client ; renseignez mission_id pour le rattacher à une mission.
  • receipt est une data URL facultative (data:<mime>;base64,<data>) ; la réponse expose un booléen has_receipt, et le justificatif complet uniquement sur GET /expenses/{id}.
{
  "id": "0190a1c2-...",
  "consultant_id": "0190a1c2-...",
  "consultant_full_name": "Ada Lovelace",
  "date": "2026-01-14",
  "category": "train",
  "description": "Client site visit",
  "amount": "120.00",
  "vat_amount": "24.00",
  "net_amount": "96.00",
  "mission_id": "0190a1c2-...",
  "mission_name": "Apollo",
  "billable": true,
  "has_receipt": false,
  "status": "pending",
  "created_at": "2026-01-14T12:00:00Z"
}

Un jeton avec le rôle consultant et sans profil lié ne peut pas créer de frais (422).

2. Modifier ou annuler avant le règlement

Tant que le statut est pending, le propriétaire ou un administrateur peut modifier le frais avec PUT /expenses/{id} (mêmes champs qu’à la création). L’annulation le retire :

POST /expenses/{id}/cancel HTTP/1.1
Authorization: Bearer <access_token>

L’annulation est autorisée depuis pending ou approved, mais plus une fois paid (409 sinon).

3. Approuver ou refuser

Un responsable examine un frais en attente :

POST /expenses/{id}/approve HTTP/1.1
Authorization: Bearer <access_token>
POST /expenses/{id}/reject HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{ "reason": "No receipt attached" }

Les deux renvoient 200 OK. Agir sur un frais qui n’est pas pending renvoie 409.

4. Payer

Les opérations soldent un frais approuvé :

POST /expenses/{id}/pay HTTP/1.1
Authorization: Bearer <access_token>

Renvoie 200 OK avec status désormais paid. Payer un frais qui n’est pas approved renvoie 409.

Le récapitulatif mensuel

GET /expenses/summary agrège les totaux par statut, éventuellement pour un mois et un consultant donné :

GET /expenses/summary?month=2026-01 HTTP/1.1
Authorization: Bearer <access_token>
{
  "date_from": "2026-01-01",
  "date_to": "2026-01-31",
  "statuses": [
    { "status": "pending", "count": 3, "total": "420.00" },
    { "status": "paid", "count": 12, "total": "1850.00" }
  ]
}

Consulter les frais

GET /expenses est paginée et filtrable par consultant_id, status, category, mission_id, date_from/date_to, search et scope (mine/team). Voir Conventions.

Points d’entrée en un coup d’œil

ActionMéthodeCheminSuccès
ListerGET/expenses200
RécapitulatifGET/expenses/summary200
RécupérerGET/expenses/{id}200
CréerPOST/expenses201
ModifierPUT/expenses/{id}200
AnnulerPOST/expenses/{id}/cancel200
ApprouverPOST/expenses/{id}/approve200
RefuserPOST/expenses/{id}/reject200
PayerPOST/expenses/{id}/pay200