/// Modèle complet de données pour un membre /// Aligné avec le backend MembreDTO library membre_complete_model; import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; part 'membre_complete_model.g.dart'; /// Énumération des genres enum Genre { @JsonValue('HOMME') homme, @JsonValue('FEMME') femme, @JsonValue('AUTRE') autre, } /// Énumération des statuts de membre enum StatutMembre { @JsonValue('ACTIF') actif, @JsonValue('INACTIF') inactif, @JsonValue('SUSPENDU') suspendu, @JsonValue('EN_ATTENTE') enAttente, } /// Modèle complet d'un membre @JsonSerializable() class MembreCompletModel extends Equatable { /// Identifiant unique final String? id; /// Nom de famille final String nom; /// Prénom final String prenom; /// Email (unique) final String email; /// Téléphone final String? telephone; /// Date de naissance @JsonKey(name: 'dateNaissance') final DateTime? dateNaissance; /// Genre final Genre? genre; /// Adresse complète final String? adresse; /// Ville final String? ville; /// Code postal @JsonKey(name: 'codePostal') final String? codePostal; /// Région final String? region; /// Pays final String? pays; /// Profession final String? profession; /// Nationalité final String? nationalite; /// URL de la photo final String? photo; /// Statut du membre final StatutMembre statut; /// Rôle dans l'organisation final String? role; /// ID de l'organisation @JsonKey(name: 'organisationId') final String? organisationId; /// Nom de l'organisation (pour affichage) @JsonKey(name: 'organisationNom') final String? organisationNom; /// Date d'adhésion @JsonKey(name: 'dateAdhesion') final DateTime? dateAdhesion; /// Date de fin d'adhésion @JsonKey(name: 'dateFinAdhesion') final DateTime? dateFinAdhesion; /// Membre du bureau @JsonKey(name: 'membreBureau') final bool membreBureau; /// Est responsable final bool responsable; /// Fonction au bureau @JsonKey(name: 'fonctionBureau') final String? fonctionBureau; /// Numéro de membre (unique) @JsonKey(name: 'numeroMembre') final String? numeroMembre; /// Cotisation à jour @JsonKey(name: 'cotisationAJour') final bool cotisationAJour; /// Nombre d'événements participés @JsonKey(name: 'nombreEvenementsParticipes') final int nombreEvenementsParticipes; /// Dernière activité @JsonKey(name: 'derniereActivite') final DateTime? derniereActivite; /// Notes internes final String? notes; /// Date de création @JsonKey(name: 'dateCreation') final DateTime? dateCreation; /// Date de modification @JsonKey(name: 'dateModification') final DateTime? dateModification; /// Actif final bool actif; const MembreCompletModel({ this.id, required this.nom, required this.prenom, required this.email, this.telephone, this.dateNaissance, this.genre, this.adresse, this.ville, this.codePostal, this.region, this.pays, this.profession, this.nationalite, this.photo, this.statut = StatutMembre.actif, this.role, this.organisationId, this.organisationNom, this.dateAdhesion, this.dateFinAdhesion, this.membreBureau = false, this.responsable = false, this.fonctionBureau, this.numeroMembre, this.cotisationAJour = false, this.nombreEvenementsParticipes = 0, this.derniereActivite, this.notes, this.dateCreation, this.dateModification, this.actif = true, }); /// Création depuis JSON factory MembreCompletModel.fromJson(Map json) => _$MembreCompletModelFromJson(json); /// Conversion vers JSON Map toJson() => _$MembreCompletModelToJson(this); /// Copie avec modifications MembreCompletModel copyWith({ String? id, String? nom, String? prenom, String? email, String? telephone, DateTime? dateNaissance, Genre? genre, String? adresse, String? ville, String? codePostal, String? region, String? pays, String? profession, String? nationalite, String? photo, StatutMembre? statut, String? role, String? organisationId, String? organisationNom, DateTime? dateAdhesion, DateTime? dateFinAdhesion, bool? membreBureau, bool? responsable, String? fonctionBureau, String? numeroMembre, bool? cotisationAJour, int? nombreEvenementsParticipes, DateTime? derniereActivite, String? notes, DateTime? dateCreation, DateTime? dateModification, bool? actif, }) { return MembreCompletModel( id: id ?? this.id, nom: nom ?? this.nom, prenom: prenom ?? this.prenom, email: email ?? this.email, telephone: telephone ?? this.telephone, dateNaissance: dateNaissance ?? this.dateNaissance, genre: genre ?? this.genre, adresse: adresse ?? this.adresse, ville: ville ?? this.ville, codePostal: codePostal ?? this.codePostal, region: region ?? this.region, pays: pays ?? this.pays, profession: profession ?? this.profession, nationalite: nationalite ?? this.nationalite, photo: photo ?? this.photo, statut: statut ?? this.statut, role: role ?? this.role, organisationId: organisationId ?? this.organisationId, organisationNom: organisationNom ?? this.organisationNom, dateAdhesion: dateAdhesion ?? this.dateAdhesion, dateFinAdhesion: dateFinAdhesion ?? this.dateFinAdhesion, membreBureau: membreBureau ?? this.membreBureau, responsable: responsable ?? this.responsable, fonctionBureau: fonctionBureau ?? this.fonctionBureau, numeroMembre: numeroMembre ?? this.numeroMembre, cotisationAJour: cotisationAJour ?? this.cotisationAJour, nombreEvenementsParticipes: nombreEvenementsParticipes ?? this.nombreEvenementsParticipes, derniereActivite: derniereActivite ?? this.derniereActivite, notes: notes ?? this.notes, dateCreation: dateCreation ?? this.dateCreation, dateModification: dateModification ?? this.dateModification, actif: actif ?? this.actif, ); } /// Nom complet String get nomComplet => '$prenom $nom'; /// Initiales String get initiales { final p = prenom.isNotEmpty ? prenom[0].toUpperCase() : ''; final n = nom.isNotEmpty ? nom[0].toUpperCase() : ''; return '$p$n'; } /// Âge calculé int? get age { if (dateNaissance == null) return null; final now = DateTime.now(); int age = now.year - dateNaissance!.year; if (now.month < dateNaissance!.month || (now.month == dateNaissance!.month && now.day < dateNaissance!.day)) { age--; } return age; } /// Ancienneté en jours int? get ancienneteJours { if (dateAdhesion == null) return null; return DateTime.now().difference(dateAdhesion!).inDays; } /// Est actif et cotisation à jour bool get estActifEtAJour => actif && statut == StatutMembre.actif && cotisationAJour; @override List get props => [ id, nom, prenom, email, telephone, dateNaissance, genre, adresse, ville, codePostal, region, pays, profession, nationalite, photo, statut, role, organisationId, organisationNom, dateAdhesion, dateFinAdhesion, membreBureau, responsable, fonctionBureau, numeroMembre, cotisationAJour, nombreEvenementsParticipes, derniereActivite, notes, dateCreation, dateModification, actif, ]; @override String toString() => 'MembreCompletModel(id: $id, nom: $nomComplet, email: $email, statut: $statut)'; }