Files
unionflow-server-impl-quarkus/unionflow-mobile-apps/lib/core/models/cotisation_model.dart
2025-09-15 20:15:34 +00:00

278 lines
7.8 KiB
Dart

import 'package:json_annotation/json_annotation.dart';
part 'cotisation_model.g.dart';
/// Modèle de données pour les cotisations
/// Correspond au CotisationDTO du backend
@JsonSerializable()
class CotisationModel {
final String id;
final String numeroReference;
final String membreId;
final String? nomMembre;
final String? numeroMembre;
final String typeCotisation;
final double montantDu;
final double montantPaye;
final String codeDevise;
final String statut;
final DateTime dateEcheance;
final DateTime? datePaiement;
final String? description;
final String? periode;
final int annee;
final int? mois;
final String? observations;
final bool recurrente;
final int nombreRappels;
final DateTime? dateDernierRappel;
final String? valideParId;
final String? nomValidateur;
final DateTime? dateValidation;
final String? methodePaiement;
final String? referencePaiement;
final DateTime dateCreation;
final DateTime? dateModification;
const CotisationModel({
required this.id,
required this.numeroReference,
required this.membreId,
this.nomMembre,
this.numeroMembre,
required this.typeCotisation,
required this.montantDu,
required this.montantPaye,
required this.codeDevise,
required this.statut,
required this.dateEcheance,
this.datePaiement,
this.description,
this.periode,
required this.annee,
this.mois,
this.observations,
required this.recurrente,
required this.nombreRappels,
this.dateDernierRappel,
this.valideParId,
this.nomValidateur,
this.dateValidation,
this.methodePaiement,
this.referencePaiement,
required this.dateCreation,
this.dateModification,
});
/// Factory pour créer depuis JSON
factory CotisationModel.fromJson(Map<String, dynamic> json) =>
_$CotisationModelFromJson(json);
/// Convertit vers JSON
Map<String, dynamic> toJson() => _$CotisationModelToJson(this);
/// Calcule le montant restant à payer
double get montantRestant => montantDu - montantPaye;
/// Vérifie si la cotisation est entièrement payée
bool get isEntierementPayee => montantRestant <= 0;
/// Vérifie si la cotisation est en retard
bool get isEnRetard {
return dateEcheance.isBefore(DateTime.now()) && !isEntierementPayee;
}
/// Retourne le pourcentage de paiement
double get pourcentagePaiement {
if (montantDu == 0) return 0;
return (montantPaye / montantDu * 100).clamp(0, 100);
}
/// Calcule le nombre de jours de retard
int get joursRetard {
if (!isEnRetard) return 0;
return DateTime.now().difference(dateEcheance).inDays;
}
/// Retourne la couleur associée au statut
String get couleurStatut {
switch (statut) {
case 'PAYEE':
return '#4CAF50'; // Vert
case 'EN_ATTENTE':
return '#FF9800'; // Orange
case 'EN_RETARD':
return '#F44336'; // Rouge
case 'PARTIELLEMENT_PAYEE':
return '#2196F3'; // Bleu
case 'ANNULEE':
return '#9E9E9E'; // Gris
default:
return '#757575'; // Gris foncé
}
}
/// Retourne le libellé du statut en français
String get libelleStatut {
switch (statut) {
case 'PAYEE':
return 'Payée';
case 'EN_ATTENTE':
return 'En attente';
case 'EN_RETARD':
return 'En retard';
case 'PARTIELLEMENT_PAYEE':
return 'Partiellement payée';
case 'ANNULEE':
return 'Annulée';
default:
return statut;
}
}
/// Retourne le libellé du type de cotisation
String get libelleTypeCotisation {
switch (typeCotisation) {
case 'MENSUELLE':
return 'Mensuelle';
case 'TRIMESTRIELLE':
return 'Trimestrielle';
case 'SEMESTRIELLE':
return 'Semestrielle';
case 'ANNUELLE':
return 'Annuelle';
case 'EXCEPTIONNELLE':
return 'Exceptionnelle';
case 'ADHESION':
return 'Adhésion';
default:
return typeCotisation;
}
}
/// Retourne l'icône associée au type de cotisation
String get iconeTypeCotisation {
switch (typeCotisation) {
case 'MENSUELLE':
return '📅';
case 'TRIMESTRIELLE':
return '📊';
case 'SEMESTRIELLE':
return '📈';
case 'ANNUELLE':
return '🗓️';
case 'EXCEPTIONNELLE':
return '';
case 'ADHESION':
return '🎯';
default:
return '💰';
}
}
/// Retourne le nombre de jours jusqu'à l'échéance
int get joursJusquEcheance {
final maintenant = DateTime.now();
final difference = dateEcheance.difference(maintenant);
return difference.inDays;
}
/// Vérifie si l'échéance approche (moins de 7 jours)
bool get echeanceProche {
return joursJusquEcheance <= 7 && joursJusquEcheance >= 0;
}
/// Retourne un message d'urgence basé sur l'échéance
String get messageUrgence {
final jours = joursJusquEcheance;
if (jours < 0) {
return 'En retard de ${-jours} jour${-jours > 1 ? 's' : ''}';
} else if (jours == 0) {
return 'Échéance aujourd\'hui';
} else if (jours <= 3) {
return 'Échéance dans $jours jour${jours > 1 ? 's' : ''}';
} else if (jours <= 7) {
return 'Échéance dans $jours jours';
} else {
return '';
}
}
/// Copie avec modifications
CotisationModel copyWith({
String? id,
String? numeroReference,
String? membreId,
String? nomMembre,
String? numeroMembre,
String? typeCotisation,
double? montantDu,
double? montantPaye,
String? codeDevise,
String? statut,
DateTime? dateEcheance,
DateTime? datePaiement,
String? description,
String? periode,
int? annee,
int? mois,
String? observations,
bool? recurrente,
int? nombreRappels,
DateTime? dateDernierRappel,
String? valideParId,
String? nomValidateur,
DateTime? dateValidation,
String? methodePaiement,
String? referencePaiement,
DateTime? dateCreation,
DateTime? dateModification,
}) {
return CotisationModel(
id: id ?? this.id,
numeroReference: numeroReference ?? this.numeroReference,
membreId: membreId ?? this.membreId,
nomMembre: nomMembre ?? this.nomMembre,
numeroMembre: numeroMembre ?? this.numeroMembre,
typeCotisation: typeCotisation ?? this.typeCotisation,
montantDu: montantDu ?? this.montantDu,
montantPaye: montantPaye ?? this.montantPaye,
codeDevise: codeDevise ?? this.codeDevise,
statut: statut ?? this.statut,
dateEcheance: dateEcheance ?? this.dateEcheance,
datePaiement: datePaiement ?? this.datePaiement,
description: description ?? this.description,
periode: periode ?? this.periode,
annee: annee ?? this.annee,
mois: mois ?? this.mois,
observations: observations ?? this.observations,
recurrente: recurrente ?? this.recurrente,
nombreRappels: nombreRappels ?? this.nombreRappels,
dateDernierRappel: dateDernierRappel ?? this.dateDernierRappel,
valideParId: valideParId ?? this.valideParId,
nomValidateur: nomValidateur ?? this.nomValidateur,
dateValidation: dateValidation ?? this.dateValidation,
methodePaiement: methodePaiement ?? this.methodePaiement,
referencePaiement: referencePaiement ?? this.referencePaiement,
dateCreation: dateCreation ?? this.dateCreation,
dateModification: dateModification ?? this.dateModification,
);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is CotisationModel && other.id == id;
}
@override
int get hashCode => id.hashCode;
@override
String toString() {
return 'CotisationModel(id: $id, numeroReference: $numeroReference, '
'nomMembre: $nomMembre, typeCotisation: $typeCotisation, '
'montantDu: $montantDu, statut: $statut)';
}
}