Refactoring

This commit is contained in:
DahoudG
2025-09-17 17:54:06 +00:00
parent 12d514d866
commit 63fe107f98
165 changed files with 54220 additions and 276 deletions

View File

@@ -0,0 +1,323 @@
import 'package:equatable/equatable.dart';
/// Énumération des types de métriques disponibles
enum TypeMetrique {
// Métriques membres
nombreMembresActifs('Nombre de membres actifs', 'membres', 'count'),
nombreMembresInactifs('Nombre de membres inactifs', 'membres', 'count'),
tauxCroissanceMembres('Taux de croissance des membres', 'membres', 'percentage'),
moyenneAgeMembres('Âge moyen des membres', 'membres', 'average'),
// Métriques financières
totalCotisationsCollectees('Total des cotisations collectées', 'finance', 'amount'),
cotisationsEnAttente('Cotisations en attente', 'finance', 'amount'),
tauxRecouvrementCotisations('Taux de recouvrement', 'finance', 'percentage'),
moyenneCotisationMembre('Cotisation moyenne par membre', 'finance', 'average'),
// Métriques événements
nombreEvenementsOrganises('Nombre d\'événements organisés', 'evenements', 'count'),
tauxParticipationEvenements('Taux de participation aux événements', 'evenements', 'percentage'),
moyenneParticipantsEvenement('Moyenne de participants par événement', 'evenements', 'average'),
// Métriques solidarité
nombreDemandesAide('Nombre de demandes d\'aide', 'solidarite', 'count'),
montantAidesAccordees('Montant des aides accordées', 'solidarite', 'amount'),
tauxApprobationAides('Taux d\'approbation des aides', 'solidarite', 'percentage');
const TypeMetrique(this.libelle, this.categorie, this.typeValeur);
final String libelle;
final String categorie;
final String typeValeur;
/// Retourne l'unité de mesure appropriée
String get unite {
switch (typeValeur) {
case 'percentage':
return '%';
case 'amount':
return 'XOF';
case 'average':
return typeValeur == 'moyenneAgeMembres' ? 'ans' : '';
default:
return '';
}
}
/// Retourne l'icône Material Design appropriée
String get icone {
switch (categorie) {
case 'membres':
return 'people';
case 'finance':
return 'attach_money';
case 'evenements':
return 'event';
case 'solidarite':
return 'favorite';
default:
return 'analytics';
}
}
/// Retourne la couleur appropriée
String get couleur {
switch (categorie) {
case 'membres':
return '#2196F3';
case 'finance':
return '#4CAF50';
case 'evenements':
return '#FF9800';
case 'solidarite':
return '#E91E63';
default:
return '#757575';
}
}
}
/// Énumération des périodes d'analyse
enum PeriodeAnalyse {
aujourdHui('Aujourd\'hui', 'today'),
hier('Hier', 'yesterday'),
cetteSemaine('Cette semaine', 'this_week'),
semaineDerniere('Semaine dernière', 'last_week'),
ceMois('Ce mois', 'this_month'),
moisDernier('Mois dernier', 'last_month'),
troisDerniersMois('3 derniers mois', 'last_3_months'),
sixDerniersMois('6 derniers mois', 'last_6_months'),
cetteAnnee('Cette année', 'this_year'),
anneeDerniere('Année dernière', 'last_year'),
septDerniersJours('7 derniers jours', 'last_7_days'),
trenteDerniersJours('30 derniers jours', 'last_30_days'),
periodePersonnalisee('Période personnalisée', 'custom');
const PeriodeAnalyse(this.libelle, this.code);
final String libelle;
final String code;
/// Vérifie si la période est courte (moins d'un mois)
bool get isPeriodeCourte {
return [
aujourdHui,
hier,
cetteSemaine,
semaineDerniere,
septDerniersJours
].contains(this);
}
/// Vérifie si la période est longue (plus d'un an)
bool get isPeriodeLongue {
return [cetteAnnee, anneeDerniere].contains(this);
}
}
/// Entité représentant une donnée analytics
class AnalyticsData extends Equatable {
const AnalyticsData({
required this.id,
required this.typeMetrique,
required this.periodeAnalyse,
required this.valeur,
this.valeurPrecedente,
this.pourcentageEvolution,
required this.dateDebut,
required this.dateFin,
required this.dateCalcul,
this.organisationId,
this.nomOrganisation,
this.utilisateurId,
this.nomUtilisateur,
this.libellePersonnalise,
this.description,
this.donneesDetaillees,
this.configurationGraphique,
this.metadonnees,
this.indicateurFiabilite = 95.0,
this.nombreElementsAnalyses,
this.tempsCalculMs,
this.tempsReel = false,
this.necessiteMiseAJour = false,
this.niveauPriorite = 3,
this.tags,
});
final String id;
final TypeMetrique typeMetrique;
final PeriodeAnalyse periodeAnalyse;
final double valeur;
final double? valeurPrecedente;
final double? pourcentageEvolution;
final DateTime dateDebut;
final DateTime dateFin;
final DateTime dateCalcul;
final String? organisationId;
final String? nomOrganisation;
final String? utilisateurId;
final String? nomUtilisateur;
final String? libellePersonnalise;
final String? description;
final String? donneesDetaillees;
final String? configurationGraphique;
final Map<String, dynamic>? metadonnees;
final double indicateurFiabilite;
final int? nombreElementsAnalyses;
final int? tempsCalculMs;
final bool tempsReel;
final bool necessiteMiseAJour;
final int niveauPriorite;
final List<String>? tags;
/// Retourne le libellé à afficher
String get libelleAffichage {
return libellePersonnalise?.isNotEmpty == true
? libellePersonnalise!
: typeMetrique.libelle;
}
/// Retourne l'unité de mesure
String get unite => typeMetrique.unite;
/// Retourne l'icône
String get icone => typeMetrique.icone;
/// Retourne la couleur
String get couleur => typeMetrique.couleur;
/// Vérifie si la métrique a évolué positivement
bool get hasEvolutionPositive {
return pourcentageEvolution != null && pourcentageEvolution! > 0;
}
/// Vérifie si la métrique a évolué négativement
bool get hasEvolutionNegative {
return pourcentageEvolution != null && pourcentageEvolution! < 0;
}
/// Vérifie si la métrique est stable
bool get isStable {
return pourcentageEvolution != null && pourcentageEvolution! == 0;
}
/// Retourne la tendance sous forme de texte
String get tendance {
if (hasEvolutionPositive) return 'hausse';
if (hasEvolutionNegative) return 'baisse';
return 'stable';
}
/// Vérifie si les données sont fiables
bool get isDonneesFiables => indicateurFiabilite >= 80.0;
/// Vérifie si la métrique est critique
bool get isCritique => niveauPriorite >= 4;
/// Formate la valeur avec l'unité appropriée
String get valeurFormatee {
switch (typeMetrique.typeValeur) {
case 'amount':
return '${valeur.toStringAsFixed(0)} ${unite}';
case 'percentage':
return '${valeur.toStringAsFixed(1)}${unite}';
case 'average':
return valeur.toStringAsFixed(1);
default:
return valeur.toStringAsFixed(0);
}
}
/// Formate le pourcentage d'évolution
String get evolutionFormatee {
if (pourcentageEvolution == null) return '';
final signe = pourcentageEvolution! >= 0 ? '+' : '';
return '$signe${pourcentageEvolution!.toStringAsFixed(1)}%';
}
@override
List<Object?> get props => [
id,
typeMetrique,
periodeAnalyse,
valeur,
valeurPrecedente,
pourcentageEvolution,
dateDebut,
dateFin,
dateCalcul,
organisationId,
nomOrganisation,
utilisateurId,
nomUtilisateur,
libellePersonnalise,
description,
donneesDetaillees,
configurationGraphique,
metadonnees,
indicateurFiabilite,
nombreElementsAnalyses,
tempsCalculMs,
tempsReel,
necessiteMiseAJour,
niveauPriorite,
tags,
];
AnalyticsData copyWith({
String? id,
TypeMetrique? typeMetrique,
PeriodeAnalyse? periodeAnalyse,
double? valeur,
double? valeurPrecedente,
double? pourcentageEvolution,
DateTime? dateDebut,
DateTime? dateFin,
DateTime? dateCalcul,
String? organisationId,
String? nomOrganisation,
String? utilisateurId,
String? nomUtilisateur,
String? libellePersonnalise,
String? description,
String? donneesDetaillees,
String? configurationGraphique,
Map<String, dynamic>? metadonnees,
double? indicateurFiabilite,
int? nombreElementsAnalyses,
int? tempsCalculMs,
bool? tempsReel,
bool? necessiteMiseAJour,
int? niveauPriorite,
List<String>? tags,
}) {
return AnalyticsData(
id: id ?? this.id,
typeMetrique: typeMetrique ?? this.typeMetrique,
periodeAnalyse: periodeAnalyse ?? this.periodeAnalyse,
valeur: valeur ?? this.valeur,
valeurPrecedente: valeurPrecedente ?? this.valeurPrecedente,
pourcentageEvolution: pourcentageEvolution ?? this.pourcentageEvolution,
dateDebut: dateDebut ?? this.dateDebut,
dateFin: dateFin ?? this.dateFin,
dateCalcul: dateCalcul ?? this.dateCalcul,
organisationId: organisationId ?? this.organisationId,
nomOrganisation: nomOrganisation ?? this.nomOrganisation,
utilisateurId: utilisateurId ?? this.utilisateurId,
nomUtilisateur: nomUtilisateur ?? this.nomUtilisateur,
libellePersonnalise: libellePersonnalise ?? this.libellePersonnalise,
description: description ?? this.description,
donneesDetaillees: donneesDetaillees ?? this.donneesDetaillees,
configurationGraphique: configurationGraphique ?? this.configurationGraphique,
metadonnees: metadonnees ?? this.metadonnees,
indicateurFiabilite: indicateurFiabilite ?? this.indicateurFiabilite,
nombreElementsAnalyses: nombreElementsAnalyses ?? this.nombreElementsAnalyses,
tempsCalculMs: tempsCalculMs ?? this.tempsCalculMs,
tempsReel: tempsReel ?? this.tempsReel,
necessiteMiseAJour: necessiteMiseAJour ?? this.necessiteMiseAJour,
niveauPriorite: niveauPriorite ?? this.niveauPriorite,
tags: tags ?? this.tags,
);
}
}