Files
dahoud d094d6db9c Initial commit: unionflow-mobile-apps
Application Flutter complète (sans build artifacts).

Signed-off-by: lions dev Team
2026-03-15 16:30:08 +00:00

242 lines
5.6 KiB
Dart

/// Entité métier Approbation Transaction
///
/// Représente une approbation dans le workflow financier multi-niveaux
library transaction_approval;
import 'package:equatable/equatable.dart';
/// Statut de l'approbation
enum ApprovalStatus {
/// En attente d'approbation
pending,
/// Approuvée (niveau 1)
approved,
/// Validée (niveau 2 - validation finale)
validated,
/// Rejetée
rejected,
/// Expirée (timeout)
expired,
/// Annulée
cancelled,
}
/// Niveau d'approbation requis selon montant
enum ApprovalLevel {
/// Aucune approbation requise (< seuil)
none,
/// Niveau 1 : Un approbateur requis
level1,
/// Niveau 2 : Deux approbateurs requis
level2,
/// Niveau 3 : Trois approbateurs requis (montants très élevés)
level3,
}
/// Type de transaction financière
enum TransactionType {
/// Cotisation/contribution
contribution,
/// Dépôt épargne
deposit,
/// Retrait épargne
withdrawal,
/// Transfert
transfer,
/// Dépense solidarité
solidarity,
/// Dépense événement
event,
/// Autre dépense
other,
}
/// Entité Approbation de Transaction
class TransactionApproval extends Equatable {
final String id;
final String transactionId;
final TransactionType transactionType;
final double amount;
final String currency;
final String requesterId;
final String requesterName;
final String? organizationId;
final ApprovalLevel requiredLevel;
final ApprovalStatus status;
final List<ApproverAction> approvers;
final String? rejectionReason;
final DateTime createdAt;
final DateTime? expiresAt;
final DateTime? completedAt;
final Map<String, dynamic>? metadata;
const TransactionApproval({
required this.id,
required this.transactionId,
required this.transactionType,
required this.amount,
this.currency = 'XOF',
required this.requesterId,
required this.requesterName,
this.organizationId,
required this.requiredLevel,
required this.status,
this.approvers = const [],
this.rejectionReason,
required this.createdAt,
this.expiresAt,
this.completedAt,
this.metadata,
});
/// Vérifie si l'approbation est en attente
bool get isPending => status == ApprovalStatus.pending;
/// Vérifie si l'approbation est complétée
bool get isCompleted =>
status == ApprovalStatus.validated ||
status == ApprovalStatus.rejected ||
status == ApprovalStatus.cancelled;
/// Vérifie si l'approbation est expirée
bool get isExpired {
if (expiresAt == null) return false;
return DateTime.now().isAfter(expiresAt!);
}
/// Nombre d'approbations reçues
int get approvalCount =>
approvers.where((a) => a.decision == ApprovalDecision.approved).length;
/// Nombre d'approbations requises
int get requiredApprovals {
switch (requiredLevel) {
case ApprovalLevel.none:
return 0;
case ApprovalLevel.level1:
return 1;
case ApprovalLevel.level2:
return 2;
case ApprovalLevel.level3:
return 3;
}
}
/// Vérifie si toutes les approbations sont reçues
bool get hasAllApprovals => approvalCount >= requiredApprovals;
/// Copie avec modifications
TransactionApproval copyWith({
String? id,
String? transactionId,
TransactionType? transactionType,
double? amount,
String? currency,
String? requesterId,
String? requesterName,
String? organizationId,
ApprovalLevel? requiredLevel,
ApprovalStatus? status,
List<ApproverAction>? approvers,
String? rejectionReason,
DateTime? createdAt,
DateTime? expiresAt,
DateTime? completedAt,
Map<String, dynamic>? metadata,
}) {
return TransactionApproval(
id: id ?? this.id,
transactionId: transactionId ?? this.transactionId,
transactionType: transactionType ?? this.transactionType,
amount: amount ?? this.amount,
currency: currency ?? this.currency,
requesterId: requesterId ?? this.requesterId,
requesterName: requesterName ?? this.requesterName,
organizationId: organizationId ?? this.organizationId,
requiredLevel: requiredLevel ?? this.requiredLevel,
status: status ?? this.status,
approvers: approvers ?? this.approvers,
rejectionReason: rejectionReason ?? this.rejectionReason,
createdAt: createdAt ?? this.createdAt,
expiresAt: expiresAt ?? this.expiresAt,
completedAt: completedAt ?? this.completedAt,
metadata: metadata ?? this.metadata,
);
}
@override
List<Object?> get props => [
id,
transactionId,
transactionType,
amount,
currency,
requesterId,
requesterName,
organizationId,
requiredLevel,
status,
approvers,
rejectionReason,
createdAt,
expiresAt,
completedAt,
metadata,
];
}
/// Décision d'un approbateur
enum ApprovalDecision {
/// En attente
pending,
/// Approuvé
approved,
/// Rejeté
rejected,
}
/// Action d'un approbateur
class ApproverAction extends Equatable {
final String approverId;
final String approverName;
final String approverRole;
final ApprovalDecision decision;
final String? comment;
final DateTime? decidedAt;
const ApproverAction({
required this.approverId,
required this.approverName,
required this.approverRole,
required this.decision,
this.comment,
this.decidedAt,
});
@override
List<Object?> get props => [
approverId,
approverName,
approverRole,
decision,
comment,
decidedAt,
];
}