Files
unionflow-mobile-apps/unionflow-mobile-apps/lib/core/models/payment_model.dart
2025-09-15 20:15:34 +00:00

280 lines
8.1 KiB
Dart

import 'package:json_annotation/json_annotation.dart';
part 'payment_model.g.dart';
/// Modèle de données pour les paiements
/// Représente une transaction de paiement de cotisation
@JsonSerializable()
class PaymentModel {
final String id;
final String cotisationId;
final String numeroReference;
final double montant;
final String codeDevise;
final String methodePaiement;
final String statut;
final DateTime dateTransaction;
final String? numeroTransaction;
final String? referencePaiement;
final String? description;
final Map<String, dynamic>? metadonnees;
final String? operateurMobileMoney;
final String? numeroTelephone;
final String? nomPayeur;
final String? emailPayeur;
final double? fraisTransaction;
final String? codeAutorisation;
final String? messageErreur;
final int? nombreTentatives;
final DateTime? dateEcheance;
final DateTime dateCreation;
final DateTime? dateModification;
const PaymentModel({
required this.id,
required this.cotisationId,
required this.numeroReference,
required this.montant,
required this.codeDevise,
required this.methodePaiement,
required this.statut,
required this.dateTransaction,
this.numeroTransaction,
this.referencePaiement,
this.description,
this.metadonnees,
this.operateurMobileMoney,
this.numeroTelephone,
this.nomPayeur,
this.emailPayeur,
this.fraisTransaction,
this.codeAutorisation,
this.messageErreur,
this.nombreTentatives,
this.dateEcheance,
required this.dateCreation,
this.dateModification,
});
/// Factory pour créer depuis JSON
factory PaymentModel.fromJson(Map<String, dynamic> json) =>
_$PaymentModelFromJson(json);
/// Convertit vers JSON
Map<String, dynamic> toJson() => _$PaymentModelToJson(this);
/// Vérifie si le paiement est réussi
bool get isSuccessful => statut == 'COMPLETED' || statut == 'SUCCESS';
/// Vérifie si le paiement est en cours
bool get isPending => statut == 'PENDING' || statut == 'PROCESSING';
/// Vérifie si le paiement a échoué
bool get isFailed => statut == 'FAILED' || statut == 'ERROR' || statut == 'CANCELLED';
/// Retourne la couleur associée au statut
String get couleurStatut {
switch (statut) {
case 'COMPLETED':
case 'SUCCESS':
return '#4CAF50'; // Vert
case 'PENDING':
case 'PROCESSING':
return '#FF9800'; // Orange
case 'FAILED':
case 'ERROR':
return '#F44336'; // Rouge
case 'CANCELLED':
return '#9E9E9E'; // Gris
default:
return '#757575'; // Gris foncé
}
}
/// Retourne le libellé du statut en français
String get libelleStatut {
switch (statut) {
case 'COMPLETED':
case 'SUCCESS':
return 'Réussi';
case 'PENDING':
return 'En attente';
case 'PROCESSING':
return 'En cours';
case 'FAILED':
return 'Échoué';
case 'ERROR':
return 'Erreur';
case 'CANCELLED':
return 'Annulé';
default:
return statut;
}
}
/// Retourne le libellé de la méthode de paiement
String get libelleMethodePaiement {
switch (methodePaiement) {
case 'MOBILE_MONEY':
return 'Mobile Money';
case 'ORANGE_MONEY':
return 'Orange Money';
case 'WAVE':
return 'Wave';
case 'MOOV_MONEY':
return 'Moov Money';
case 'CARTE_BANCAIRE':
return 'Carte bancaire';
case 'VIREMENT':
return 'Virement bancaire';
case 'ESPECES':
return 'Espèces';
case 'CHEQUE':
return 'Chèque';
default:
return methodePaiement;
}
}
/// Retourne l'icône associée à la méthode de paiement
String get iconeMethodePaiement {
switch (methodePaiement) {
case 'MOBILE_MONEY':
case 'ORANGE_MONEY':
case 'WAVE':
case 'MOOV_MONEY':
return '📱';
case 'CARTE_BANCAIRE':
return '💳';
case 'VIREMENT':
return '🏦';
case 'ESPECES':
return '💵';
case 'CHEQUE':
return '📝';
default:
return '💰';
}
}
/// Calcule le montant net (montant - frais)
double get montantNet {
return montant - (fraisTransaction ?? 0);
}
/// Vérifie si des frais sont appliqués
bool get hasFrais => fraisTransaction != null && fraisTransaction! > 0;
/// Retourne le pourcentage de frais
double get pourcentageFrais {
if (montant == 0 || fraisTransaction == null) return 0;
return (fraisTransaction! / montant * 100);
}
/// Vérifie si le paiement est expiré
bool get isExpired {
if (dateEcheance == null) return false;
return DateTime.now().isAfter(dateEcheance!) && !isSuccessful;
}
/// Retourne le temps restant avant expiration
Duration? get tempsRestant {
if (dateEcheance == null || isExpired) return null;
return dateEcheance!.difference(DateTime.now());
}
/// Retourne un message d'état détaillé
String get messageStatut {
switch (statut) {
case 'COMPLETED':
case 'SUCCESS':
return 'Paiement effectué avec succès';
case 'PENDING':
return 'Paiement en attente de confirmation';
case 'PROCESSING':
return 'Traitement du paiement en cours';
case 'FAILED':
return messageErreur ?? 'Le paiement a échoué';
case 'ERROR':
return messageErreur ?? 'Erreur lors du paiement';
case 'CANCELLED':
return 'Paiement annulé par l\'utilisateur';
default:
return 'Statut inconnu';
}
}
/// Vérifie si le paiement peut être retenté
bool get canRetry {
return isFailed && (nombreTentatives ?? 0) < 3 && !isExpired;
}
/// Copie avec modifications
PaymentModel copyWith({
String? id,
String? cotisationId,
String? numeroReference,
double? montant,
String? codeDevise,
String? methodePaiement,
String? statut,
DateTime? dateTransaction,
String? numeroTransaction,
String? referencePaiement,
String? description,
Map<String, dynamic>? metadonnees,
String? operateurMobileMoney,
String? numeroTelephone,
String? nomPayeur,
String? emailPayeur,
double? fraisTransaction,
String? codeAutorisation,
String? messageErreur,
int? nombreTentatives,
DateTime? dateEcheance,
DateTime? dateCreation,
DateTime? dateModification,
}) {
return PaymentModel(
id: id ?? this.id,
cotisationId: cotisationId ?? this.cotisationId,
numeroReference: numeroReference ?? this.numeroReference,
montant: montant ?? this.montant,
codeDevise: codeDevise ?? this.codeDevise,
methodePaiement: methodePaiement ?? this.methodePaiement,
statut: statut ?? this.statut,
dateTransaction: dateTransaction ?? this.dateTransaction,
numeroTransaction: numeroTransaction ?? this.numeroTransaction,
referencePaiement: referencePaiement ?? this.referencePaiement,
description: description ?? this.description,
metadonnees: metadonnees ?? this.metadonnees,
operateurMobileMoney: operateurMobileMoney ?? this.operateurMobileMoney,
numeroTelephone: numeroTelephone ?? this.numeroTelephone,
nomPayeur: nomPayeur ?? this.nomPayeur,
emailPayeur: emailPayeur ?? this.emailPayeur,
fraisTransaction: fraisTransaction ?? this.fraisTransaction,
codeAutorisation: codeAutorisation ?? this.codeAutorisation,
messageErreur: messageErreur ?? this.messageErreur,
nombreTentatives: nombreTentatives ?? this.nombreTentatives,
dateEcheance: dateEcheance ?? this.dateEcheance,
dateCreation: dateCreation ?? this.dateCreation,
dateModification: dateModification ?? this.dateModification,
);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is PaymentModel && other.id == id;
}
@override
int get hashCode => id.hashCode;
@override
String toString() {
return 'PaymentModel(id: $id, numeroReference: $numeroReference, '
'montant: $montant, methodePaiement: $methodePaiement, statut: $statut)';
}
}