330 lines
7.8 KiB
Dart
330 lines
7.8 KiB
Dart
/// 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<String, dynamic> json) =>
|
|
_$MembreCompletModelFromJson(json);
|
|
|
|
/// Conversion vers JSON
|
|
Map<String, dynamic> 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<Object?> 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)';
|
|
}
|
|
|