Files
unionflow-mobile-apps/lib/features/organizations/data/models/organization_model.dart
2026-03-31 09:14:47 +00:00

425 lines
11 KiB
Dart

/// Modèle de données pour les organisations
/// Correspond au OrganizationDTO du backend
library organization_model;
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'organization_model.g.dart';
/// Énumération des statuts d'organisation
enum StatutOrganization {
@JsonValue('ACTIVE')
active,
@JsonValue('INACTIVE')
inactive,
@JsonValue('SUSPENDUE')
suspendue,
@JsonValue('DISSOUTE')
dissoute,
@JsonValue('EN_CREATION')
enCreation,
}
/// Extension pour les statuts d'organisation
extension StatutOrganizationExtension on StatutOrganization {
String get displayName {
switch (this) {
case StatutOrganization.active:
return 'Active';
case StatutOrganization.inactive:
return 'Inactive';
case StatutOrganization.suspendue:
return 'Suspendue';
case StatutOrganization.dissoute:
return 'Dissoute';
case StatutOrganization.enCreation:
return 'En création';
}
}
String get color {
switch (this) {
case StatutOrganization.active:
return '#10B981'; // Vert
case StatutOrganization.inactive:
return '#6B7280'; // Gris
case StatutOrganization.suspendue:
return '#F59E0B'; // Orange
case StatutOrganization.dissoute:
return '#EF4444'; // Rouge
case StatutOrganization.enCreation:
return '#3B82F6'; // Bleu
}
}
}
/// Énumération des types de tri pour les organisations
enum OrganizationSortType {
name,
creationDate,
memberCount,
type,
status,
}
/// Extension pour les types de tri d'organisation
extension OrganizationSortTypeExtension on OrganizationSortType {
String get displayName {
switch (this) {
case OrganizationSortType.name:
return 'Nom';
case OrganizationSortType.creationDate:
return 'Date de création';
case OrganizationSortType.memberCount:
return 'Nombre de membres';
case OrganizationSortType.type:
return 'Type';
case OrganizationSortType.status:
return 'Statut';
}
}
}
/// Modèle d'organisation mobile
@JsonSerializable()
class OrganizationModel extends Equatable {
/// Identifiant unique
final String? id;
/// Nom de l'organisation
final String nom;
/// Nom court ou sigle
final String? nomCourt;
/// Type d'organisation (code dynamique depuis /api/references/types-organisation)
@JsonKey(name: 'typeOrganisation')
final String typeOrganisation;
/// Statut de l'organisation
final StatutOrganization statut;
/// Description
final String? description;
/// Date de fondation
@JsonKey(name: 'dateFondation')
final DateTime? dateFondation;
/// Numéro d'enregistrement officiel
@JsonKey(name: 'numeroEnregistrement')
final String? numeroEnregistrement;
/// Email de contact
final String? email;
/// Téléphone
final String? telephone;
/// Téléphone secondaire
@JsonKey(name: 'telephoneSecondaire')
final String? telephoneSecondaire;
/// Email secondaire
@JsonKey(name: 'emailSecondaire')
final String? emailSecondaire;
/// Site web
@JsonKey(name: 'siteWeb')
final String? siteWeb;
/// Réseaux sociaux (JSON string)
@JsonKey(name: 'reseauxSociaux')
final String? reseauxSociaux;
/// 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;
/// Logo URL
final String? logo;
/// Nombre de membres
@JsonKey(name: 'nombreMembres')
final int nombreMembres;
/// Nombre d'administrateurs
@JsonKey(name: 'nombreAdministrateurs')
final int nombreAdministrateurs;
/// Nombre d'événements (fourni par l'API si disponible)
@JsonKey(name: 'nombreEvenements')
final int? nombreEvenements;
/// Budget annuel
@JsonKey(name: 'budgetAnnuel')
final double? budgetAnnuel;
/// Devise
final String devise;
/// Cotisation obligatoire
@JsonKey(name: 'cotisationObligatoire')
final bool cotisationObligatoire;
/// Montant cotisation annuelle
@JsonKey(name: 'montantCotisationAnnuelle')
final double? montantCotisationAnnuelle;
/// Objectifs
final String? objectifs;
/// Activités principales
@JsonKey(name: 'activitesPrincipales')
final String? activitesPrincipales;
/// Certifications
final String? certifications;
/// Partenaires
final String? partenaires;
/// Notes internes
final String? notes;
/// Libellé résolu du type d'organisation (lecture seule, depuis la réponse API)
@JsonKey(name: 'typeOrganisationLibelle')
final String? typeOrganisationLibelle;
/// Libellé résolu du statut (lecture seule, depuis la réponse API)
@JsonKey(name: 'statutLibelle')
final String? statutLibelle;
/// Organisation publique
@JsonKey(name: 'organisationPublique')
final bool organisationPublique;
/// Accepte nouveaux membres
@JsonKey(name: 'accepteNouveauxMembres')
final bool accepteNouveauxMembres;
/// Date de création
@JsonKey(name: 'dateCreation')
final DateTime? dateCreation;
/// Date de modification
@JsonKey(name: 'dateModification')
final DateTime? dateModification;
/// Actif
final bool actif;
const OrganizationModel({
this.id,
required this.nom,
this.nomCourt,
this.typeOrganisation = 'ASSOCIATION',
this.statut = StatutOrganization.active,
this.description,
this.dateFondation,
this.numeroEnregistrement,
this.email,
this.telephone,
this.telephoneSecondaire,
this.emailSecondaire,
this.siteWeb,
this.reseauxSociaux,
this.adresse,
this.ville,
this.codePostal,
this.region,
this.pays,
this.logo,
this.nombreMembres = 0,
this.nombreAdministrateurs = 0,
this.nombreEvenements,
this.budgetAnnuel,
this.devise = 'XOF',
this.cotisationObligatoire = false,
this.montantCotisationAnnuelle,
this.objectifs,
this.activitesPrincipales,
this.certifications,
this.partenaires,
this.notes,
this.typeOrganisationLibelle,
this.statutLibelle,
this.organisationPublique = true,
this.accepteNouveauxMembres = true,
this.dateCreation,
this.dateModification,
this.actif = true,
});
/// Factory depuis JSON
factory OrganizationModel.fromJson(Map<String, dynamic> json) =>
_$OrganizationModelFromJson(json);
/// Conversion vers JSON
Map<String, dynamic> toJson() => _$OrganizationModelToJson(this);
/// Copie avec modifications
OrganizationModel copyWith({
String? id,
String? nom,
String? nomCourt,
String? typeOrganisation,
StatutOrganization? statut,
String? description,
DateTime? dateFondation,
String? numeroEnregistrement,
String? email,
String? telephone,
String? telephoneSecondaire,
String? emailSecondaire,
String? siteWeb,
String? reseauxSociaux,
String? adresse,
String? ville,
String? codePostal,
String? region,
String? pays,
String? logo,
int? nombreMembres,
int? nombreAdministrateurs,
int? nombreEvenements,
double? budgetAnnuel,
String? devise,
bool? cotisationObligatoire,
double? montantCotisationAnnuelle,
String? objectifs,
String? activitesPrincipales,
String? certifications,
String? partenaires,
String? notes,
String? typeOrganisationLibelle,
String? statutLibelle,
bool? organisationPublique,
bool? accepteNouveauxMembres,
DateTime? dateCreation,
DateTime? dateModification,
bool? actif,
}) {
return OrganizationModel(
id: id ?? this.id,
nom: nom ?? this.nom,
nomCourt: nomCourt ?? this.nomCourt,
typeOrganisation: typeOrganisation ?? this.typeOrganisation,
statut: statut ?? this.statut,
description: description ?? this.description,
dateFondation: dateFondation ?? this.dateFondation,
numeroEnregistrement: numeroEnregistrement ?? this.numeroEnregistrement,
email: email ?? this.email,
telephone: telephone ?? this.telephone,
telephoneSecondaire: telephoneSecondaire ?? this.telephoneSecondaire,
emailSecondaire: emailSecondaire ?? this.emailSecondaire,
siteWeb: siteWeb ?? this.siteWeb,
reseauxSociaux: reseauxSociaux ?? this.reseauxSociaux,
adresse: adresse ?? this.adresse,
ville: ville ?? this.ville,
codePostal: codePostal ?? this.codePostal,
region: region ?? this.region,
pays: pays ?? this.pays,
logo: logo ?? this.logo,
nombreMembres: nombreMembres ?? this.nombreMembres,
nombreAdministrateurs: nombreAdministrateurs ?? this.nombreAdministrateurs,
nombreEvenements: nombreEvenements ?? this.nombreEvenements,
budgetAnnuel: budgetAnnuel ?? this.budgetAnnuel,
devise: devise ?? this.devise,
cotisationObligatoire: cotisationObligatoire ?? this.cotisationObligatoire,
montantCotisationAnnuelle: montantCotisationAnnuelle ?? this.montantCotisationAnnuelle,
objectifs: objectifs ?? this.objectifs,
activitesPrincipales: activitesPrincipales ?? this.activitesPrincipales,
certifications: certifications ?? this.certifications,
partenaires: partenaires ?? this.partenaires,
notes: notes ?? this.notes,
typeOrganisationLibelle: typeOrganisationLibelle ?? this.typeOrganisationLibelle,
statutLibelle: statutLibelle ?? this.statutLibelle,
organisationPublique: organisationPublique ?? this.organisationPublique,
accepteNouveauxMembres: accepteNouveauxMembres ?? this.accepteNouveauxMembres,
dateCreation: dateCreation ?? this.dateCreation,
dateModification: dateModification ?? this.dateModification,
actif: actif ?? this.actif,
);
}
/// Ancienneté en années
int get ancienneteAnnees {
if (dateFondation == null) return 0;
return DateTime.now().difference(dateFondation!).inDays ~/ 365;
}
/// Adresse complète formatée
String get adresseComplete {
final parts = <String>[];
if (adresse?.isNotEmpty == true) parts.add(adresse!);
if (ville?.isNotEmpty == true) parts.add(ville!);
if (codePostal?.isNotEmpty == true) parts.add(codePostal!);
if (region?.isNotEmpty == true) parts.add(region!);
if (pays?.isNotEmpty == true) parts.add(pays!);
return parts.join(', ');
}
/// Nom d'affichage
String get nomAffichage => nomCourt?.isNotEmpty == true ? '$nomCourt ($nom)' : nom;
@override
List<Object?> get props => [
id,
nom,
nomCourt,
typeOrganisation,
statut,
description,
dateFondation,
numeroEnregistrement,
email,
telephone,
telephoneSecondaire,
emailSecondaire,
siteWeb,
reseauxSociaux,
adresse,
ville,
codePostal,
region,
pays,
logo,
nombreMembres,
nombreAdministrateurs,
nombreEvenements,
budgetAnnuel,
devise,
cotisationObligatoire,
montantCotisationAnnuelle,
objectifs,
activitesPrincipales,
certifications,
partenaires,
notes,
typeOrganisationLibelle,
statutLibelle,
organisationPublique,
accepteNouveauxMembres,
dateCreation,
dateModification,
actif,
];
@override
String toString() => 'OrganisationModel(id: $id, nom: $nom, type: $typeOrganisation, statut: $statut)';
}