/// Modèle de données pour les cotisations library cotisation_model; import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; part 'cotisation_model.g.dart'; /// Statut d'une cotisation enum StatutCotisation { @JsonValue('PAYEE') payee, @JsonValue('NON_PAYEE') nonPayee, @JsonValue('EN_RETARD') enRetard, @JsonValue('PARTIELLE') partielle, @JsonValue('ANNULEE') annulee, } /// Type de cotisation enum TypeCotisation { @JsonValue('ANNUELLE') annuelle, @JsonValue('MENSUELLE') mensuelle, @JsonValue('TRIMESTRIELLE') trimestrielle, @JsonValue('SEMESTRIELLE') semestrielle, @JsonValue('EXCEPTIONNELLE') exceptionnelle, } /// Méthode de paiement enum MethodePaiement { @JsonValue('ESPECES') especes, @JsonValue('CHEQUE') cheque, @JsonValue('VIREMENT') virement, @JsonValue('CARTE_BANCAIRE') carteBancaire, @JsonValue('WAVE_MONEY') waveMoney, @JsonValue('ORANGE_MONEY') orangeMoney, @JsonValue('FREE_MONEY') freeMoney, @JsonValue('MOBILE_MONEY') mobileMoney, @JsonValue('AUTRE') autre, } /// Modèle complet d'une cotisation @JsonSerializable(explicitToJson: true) class CotisationModel extends Equatable { /// Identifiant unique final String? id; /// Membre concerné final String membreId; final String? membreNom; final String? membrePrenom; /// Organisation final String? organisationId; final String? organisationNom; /// Informations de la cotisation final TypeCotisation type; final StatutCotisation statut; final double montant; final double? montantPaye; final String devise; /// Dates final DateTime dateEcheance; final DateTime? datePaiement; final DateTime? dateRappel; /// Paiement final MethodePaiement? methodePaiement; final String? numeroPaiement; final String? referencePaiement; /// Période final int annee; final int? mois; final int? trimestre; final int? semestre; /// Informations complémentaires final String? description; final String? notes; final String? recu; /// Métadonnées final DateTime? dateCreation; final DateTime? dateModification; final String? creeParId; final String? modifieParId; const CotisationModel({ this.id, required this.membreId, this.membreNom, this.membrePrenom, this.organisationId, this.organisationNom, this.type = TypeCotisation.annuelle, this.statut = StatutCotisation.nonPayee, required this.montant, this.montantPaye, this.devise = 'XOF', required this.dateEcheance, this.datePaiement, this.dateRappel, this.methodePaiement, this.numeroPaiement, this.referencePaiement, required this.annee, this.mois, this.trimestre, this.semestre, this.description, this.notes, this.recu, this.dateCreation, this.dateModification, this.creeParId, this.modifieParId, }); /// Désérialisation depuis JSON factory CotisationModel.fromJson(Map json) => _$CotisationModelFromJson(json); /// Sérialisation vers JSON Map toJson() => _$CotisationModelToJson(this); /// Copie avec modifications CotisationModel copyWith({ String? id, String? membreId, String? membreNom, String? membrePrenom, String? organisationId, String? organisationNom, TypeCotisation? type, StatutCotisation? statut, double? montant, double? montantPaye, String? devise, DateTime? dateEcheance, DateTime? datePaiement, DateTime? dateRappel, MethodePaiement? methodePaiement, String? numeroPaiement, String? referencePaiement, int? annee, int? mois, int? trimestre, int? semestre, String? description, String? notes, String? recu, DateTime? dateCreation, DateTime? dateModification, String? creeParId, String? modifieParId, }) { return CotisationModel( id: id ?? this.id, membreId: membreId ?? this.membreId, membreNom: membreNom ?? this.membreNom, membrePrenom: membrePrenom ?? this.membrePrenom, organisationId: organisationId ?? this.organisationId, organisationNom: organisationNom ?? this.organisationNom, type: type ?? this.type, statut: statut ?? this.statut, montant: montant ?? this.montant, montantPaye: montantPaye ?? this.montantPaye, devise: devise ?? this.devise, dateEcheance: dateEcheance ?? this.dateEcheance, datePaiement: datePaiement ?? this.datePaiement, dateRappel: dateRappel ?? this.dateRappel, methodePaiement: methodePaiement ?? this.methodePaiement, numeroPaiement: numeroPaiement ?? this.numeroPaiement, referencePaiement: referencePaiement ?? this.referencePaiement, annee: annee ?? this.annee, mois: mois ?? this.mois, trimestre: trimestre ?? this.trimestre, semestre: semestre ?? this.semestre, description: description ?? this.description, notes: notes ?? this.notes, recu: recu ?? this.recu, dateCreation: dateCreation ?? this.dateCreation, dateModification: dateModification ?? this.dateModification, creeParId: creeParId ?? this.creeParId, modifieParId: modifieParId ?? this.modifieParId, ); } /// Nom complet du membre String get membreNomComplet { if (membreNom != null && membrePrenom != null) { return '$membrePrenom $membreNom'; } return membreNom ?? membrePrenom ?? 'Membre inconnu'; } /// Montant restant à payer double get montantRestant { if (montantPaye == null) return montant; return montant - montantPaye!; } /// Pourcentage payé double get pourcentagePaye { if (montantPaye == null || montant == 0) return 0; return (montantPaye! / montant) * 100; } /// Vérifie si la cotisation est payée bool get estPayee => statut == StatutCotisation.payee; /// Vérifie si la cotisation est en retard bool get estEnRetard { if (estPayee) return false; return DateTime.now().isAfter(dateEcheance); } /// Nombre de jours avant/après l'échéance int get joursAvantEcheance { return dateEcheance.difference(DateTime.now()).inDays; } /// Libellé de la période String get libellePeriode { switch (type) { case TypeCotisation.annuelle: return 'Année $annee'; case TypeCotisation.mensuelle: if (mois != null) { return '${_getNomMois(mois!)} $annee'; } return 'Année $annee'; case TypeCotisation.trimestrielle: if (trimestre != null) { return 'T$trimestre $annee'; } return 'Année $annee'; case TypeCotisation.semestrielle: if (semestre != null) { return 'S$semestre $annee'; } return 'Année $annee'; case TypeCotisation.exceptionnelle: return 'Exceptionnelle $annee'; } } /// Nom du mois String _getNomMois(int mois) { const mois_fr = [ 'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre' ]; if (mois >= 1 && mois <= 12) { return mois_fr[mois - 1]; } return 'Mois $mois'; } @override List get props => [ id, membreId, membreNom, membrePrenom, organisationId, organisationNom, type, statut, montant, montantPaye, devise, dateEcheance, datePaiement, dateRappel, methodePaiement, numeroPaiement, referencePaiement, annee, mois, trimestre, semestre, description, notes, recu, dateCreation, dateModification, creeParId, modifieParId, ]; @override String toString() => 'CotisationModel(id: $id, membre: $membreNomComplet, montant: $montant $devise, statut: $statut)'; }