327 lines
11 KiB
Markdown
327 lines
11 KiB
Markdown
# Finance Workflow Feature
|
|
|
|
## Vue d'ensemble
|
|
|
|
Module complet de workflow financier avec approbations multi-niveaux et gestion budgétaire pour UnionFlow.
|
|
|
|
## Architecture Clean Architecture + BLoC
|
|
|
|
```
|
|
finance_workflow/
|
|
├── domain/ # Couche métier (entités, repositories interfaces, use cases)
|
|
│ ├── entities/
|
|
│ │ ├── transaction_approval.dart # Entité approbation avec statuts
|
|
│ │ ├── budget.dart # Entité budget avec lignes
|
|
│ │ └── financial_audit_log.dart # Entité audit trail
|
|
│ ├── repositories/
|
|
│ │ └── finance_workflow_repository.dart # Interface repository
|
|
│ └── usecases/
|
|
│ ├── get_pending_approvals.dart
|
|
│ ├── get_approval_by_id.dart
|
|
│ ├── approve_transaction.dart
|
|
│ ├── reject_transaction.dart
|
|
│ ├── get_budgets.dart
|
|
│ ├── get_budget_by_id.dart
|
|
│ ├── create_budget.dart
|
|
│ └── get_budget_tracking.dart
|
|
│
|
|
├── data/ # Couche données (models, datasources, repository impl)
|
|
│ ├── models/
|
|
│ │ ├── transaction_approval_model.dart
|
|
│ │ ├── transaction_approval_model.g.dart
|
|
│ │ ├── budget_model.dart
|
|
│ │ └── budget_model.g.dart
|
|
│ ├── datasources/
|
|
│ │ └── finance_workflow_remote_datasource.dart
|
|
│ └── repositories/
|
|
│ └── finance_workflow_repository_impl.dart
|
|
│
|
|
└── presentation/ # Couche présentation (BLoC, pages, widgets)
|
|
├── bloc/
|
|
│ ├── approval_bloc.dart
|
|
│ ├── approval_event.dart
|
|
│ ├── approval_state.dart
|
|
│ ├── budget_bloc.dart
|
|
│ ├── budget_event.dart
|
|
│ └── budget_state.dart
|
|
├── pages/
|
|
│ ├── pending_approvals_page.dart
|
|
│ └── budgets_list_page.dart
|
|
└── widgets/
|
|
├── approve_dialog.dart
|
|
└── reject_dialog.dart
|
|
```
|
|
|
|
## Fonctionnalités
|
|
|
|
### 1. Approbations de Transactions
|
|
|
|
#### Statuts d'approbation
|
|
- `pending` : En attente d'approbation
|
|
- `approved` : Approuvée (niveau 1)
|
|
- `validated` : Validée (niveau 2 - validation finale)
|
|
- `rejected` : Rejetée
|
|
- `expired` : Expirée (timeout)
|
|
- `cancelled` : Annulée
|
|
|
|
#### Niveaux d'approbation (selon montant)
|
|
- `none` : Aucune approbation requise (< seuil)
|
|
- `level1` : Un approbateur requis
|
|
- `level2` : Deux approbateurs requis
|
|
- `level3` : Trois approbateurs requis (montants très élevés)
|
|
|
|
#### Types de transactions
|
|
- `contribution` : Cotisation/contribution
|
|
- `deposit` : Dépôt épargne
|
|
- `withdrawal` : Retrait épargne
|
|
- `transfer` : Transfert
|
|
- `solidarity` : Dépense solidarité
|
|
- `event` : Dépense événement
|
|
- `other` : Autre dépense
|
|
|
|
#### Cas d'usage implémentés
|
|
1. **Consulter les approbations en attente** : Liste filtrée par organisation
|
|
2. **Voir détail d'une approbation** : Informations complètes avec historique
|
|
3. **Approuver une transaction** : Avec commentaire optionnel
|
|
4. **Rejeter une transaction** : Avec raison obligatoire (min 10 caractères)
|
|
5. **Rafraîchir la liste** : Pull-to-refresh
|
|
|
|
#### UI/UX
|
|
- Liste des approbations avec filtres
|
|
- Card d'approbation affichant :
|
|
- Type de transaction avec badge coloré selon niveau
|
|
- Montant en devise locale (XOF par défaut)
|
|
- Demandeur et date de création
|
|
- Progression des approbations (X/Y)
|
|
- Boutons Approuver/Rejeter
|
|
- Dialog d'approbation avec récapitulatif et champ commentaire
|
|
- Dialog de rejet avec validation de raison (min 10 chars)
|
|
- États : Loading, Empty, Error avec retry
|
|
- Notifications Snackbar pour succès/erreur
|
|
|
|
### 2. Gestion des Budgets
|
|
|
|
#### Périodes budgétaires
|
|
- `monthly` : Budget mensuel
|
|
- `quarterly` : Budget trimestriel
|
|
- `semiannual` : Budget semestriel
|
|
- `annual` : Budget annuel
|
|
|
|
#### Statuts de budget
|
|
- `draft` : Brouillon (en cours de création)
|
|
- `active` : Actif
|
|
- `closed` : Clos (période terminée)
|
|
- `cancelled` : Annulé
|
|
|
|
#### Catégories budgétaires
|
|
- `contributions` : Cotisations/contributions
|
|
- `savings` : Épargne
|
|
- `solidarity` : Solidarité
|
|
- `events` : Événements
|
|
- `operational` : Fonctionnement (frais généraux)
|
|
- `investments` : Investissements
|
|
- `other` : Autres
|
|
|
|
#### Cas d'usage implémentés
|
|
1. **Consulter les budgets** : Liste avec filtres (statut, année)
|
|
2. **Voir détail d'un budget** : Informations complètes avec lignes
|
|
3. **Créer un budget** : Avec validation (nom, période, lignes)
|
|
4. **Suivre l'exécution budgétaire** : Taux de réalisation, écart
|
|
5. **Filtrer les budgets** : Par statut et année
|
|
|
|
#### UI/UX
|
|
- Liste des budgets avec filtres avancés
|
|
- Card de budget affichant :
|
|
- Nom et période (Mensuel/Annuel YYYY)
|
|
- Statut avec badge coloré
|
|
- Montant prévu vs réalisé
|
|
- Barre de progression avec taux de réalisation
|
|
- Indicateur de dépassement (rouge si > 100%)
|
|
- Dialog de filtres avec chips (statut + année)
|
|
- Chips de filtres actifs supprimables
|
|
- FAB pour créer un nouveau budget
|
|
- États : Loading, Empty, Error avec retry
|
|
|
|
### 3. Audit Trail
|
|
|
|
#### Types d'opérations auditées
|
|
- `create`, `read`, `update`, `delete`
|
|
- `approve`, `reject`, `validate`, `cancel`
|
|
- `export`
|
|
|
|
#### Types d'entités auditées
|
|
- `contribution`, `savingsTransaction`, `approval`, `budget`
|
|
|
|
#### Niveaux de sévérité
|
|
- `info` : Information
|
|
- `warning` : Avertissement
|
|
- `error` : Erreur
|
|
- `critical` : Critique
|
|
|
|
#### Données capturées
|
|
- Utilisateur, rôle, IP, user agent
|
|
- Date/heure de l'opération
|
|
- Entité et ID de l'entité
|
|
- Données avant/après (JSON)
|
|
- Montants impliqués
|
|
|
|
## API Endpoints
|
|
|
|
### Approbations
|
|
- `GET /api/finance/approvals/pending?organizationId={id}` : Liste des approbations en attente
|
|
- `GET /api/finance/approvals/{approvalId}` : Détail d'une approbation
|
|
- `POST /api/finance/approvals/{approvalId}/approve` : Approuver (body: {comment?})
|
|
- `POST /api/finance/approvals/{approvalId}/reject` : Rejeter (body: {reason})
|
|
|
|
### Budgets
|
|
- `GET /api/finance/budgets?organizationId={id}&status={status}&year={year}` : Liste des budgets
|
|
- `GET /api/finance/budgets/{budgetId}` : Détail d'un budget
|
|
- `POST /api/finance/budgets` : Créer un budget
|
|
- `GET /api/finance/budgets/{budgetId}/tracking` : Suivi budgétaire
|
|
|
|
## Permissions RBAC
|
|
|
|
### OrgAdmin + SuperAdmin
|
|
- ✅ Consulter toutes les approbations de l'organisation
|
|
- ✅ Approuver/Rejeter les transactions
|
|
- ✅ Consulter tous les budgets de l'organisation
|
|
- ✅ Créer/Modifier les budgets
|
|
- ✅ Accéder aux logs d'audit
|
|
|
|
### Autres rôles
|
|
- ❌ Pas d'accès au workflow financier (gap P0 identifié dans audit métier)
|
|
|
|
## État d'implémentation
|
|
|
|
### ✅ Terminé (Mobile)
|
|
- [x] Entities (TransactionApproval, Budget, FinancialAuditLog)
|
|
- [x] Repository interface
|
|
- [x] Data models avec JSON serialization (custom @JsonKey pour nested types)
|
|
- [x] Remote datasource (8 endpoints API)
|
|
- [x] Repository implementation avec gestion d'erreurs
|
|
- [x] 8 Use cases avec validation
|
|
- [x] 2 BLoCs complets (Approval, Budget) avec états/événements
|
|
- [x] 2 Pages fonctionnelles (Pending Approvals, Budgets List)
|
|
- [x] 2 Dialogs (Approve, Reject) avec validation
|
|
- [x] Integration navigation (routes + menu RBAC)
|
|
- [x] Build runner successful (génération .g.dart)
|
|
|
|
### ⏳ En cours
|
|
- [ ] Budget detail page (voir détail + tracking)
|
|
- [ ] Create budget page (formulaire création avec lignes)
|
|
- [ ] Audit logs page (consultation logs d'audit)
|
|
|
|
### 📋 À faire (Backend Quarkus)
|
|
- [ ] POST /api/finance/approvals/pending (endpoint backend)
|
|
- [ ] POST /api/finance/approvals/{id}/approve (endpoint backend)
|
|
- [ ] POST /api/finance/approvals/{id}/reject (endpoint backend)
|
|
- [ ] GET /api/finance/budgets (endpoint backend)
|
|
- [ ] POST /api/finance/budgets (endpoint backend)
|
|
- [ ] GET /api/finance/budgets/{id}/tracking (endpoint backend)
|
|
- [ ] Audit log persistence et endpoints
|
|
- [ ] Tests unitaires (use cases, BLoCs)
|
|
- [ ] Tests d'intégration (API)
|
|
|
|
## Patterns techniques
|
|
|
|
### JSON Serialization pour types nested
|
|
|
|
Fix appliqué pour les listes de types custom (ApproverAction, BudgetLine) :
|
|
|
|
```dart
|
|
@JsonSerializable(explicitToJson: true)
|
|
class TransactionApprovalModel extends TransactionApproval {
|
|
@JsonKey(
|
|
fromJson: _approversFromJson,
|
|
toJson: _approversToJson,
|
|
)
|
|
@override
|
|
final List<ApproverAction> approvers;
|
|
|
|
const TransactionApprovalModel({
|
|
// ... autres params
|
|
this.approvers = const [],
|
|
// ... autres params
|
|
}) : super(approvers: approvers);
|
|
|
|
static List<ApproverAction> _approversFromJson(List<dynamic>? json) =>
|
|
json?.map((e) => ApproverActionModel.fromJson(e as Map<String, dynamic>)).toList() ?? [];
|
|
|
|
static List<Map<String, dynamic>> _approversToJson(List<ApproverAction>? approvers) =>
|
|
approvers?.map((a) => ApproverActionModel(
|
|
approverId: a.approverId,
|
|
approverName: a.approverName,
|
|
approverRole: a.approverRole,
|
|
decision: a.decision,
|
|
comment: a.comment,
|
|
decidedAt: a.decidedAt,
|
|
).toJson()).toList() ?? [];
|
|
}
|
|
```
|
|
|
|
### Gestion d'erreurs avec Either
|
|
|
|
```dart
|
|
final result = await approveTransaction(approvalId: id);
|
|
|
|
result.fold(
|
|
(failure) => emit(ApprovalError(failure.message)),
|
|
(approval) => emit(TransactionApproved(approval: approval)),
|
|
);
|
|
```
|
|
|
|
### BLoC Pattern
|
|
|
|
```dart
|
|
@injectable
|
|
class ApprovalBloc extends Bloc<ApprovalEvent, ApprovalState> {
|
|
final GetPendingApprovals getPendingApprovals;
|
|
final ApproveTransaction approveTransaction;
|
|
final RejectTransaction rejectTransaction;
|
|
|
|
ApprovalBloc({
|
|
required this.getPendingApprovals,
|
|
required this.approveTransaction,
|
|
required this.rejectTransaction,
|
|
}) : super(const ApprovalInitial()) {
|
|
on<LoadPendingApprovals>(_onLoadPendingApprovals);
|
|
on<ApproveTransactionEvent>(_onApproveTransaction);
|
|
on<RejectTransactionEvent>(_onRejectTransaction);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Dépendances
|
|
|
|
Déjà présentes dans `pubspec.yaml` :
|
|
- `flutter_bloc: ^8.1.6`
|
|
- `injectable: ^2.4.4`
|
|
- `get_it: ^8.0.2`
|
|
- `dartz: ^0.10.1`
|
|
- `equatable: ^2.0.7`
|
|
- `json_annotation: ^4.9.0`
|
|
- `http: ^1.2.2`
|
|
- `flutter_secure_storage: ^9.2.2`
|
|
- `intl: ^0.19.0`
|
|
|
|
## Notes techniques
|
|
|
|
1. **Custom JSON serialization** requise pour `List<ApproverAction>` et `List<BudgetLine>` (types nested)
|
|
2. **Network check** avant chaque appel API (NetworkInfo)
|
|
3. **Error mapping** : Exceptions → Failures (ValidationFailure, NetworkFailure, ServerFailure, etc.)
|
|
4. **RBAC check** dans navigation (OrgAdmin/SuperAdmin uniquement)
|
|
5. **Pull-to-refresh** sur toutes les listes
|
|
6. **Snackbar notifications** pour succès/erreur
|
|
7. **Form validation** sur reject dialog (raison min 10 chars)
|
|
|
|
## Prochaines étapes
|
|
|
|
1. Créer Budget Detail Page avec suivi détaillé par ligne
|
|
2. Créer Create Budget Page avec formulaire multi-steps
|
|
3. Créer Audit Logs Page avec filtres avancés
|
|
4. Implémenter endpoints backend Quarkus
|
|
5. Ajouter tests unitaires pour use cases et BLoCs
|
|
6. Ajouter tests d'intégration API
|
|
7. Optimiser avec caching (budget actif, approvals count)
|
|
8. Ajouter notifications push pour approbations urgentes
|