272 lines
7.7 KiB
Dart
272 lines
7.7 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);
|
|
}
|
|
|
|
/// 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)';
|
|
}
|
|
}
|