# Prompt p11 — Finances SYSCOHADA (web)
*Contextes requis : ctx-global.md + ctx-web-nextjs.md + ctx-laravel-bff.md*

---

## Profil & Accès
- **Rôle** : CPT (Comptable)
- **Nombre d'utilisateurs** : 2
- **Accès** : toute la comptabilité — journaux, écritures, états financiers, rapprochement bancaire
- **Session** : 8h, OTP à la connexion

---

## Fichiers à créer

```
app/(erp)/finances/page.tsx
app/(erp)/finances/journaux/page.tsx
app/(erp)/finances/journaux/[id]/page.tsx
app/(erp)/finances/ecritures/page.tsx
app/(erp)/finances/ecritures/saisie/page.tsx
app/(erp)/finances/rapprochement/page.tsx
app/(erp)/finances/etats/page.tsx
app/(erp)/finances/etats/[type]/page.tsx
components/finances/JournauxList.tsx
components/finances/GrandLivre.tsx
components/finances/BalanceComptes.tsx
components/finances/EcritureForm.tsx
components/finances/RapprochementBancaire.tsx
components/finances/BilanSYSCOHADA.tsx
components/finances/CompteResultat.tsx
components/finances/PlanComptable.tsx
hooks/useFinances.ts
hooks/useRapprochement.ts
```

---

## Spec UX condensée

```
┌─────────────────────────────────────────────────────────────────────┐
│ FLOWUP ERP          Comptabilité SYSCOHADA                  [CPT]   │
├─────────────────────────────────────────────────────────────────────┤
│ [Journaux][Écritures][Rapproch. Bancaire][États Financiers]         │
├─────────────────────────────────────────────────────────────────────┤
│                    JOURNAUX COMPTABLES                               │
│ ┌──────┬───────────────────────────┬─────────┬────────────────────┐ │
│ │ Code │ Journal                   │Écritures│ Dernière écriture  │ │
│ ├──────┼───────────────────────────┼─────────┼────────────────────┤ │
│ │  AC  │ Journal des Achats        │  1 247  │ 13/05/2026         │ │
│ │  VE  │ Journal des Ventes        │ 18 432  │ 13/05/2026         │ │
│ │  BQ  │ Journal de Banque         │    892  │ 12/05/2026         │ │
│ │  CA  │ Journal de Caisse         │  4 218  │ 13/05/2026         │ │
│ │  OD  │ Journal des OD            │    341  │ 10/05/2026         │ │
│ │  SA  │ Journal des Salaires      │    174  │ 30/04/2026         │ │
│ └──────┴───────────────────────────┴─────────┴────────────────────┘ │
│                                                                      │
│ SAISIE ÉCRITURE MANUELLE                                            │
│ Journal: [OD ▾]  Date: [13/05/2026]  Libellé: [________]           │
│ ┌────────────┬───────────────────────┬──────────┬──────────┐       │
│ │ N° Compte  │ Libellé ligne         │  Débit   │  Crédit  │       │
│ │ 601100     │ Achats carburant      │ 4 200 000│          │       │
│ │ 401000     │ Fournisseurs          │          │ 4 200 000│       │
│ │ [+ Ligne]  │                       │─────────────────────│       │
│ │            │ TOTAL                 │ 4 200 000│ 4 200 000│       │
│ └────────────┴───────────────────────┴──────────┴──────────┘       │
│ Équilibre : ✓ 0 GNF  [VALIDER L'ÉCRITURE]                          │
├─────────────────────────────────────────────────────────────────────┤
│ RAPPROCHEMENT BANCAIRE                                              │
│ [Importer OFX/CSV]   Période: Mai 2026  Banque: BGFIBank            │
│ Solde banque : 89 240 000 GNF  |  Solde comptable : 89 240 000 GNF│
│ Écart : 0 GNF ✓                                                     │
└─────────────────────────────────────────────────────────────────────┘
```

### Plan comptable SYSCOHADA
- **7 classes** : 1 Capitaux, 2 Immobilisations, 3 Stocks, 4 Tiers, 5 Trésorerie, 6 Charges, 7 Produits
- **203 comptes** configurés pour FEBI ITC SA (distribution carburant, Guinée)
- **Numérotation** : 6 chiffres (ex: 601100 = Achats carburants)

### 6 journaux
- **AC** : Achats (factures fournisseurs, auto-généré depuis réceptions)
- **VE** : Ventes (reçus pompistes, auto-généré depuis ventes)
- **BQ** : Banque (virements, relevés)
- **CA** : Caisse (espèces, Mobile Money)
- **OD** : Opérations Diverses (écritures manuelles)
- **SA** : Salaires (bulletins de paie, auto-généré depuis module RH)

### Écritures AUTO vs SAISIE
- **AUTO** : générées par les opérations ERP (vente → VE, réception → AC, paie → SA). Lecture seule, non modifiables.
- **SAISIE** : saisie manuelle dans le journal OD uniquement (pour les ajustements, dotations amortissement, etc.)

### États financiers
- **Bilan** : actif/passif au 31/12 ou à date
- **Compte de résultat** : produits - charges = résultat net
- **Balance des comptes** : débit/crédit/solde par compte
- **Grand livre** : détail des mouvements par compte

---

## Endpoints BFF

```
GET /api/comptabilite/journaux
  Réponse : [{
    code: "AC",
    libelle: "Journal des Achats",
    nb_ecritures: 1247,
    derniere_ecriture: "2026-05-13"
  }]

GET /api/comptabilite/journaux/{code}/ecritures
  Query : ?debut={YYYY-MM-DD}&fin={YYYY-MM-DD}&page={n}
  Réponse : {
    data: [{
      id: INT,
      date: "2026-05-13",
      libelle: "Achat carburant TotalGin",
      lignes: [
        { compte: "601100", libelle: "Achats carburant", debit: "4200000", credit: "0" },
        { compte: "401000", libelle: "Fournisseurs", debit: "0", credit: "4200000" }
      ],
      origine: "AUTO"|"SAISIE",
      reference_source: "REC-2026-0047"|null
    }],
    meta: { total: INT }
  }

POST /api/ecritures
  Body : {
    journal: "OD",
    date: "2026-05-13",
    libelle: "Dotation amortissement véhicules",
    lignes: [
      { compte: "681100", libelle: "DAP véhicules", debit: "1200000", credit: "0" },
      { compte: "281831", libelle: "Amort. véhicules", debit: "0", credit: "1200000" }
    ]
  }
  Réponse : { id: INT, reference: "OD-2026-0341", equilibre: true }

GET /api/comptabilite/plan-comptable
  Query : ?classe={1-7}&search={q}
  Réponse : [{ numero: "601100", libelle: "Achats carburants", classe: 6 }]

GET /api/etats-financiers/{type}
  Params : type = bilan|compte-resultat|balance|grand-livre
  Query : ?debut={YYYY-MM-DD}&fin={YYYY-MM-DD}&compte={numero}
  Réponse selon type :
    bilan : { actif: [...], passif: [...], total_actif: "...", total_passif: "..." }
    compte-resultat : { produits: [...], charges: [...], resultat_net: "..." }
    balance : [{ compte: "601100", libelle: "...", debit_cumul: "...", credit_cumul: "...", solde: "..." }]
    grand-livre : [{ compte: "601100", mouvements: [...], solde_debiteur: "...", solde_crediteur: "..." }]

POST /api/rapprochement/import
  Body : FormData { fichier: File (OFX|CSV), banque_id: INT, periode: "2026-05" }
  Réponse : { lignes_importees: INT, rapprochees: INT, non_rapprochees: INT }

GET /api/rapprochement/{periode}
  Réponse : {
    solde_banque: "89240000",       // VARCHAR
    solde_comptable: "89240000",    // VARCHAR
    ecart: "0",                     // VARCHAR
    lignes: [{
      date: "2026-05-12",
      libelle_banque: "VRT-TOTALGUIN",
      montant: "480000000",         // VARCHAR
      rapprochee: true,
      ecriture_id: INT|null
    }]
  }
```

---

## Règles spécifiques

- **RGCPT-01** : Les écritures AUTO (générées par l'ERP) sont en lecture strictement seule — pas de bouton Modifier/Supprimer dessus. Un cadenas visuel les distingue des écritures manuelles.
- **RGCPT-02** : La saisie manuelle n'est autorisée que dans le journal OD. Tout autre journal est en lecture seule depuis l'interface de saisie.
- **RGCPT-03** : L'équilibre comptable (débit = crédit) est vérifié en temps réel côté client via `Decimal.js`. Le bouton "VALIDER" reste `disabled` tant que l'équilibre n'est pas atteint.
- **RGCPT-04** : Montants = VARCHAR(255) côté BFF et DB. Affichage formaté (espaces milliers) côté client via `formatGNF()`. Calculs via `Decimal.js`.
- **RGCPT-05** : L'import OFX/CSV du rapprochement bancaire parse les fichiers côté client pour prévisualisation, puis envoie en multipart au BFF. Taille max : 10 MB.
- **RGCPT-06** : Les états financiers (bilan, CR) sont générables à n'importe quelle date — pas seulement en fin d'exercice. Export PDF déclenché côté BFF (bouton "Exporter PDF").
- **RGCPT-07** : IDs = `number` (INT UNSIGNED). Les numéros de comptes SYSCOHADA sont des `string` (6 chiffres avec zéros possibles).
- **RGCPT-08** : Autocomplétion sur le champ "N° Compte" dans la saisie d'écriture — recherche dans les 203 comptes du plan comptable avec debounce 200ms.

---

## Tâche Claude

Génère le code complet Next.js 15 TypeScript pour le module Comptabilité SYSCOHADA FlowUp ERP.

**Contraintes techniques absolues :**
- Palette navy `#1A2157`, blue `#1E5EFF`, cyan `#00C8C0` — Inter + JetBrains Mono, JetBrains Mono pour les numéros de comptes
- Montants = VARCHAR(255) → `string` dans les types TS. Calculs via `Decimal.js`
- Numéros de comptes SYSCOHADA = `string` (pas `number`)
- IDs = `number` (INT UNSIGNED)
- Gestion des écritures multi-lignes dynamiques (ajouter/supprimer lignes)
- SWR pour les fetches paginés

**Génère dans cet ordre :**
1. Types TypeScript (`types/finances.ts`, `types/syscohada.ts`)
2. Utilitaire `utils/comptabilite.ts` (équilibre Decimal.js, formatage comptes)
3. Hook `useFinances.ts` (journaux, écritures, états)
4. Hook `useRapprochement.ts` (import, matching)
5. `PlanComptable.tsx` (autocomplétion 203 comptes)
6. `EcritureForm.tsx` (lignes dynamiques, équilibre temps réel)
7. `GrandLivre.tsx`, `BalanceComptes.tsx`
8. `BilanSYSCOHADA.tsx`, `CompteResultat.tsx`
9. `RapprochementBancaire.tsx` (import OFX/CSV, matching visuel)
10. `JournauxList.tsx`
11. Pages : `page.tsx`, `journaux/page.tsx`, `journaux/[id]/page.tsx`, `ecritures/page.tsx`, `ecritures/saisie/page.tsx`, `rapprochement/page.tsx`, `etats/page.tsx`, `etats/[type]/page.tsx`
