Aller au contenu

Story CP-006 : Configuration Pays : Tranches d'Imposition + Cotisations Sociales

Module : control-plane Slice : Slice 6a from architecture (split from original CP-006) Brand context : [BOTH] Papillon HR Suite + ALTARYS ENTERPRISE HR Suite Priority : 6 Depends on : CP-001, CP-002 Estimated complexity : S


Objectif

Construire la configuration des tranches d'imposition et des cotisations sociales pour le moteur de configuration spécifique au pays. Ce slice crée les entités CountryTaxBracket et CountrySocialContribution, le CountryConfigService (méthodes tax + social) et les endpoints GET pour tax-brackets et social-contributions. Les taux sont versionnés par année fiscale, modifiables sans redéploiement et signalés comme vérifiés/non vérifiés. Pour le MVP, seules les données de la Côte d'Ivoire (CI) sont seedées.


Périmètre Backend

Entités & Records

Entité CountryTaxBracket (base plateforme — données de référence) :

Champ Type Contraintes
id UUID v7 PK
country_code String(2) NOT NULL
fiscal_year int NOT NULL
bracket_lower BigDecimal NOT NULL
bracket_upper BigDecimal Nullable (null = infini)
rate_percent BigDecimal NOT NULL
effective_date LocalDate NOT NULL
is_verified boolean NOT NULL, défaut false

Tranches ITS CI (Ordonnance n° 2023-719 — temporairement validées) :

Inférieur (FCFA/mois) Supérieur (FCFA/mois) Taux
0 75 000 0%
75 001 240 000 16%
240 001 800 000 21%
800 001 2 400 000 24%
2 400 001 8 000 000 28%
8 000 001 32%

Entité CountrySocialContribution (base plateforme) :

Champ Type Contraintes
id UUID v7 PK
country_code String(2) NOT NULL
fiscal_year int NOT NULL
branch_code String(10) NOT NULL (PF, MAT, ATMP, AV)
branch_name String NOT NULL
employer_rate BigDecimal NOT NULL
employee_rate BigDecimal NOT NULL
ceiling_monthly BigDecimal Nullable (null = pas de plafond)
risk_class String Nullable (uniquement pour ATMP)
effective_date LocalDate NOT NULL
is_verified boolean NOT NULL, défaut false

Taux CNPS CI (temporairement validés) :

Branche Code Patronal Salarial Plafond Notes
Prestations Familiales PF 5,00% 0% Sans plafond
Maternité MAT 0,75% 0% Sans plafond
AT/MP ATMP 2,00%–5,00% 0% Sans plafond Taux selon classe de risque
Assurance Vieillesse AV 7,70% 6,30% 3 375 000 FCFA/mois Plafond non vérifié

Couche Repository

  • CountryTaxBracketRepository.java — Platform-scoped :
  • findByCountryCodeAndFiscalYear(String, int) → List<CountryTaxBracket>
  • CountrySocialContributionRepository.java — Platform-scoped :
  • findByCountryCodeAndFiscalYear(String, int) → List<CountrySocialContribution>
  • findByCountryCodeAndFiscalYearAndBranchCode(String, int, String) → Optional<CountrySocialContribution>

Couche Service

CountryConfigService.java : - getTaxBrackets(String countryCode, int fiscalYear) → List<CountryTaxBracket> — Retourne les tranches ordonnées par bracket_lower - getSocialContributions(String countryCode, int fiscalYear) → List<CountrySocialContribution> - Pas de mise en cache dans ce slice (le cache est ajouté dans CP-019)

Endpoints API

Méthode Chemin Corps de requête Réponse Auth
GET /api/v1/country-config/{countryCode}/tax-brackets?fiscalYear={y} List Tout utilisateur authentifié
GET /api/v1/country-config/{countryCode}/social-contributions?fiscalYear={y} List Tout utilisateur authentifié

Endpoints CRUD admin (pour l'admin plateforme — consommés par la Console Admin CP-012) :

Méthode Chemin Auth
PUT /api/v1/admin/country-config/{countryCode}/tax-brackets PLATFORM_ADMIN
PUT /api/v1/admin/country-config/{countryCode}/social-contributions PLATFORM_ADMIN

Règles de validation

  • country_code : ISO 3166-1 alpha-2 valide (MVP : seul "CI" accepté)
  • fiscal_year : >= 2020, <= année courante + 2
  • Tous les champs de taux : BigDecimal, >= 0, <= 100 (pourcentages)
  • Tous les champs monétaires : BigDecimal, >= 0, zéro décimale (XOF)
  • Les tranches d'imposition ne doivent pas se chevaucher pour le même pays/année

Considérations multi-tenant

  • La configuration pays est dans la base plateforme — partagée entre tous les tenants
  • NON tenant-scoped (les mêmes taux CI s'appliquent à tous les tenants CI)
  • Les endpoints de lecture sont accessibles à tout utilisateur authentifié (le country_code du JWT détermine les données pertinentes)
  • Les endpoints d'écriture sont restreints au rôle PLATFORM_ADMIN

Migration Flyway

  • V003__create_country_config_tax_social.sql — Base plateforme : tables CountryTaxBracket + CountrySocialContribution + seed des tranches ITS CI et des taux CNPS pour l'année fiscale 2026

Périmètre Frontend

Aucun frontend côté tenant dans ce slice. La configuration pays est une donnée de référence en lecture seule pour les tenants. La Console Admin (CP-012) fournit l'UI d'édition.

Pages & Routes

N/A pour le frontend tenant. L'éditeur de la console admin est dans CP-012.

États UI (TOUS REQUIS)

N/A — Slice uniquement backend côté tenant. UI admin dans CP-012.

Comportement responsive

N/A

Interactions

N/A


Critères d'acceptation

AC-046: Get CI tax brackets
Given CI ITS brackets are seeded for fiscal year 2026
When I call GET /api/v1/country-config/CI/tax-brackets?fiscalYear=2026
Then I receive 6 brackets ordered by bracket_lower
And the first bracket has rate=0% (075,000 FCFA)

AC-047: Get CI CNPS social contributions
Given CI CNPS rates are seeded for fiscal year 2026
When I call GET /api/v1/country-config/CI/social-contributions?fiscalYear=2026
Then I receive 4 branches: PF, MAT, ATMP, AV
And each includes employer_rate, employee_rate, ceiling (nullable), is_verified flag

AC-049: Unverified rates flagged
Given CNPS AV ceiling is seeded with is_verified=false
When any module reads the rate
Then the response includes is_verified=false
And the admin console can display it with an "⚠ Non vérifié" badge (CP-012)

Règles OHADA & Réglementaires

  • Tranches ITS : L'Ordonnance n° 2023-719 définit les tranches d'imposition sur les revenus CI. Actuellement temporairement validées (TV-CP-05) — is_verified=false. Doivent être confirmées avec les publications officielles de la DGI avant la mise en production du module Paie.
  • Taux CNPS : Basés sur le Communiqué CNPS 2023 — temporairement validés (TV-CP-01 à TV-CP-04). Le plafond de la branche AV (3 375 000 FCFA/mois) nécessite une confirmation officielle.
  • Plan comptable SYSCOHADA : Standard pour les 17 pays OHADA. Seedé pour le module Comptabilité.
  • Grilles salariales sectorielles : La CCI définit des salaires minimaux par catégorie et par secteur. Valeurs provisoires seedées ; valeurs finales nécessaires avant la Paie.
  • BigDecimal UNIQUEMENT : Toutes les valeurs monétaires et de pourcentage utilisent BigDecimal. Jamais de double/float pour les données financières.

Standards & Conventions

  • docs/standards/java-spring-guidelines.md — §Entities, §BigDecimal for financials
  • docs/standards/database-guidelines.md — §Platform DB reference data, §Seed data in migrations
  • docs/standards/api-guidelines.md — §Read-only reference endpoints, §Admin-only write endpoints

Exigences de test

Tests unitaires

  • CountryConfigService : recherche de tranche par pays + année fiscale
  • CountryConfigService : recherche de cotisation sociale par pays + année fiscale
  • Validation : détection de chevauchement de tranches

Tests d'intégration

  • Endpoints GET pour tax-brackets et social-contributions
  • Vérification des données de seed : tranches CI et taux CNPS correspondent aux valeurs attendues
  • Autorisation : l'utilisateur tenant peut lire, ne peut pas écrire (403)

Ce que le QA validera

  • N/A pour l'UI tenant (uniquement backend pour les tenants)
  • La console admin (CP-012) validera l'UI de l'éditeur

Hors périmètre

  • Jours fériés, grilles salariales, cache, validation du code pays — CP-019
  • UI éditeur de la console admin — CP-012
  • Pays autres que CI — Post-MVP (l'architecture supporte le multi-pays dès le départ)
  • RICF (Réduction d'Impôt pour Charges de Famille) — Question ouverte OQ-CP-02, nécessaire avant la Paie
  • API d'import automatique des jours fériés — Backlog OQ-CP-06
  • Plan comptable SYSCOHADA — Seedé dans la migration, consommé plus tard par le module Comptabilité
  • Données de référence des types de congé — Seedées ici, détaillées dans le PRD Gestion des Absences

Définition de Done

  • [ ] Tous les endpoints backend implémentés et retournant les réponses correctes
  • [ ] Toutes les pages frontend s'affichent correctement à 360px, 768px, 1024px — N/A
  • [ ] Les 5 états UI implémentés — N/A (uniquement backend côté tenant)
  • [ ] Les micro-textes français correspondent exactement à la spec design — N/A
  • [ ] Tous les critères d'acceptation passent manuellement
  • [ ] Tests unitaires écrits et passants
  • [ ] Tests d'intégration écrits et passants
  • [ ] Isolation multi-tenant vérifiée — N/A (les données de référence sont partagées)
  • [ ] Écriture hors ligne + sync fonctionnelle — N/A
  • [ ] Pas de any TypeScript — N/A
  • [ ] Pas de types Java bruts — tous les génériques explicites
  • [ ] Les réponses API respectent le format d'enveloppe standard
  • [ ] Entrées d'audit créées pour chaque mutation de données — Les mises à jour admin de la config génèrent des entrées d'audit