479 lines
13 KiB
Dart
479 lines
13 KiB
Dart
import 'package:equatable/equatable.dart';
|
|
import '../../../domain/entities/evaluation_aide.dart';
|
|
import 'evaluations_event.dart';
|
|
|
|
/// États pour la gestion des évaluations d'aide
|
|
///
|
|
/// Ces états représentent tous les états possibles
|
|
/// de l'interface utilisateur pour les évaluations d'aide.
|
|
abstract class EvaluationsState extends Equatable {
|
|
const EvaluationsState();
|
|
|
|
@override
|
|
List<Object?> get props => [];
|
|
}
|
|
|
|
/// État initial
|
|
class EvaluationsInitial extends EvaluationsState {
|
|
const EvaluationsInitial();
|
|
}
|
|
|
|
/// État de chargement
|
|
class EvaluationsLoading extends EvaluationsState {
|
|
final bool isRefreshing;
|
|
final bool isLoadingMore;
|
|
|
|
const EvaluationsLoading({
|
|
this.isRefreshing = false,
|
|
this.isLoadingMore = false,
|
|
});
|
|
|
|
@override
|
|
List<Object> get props => [isRefreshing, isLoadingMore];
|
|
}
|
|
|
|
/// État de succès avec données chargées
|
|
class EvaluationsLoaded extends EvaluationsState {
|
|
final List<EvaluationAide> evaluations;
|
|
final List<EvaluationAide> evaluationsFiltrees;
|
|
final bool hasReachedMax;
|
|
final int currentPage;
|
|
final int totalElements;
|
|
final Map<String, bool> evaluationsSelectionnees;
|
|
final TriEvaluations? criterieTri;
|
|
final bool triCroissant;
|
|
final FiltresEvaluations filtres;
|
|
final bool isRefreshing;
|
|
final bool isLoadingMore;
|
|
final DateTime lastUpdated;
|
|
|
|
const EvaluationsLoaded({
|
|
required this.evaluations,
|
|
required this.evaluationsFiltrees,
|
|
this.hasReachedMax = false,
|
|
this.currentPage = 0,
|
|
this.totalElements = 0,
|
|
this.evaluationsSelectionnees = const {},
|
|
this.criterieTri,
|
|
this.triCroissant = true,
|
|
this.filtres = const FiltresEvaluations(),
|
|
this.isRefreshing = false,
|
|
this.isLoadingMore = false,
|
|
required this.lastUpdated,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [
|
|
evaluations,
|
|
evaluationsFiltrees,
|
|
hasReachedMax,
|
|
currentPage,
|
|
totalElements,
|
|
evaluationsSelectionnees,
|
|
criterieTri,
|
|
triCroissant,
|
|
filtres,
|
|
isRefreshing,
|
|
isLoadingMore,
|
|
lastUpdated,
|
|
];
|
|
|
|
/// Copie l'état avec de nouvelles valeurs
|
|
EvaluationsLoaded copyWith({
|
|
List<EvaluationAide>? evaluations,
|
|
List<EvaluationAide>? evaluationsFiltrees,
|
|
bool? hasReachedMax,
|
|
int? currentPage,
|
|
int? totalElements,
|
|
Map<String, bool>? evaluationsSelectionnees,
|
|
TriEvaluations? criterieTri,
|
|
bool? triCroissant,
|
|
FiltresEvaluations? filtres,
|
|
bool? isRefreshing,
|
|
bool? isLoadingMore,
|
|
DateTime? lastUpdated,
|
|
}) {
|
|
return EvaluationsLoaded(
|
|
evaluations: evaluations ?? this.evaluations,
|
|
evaluationsFiltrees: evaluationsFiltrees ?? this.evaluationsFiltrees,
|
|
hasReachedMax: hasReachedMax ?? this.hasReachedMax,
|
|
currentPage: currentPage ?? this.currentPage,
|
|
totalElements: totalElements ?? this.totalElements,
|
|
evaluationsSelectionnees: evaluationsSelectionnees ?? this.evaluationsSelectionnees,
|
|
criterieTri: criterieTri ?? this.criterieTri,
|
|
triCroissant: triCroissant ?? this.triCroissant,
|
|
filtres: filtres ?? this.filtres,
|
|
isRefreshing: isRefreshing ?? this.isRefreshing,
|
|
isLoadingMore: isLoadingMore ?? this.isLoadingMore,
|
|
lastUpdated: lastUpdated ?? this.lastUpdated,
|
|
);
|
|
}
|
|
|
|
/// Obtient le nombre d'évaluations sélectionnées
|
|
int get nombreEvaluationsSelectionnees {
|
|
return evaluationsSelectionnees.values.where((selected) => selected).length;
|
|
}
|
|
|
|
/// Vérifie si toutes les évaluations sont sélectionnées
|
|
bool get toutesEvaluationsSelectionnees {
|
|
if (evaluationsFiltrees.isEmpty) return false;
|
|
return evaluationsFiltrees.every((evaluation) =>
|
|
evaluationsSelectionnees[evaluation.id] == true
|
|
);
|
|
}
|
|
|
|
/// Obtient les IDs des évaluations sélectionnées
|
|
List<String> get evaluationsSelectionneesIds {
|
|
return evaluationsSelectionnees.entries
|
|
.where((entry) => entry.value)
|
|
.map((entry) => entry.key)
|
|
.toList();
|
|
}
|
|
|
|
/// Obtient les évaluations sélectionnées
|
|
List<EvaluationAide> get evaluationsSelectionneesEntities {
|
|
return evaluations.where((evaluation) =>
|
|
evaluationsSelectionnees[evaluation.id] == true
|
|
).toList();
|
|
}
|
|
|
|
/// Vérifie si des données sont disponibles
|
|
bool get hasData => evaluations.isNotEmpty;
|
|
|
|
/// Vérifie si des filtres sont appliqués
|
|
bool get hasFiltres => !filtres.isEmpty;
|
|
|
|
/// Obtient le texte de statut
|
|
String get statusText {
|
|
if (isRefreshing) return 'Actualisation...';
|
|
if (isLoadingMore) return 'Chargement...';
|
|
if (evaluationsFiltrees.isEmpty && hasData) return 'Aucun résultat pour les filtres appliqués';
|
|
if (evaluationsFiltrees.isEmpty) return 'Aucune évaluation';
|
|
return '${evaluationsFiltrees.length} évaluation${evaluationsFiltrees.length > 1 ? 's' : ''}';
|
|
}
|
|
|
|
/// Obtient la note moyenne
|
|
double get noteMoyenne {
|
|
if (evaluationsFiltrees.isEmpty) return 0.0;
|
|
final notesValides = evaluationsFiltrees
|
|
.where((e) => e.noteGlobale != null)
|
|
.map((e) => e.noteGlobale!)
|
|
.toList();
|
|
if (notesValides.isEmpty) return 0.0;
|
|
return notesValides.reduce((a, b) => a + b) / notesValides.length;
|
|
}
|
|
|
|
/// Obtient le nombre d'évaluations par décision
|
|
Map<StatutAide, int> get repartitionDecisions {
|
|
final repartition = <StatutAide, int>{};
|
|
for (final evaluation in evaluationsFiltrees) {
|
|
repartition[evaluation.decision] = (repartition[evaluation.decision] ?? 0) + 1;
|
|
}
|
|
return repartition;
|
|
}
|
|
}
|
|
|
|
/// État d'erreur
|
|
class EvaluationsError extends EvaluationsState {
|
|
final String message;
|
|
final String? code;
|
|
final bool isNetworkError;
|
|
final bool canRetry;
|
|
final List<EvaluationAide>? cachedData;
|
|
|
|
const EvaluationsError({
|
|
required this.message,
|
|
this.code,
|
|
this.isNetworkError = false,
|
|
this.canRetry = true,
|
|
this.cachedData,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [
|
|
message,
|
|
code,
|
|
isNetworkError,
|
|
canRetry,
|
|
cachedData,
|
|
];
|
|
|
|
/// Vérifie si des données en cache sont disponibles
|
|
bool get hasCachedData => cachedData != null && cachedData!.isNotEmpty;
|
|
}
|
|
|
|
/// État de succès pour une opération spécifique
|
|
class EvaluationsOperationSuccess extends EvaluationsState {
|
|
final String message;
|
|
final EvaluationAide? evaluation;
|
|
final TypeOperationEvaluation operation;
|
|
|
|
const EvaluationsOperationSuccess({
|
|
required this.message,
|
|
this.evaluation,
|
|
required this.operation,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [message, evaluation, operation];
|
|
}
|
|
|
|
/// État de validation
|
|
class EvaluationsValidation extends EvaluationsState {
|
|
final Map<String, String> erreurs;
|
|
final bool isValid;
|
|
final EvaluationAide? evaluation;
|
|
|
|
const EvaluationsValidation({
|
|
required this.erreurs,
|
|
required this.isValid,
|
|
this.evaluation,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [erreurs, isValid, evaluation];
|
|
|
|
/// Obtient la première erreur
|
|
String? get premiereErreur {
|
|
return erreurs.values.isNotEmpty ? erreurs.values.first : null;
|
|
}
|
|
|
|
/// Obtient les erreurs pour un champ spécifique
|
|
String? getErreurPourChamp(String champ) {
|
|
return erreurs[champ];
|
|
}
|
|
}
|
|
|
|
/// État de calcul de note globale
|
|
class EvaluationsNoteCalculee extends EvaluationsState {
|
|
final double noteGlobale;
|
|
final Map<String, double> criteres;
|
|
|
|
const EvaluationsNoteCalculee({
|
|
required this.noteGlobale,
|
|
required this.criteres,
|
|
});
|
|
|
|
@override
|
|
List<Object> get props => [noteGlobale, criteres];
|
|
}
|
|
|
|
/// État des statistiques d'évaluation
|
|
class EvaluationsStatistiques extends EvaluationsState {
|
|
final Map<String, dynamic> statistiques;
|
|
final DateTime? dateDebut;
|
|
final DateTime? dateFin;
|
|
|
|
const EvaluationsStatistiques({
|
|
required this.statistiques,
|
|
this.dateDebut,
|
|
this.dateFin,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [statistiques, dateDebut, dateFin];
|
|
}
|
|
|
|
/// État d'export
|
|
class EvaluationsExporting extends EvaluationsState {
|
|
final double progress;
|
|
final String? currentStep;
|
|
|
|
const EvaluationsExporting({
|
|
required this.progress,
|
|
this.currentStep,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [progress, currentStep];
|
|
}
|
|
|
|
/// État d'export terminé
|
|
class EvaluationsExported extends EvaluationsState {
|
|
final String filePath;
|
|
final FormatExport format;
|
|
final int nombreEvaluations;
|
|
|
|
const EvaluationsExported({
|
|
required this.filePath,
|
|
required this.format,
|
|
required this.nombreEvaluations,
|
|
});
|
|
|
|
@override
|
|
List<Object> get props => [filePath, format, nombreEvaluations];
|
|
}
|
|
|
|
/// Classe pour les filtres des évaluations
|
|
class FiltresEvaluations extends Equatable {
|
|
final TypeEvaluateur? typeEvaluateur;
|
|
final StatutAide? decision;
|
|
final double? noteMin;
|
|
final double? noteMax;
|
|
final String? motCle;
|
|
final String? evaluateurId;
|
|
final String? demandeId;
|
|
final DateTime? dateDebutEvaluation;
|
|
final DateTime? dateFinEvaluation;
|
|
|
|
const FiltresEvaluations({
|
|
this.typeEvaluateur,
|
|
this.decision,
|
|
this.noteMin,
|
|
this.noteMax,
|
|
this.motCle,
|
|
this.evaluateurId,
|
|
this.demandeId,
|
|
this.dateDebutEvaluation,
|
|
this.dateFinEvaluation,
|
|
});
|
|
|
|
@override
|
|
List<Object?> get props => [
|
|
typeEvaluateur,
|
|
decision,
|
|
noteMin,
|
|
noteMax,
|
|
motCle,
|
|
evaluateurId,
|
|
demandeId,
|
|
dateDebutEvaluation,
|
|
dateFinEvaluation,
|
|
];
|
|
|
|
/// Copie les filtres avec de nouvelles valeurs
|
|
FiltresEvaluations copyWith({
|
|
TypeEvaluateur? typeEvaluateur,
|
|
StatutAide? decision,
|
|
double? noteMin,
|
|
double? noteMax,
|
|
String? motCle,
|
|
String? evaluateurId,
|
|
String? demandeId,
|
|
DateTime? dateDebutEvaluation,
|
|
DateTime? dateFinEvaluation,
|
|
}) {
|
|
return FiltresEvaluations(
|
|
typeEvaluateur: typeEvaluateur ?? this.typeEvaluateur,
|
|
decision: decision ?? this.decision,
|
|
noteMin: noteMin ?? this.noteMin,
|
|
noteMax: noteMax ?? this.noteMax,
|
|
motCle: motCle ?? this.motCle,
|
|
evaluateurId: evaluateurId ?? this.evaluateurId,
|
|
demandeId: demandeId ?? this.demandeId,
|
|
dateDebutEvaluation: dateDebutEvaluation ?? this.dateDebutEvaluation,
|
|
dateFinEvaluation: dateFinEvaluation ?? this.dateFinEvaluation,
|
|
);
|
|
}
|
|
|
|
/// Réinitialise tous les filtres
|
|
FiltresEvaluations clear() {
|
|
return const FiltresEvaluations();
|
|
}
|
|
|
|
/// Vérifie si les filtres sont vides
|
|
bool get isEmpty {
|
|
return typeEvaluateur == null &&
|
|
decision == null &&
|
|
noteMin == null &&
|
|
noteMax == null &&
|
|
(motCle == null || motCle!.isEmpty) &&
|
|
evaluateurId == null &&
|
|
demandeId == null &&
|
|
dateDebutEvaluation == null &&
|
|
dateFinEvaluation == null;
|
|
}
|
|
|
|
/// Obtient le nombre de filtres actifs
|
|
int get nombreFiltresActifs {
|
|
int count = 0;
|
|
if (typeEvaluateur != null) count++;
|
|
if (decision != null) count++;
|
|
if (noteMin != null) count++;
|
|
if (noteMax != null) count++;
|
|
if (motCle != null && motCle!.isNotEmpty) count++;
|
|
if (evaluateurId != null) count++;
|
|
if (demandeId != null) count++;
|
|
if (dateDebutEvaluation != null) count++;
|
|
if (dateFinEvaluation != null) count++;
|
|
return count;
|
|
}
|
|
|
|
/// Obtient une description textuelle des filtres
|
|
String get description {
|
|
final parts = <String>[];
|
|
|
|
if (typeEvaluateur != null) parts.add('Type: ${typeEvaluateur!.libelle}');
|
|
if (decision != null) parts.add('Décision: ${decision!.libelle}');
|
|
if (motCle != null && motCle!.isNotEmpty) parts.add('Recherche: "$motCle"');
|
|
if (noteMin != null || noteMax != null) {
|
|
if (noteMin != null && noteMax != null) {
|
|
parts.add('Note: ${noteMin!.toStringAsFixed(1)} - ${noteMax!.toStringAsFixed(1)}');
|
|
} else if (noteMin != null) {
|
|
parts.add('Note min: ${noteMin!.toStringAsFixed(1)}');
|
|
} else {
|
|
parts.add('Note max: ${noteMax!.toStringAsFixed(1)}');
|
|
}
|
|
}
|
|
|
|
return parts.join(', ');
|
|
}
|
|
}
|
|
|
|
/// Énumération pour les types d'opération
|
|
enum TypeOperationEvaluation {
|
|
creation,
|
|
modification,
|
|
soumission,
|
|
approbation,
|
|
rejet,
|
|
suppression,
|
|
export,
|
|
signalement,
|
|
}
|
|
|
|
/// Extension pour obtenir le libellé des opérations
|
|
extension TypeOperationEvaluationExtension on TypeOperationEvaluation {
|
|
String get libelle {
|
|
switch (this) {
|
|
case TypeOperationEvaluation.creation:
|
|
return 'Création';
|
|
case TypeOperationEvaluation.modification:
|
|
return 'Modification';
|
|
case TypeOperationEvaluation.soumission:
|
|
return 'Soumission';
|
|
case TypeOperationEvaluation.approbation:
|
|
return 'Approbation';
|
|
case TypeOperationEvaluation.rejet:
|
|
return 'Rejet';
|
|
case TypeOperationEvaluation.suppression:
|
|
return 'Suppression';
|
|
case TypeOperationEvaluation.export:
|
|
return 'Export';
|
|
case TypeOperationEvaluation.signalement:
|
|
return 'Signalement';
|
|
}
|
|
}
|
|
|
|
String get messageSucces {
|
|
switch (this) {
|
|
case TypeOperationEvaluation.creation:
|
|
return 'Évaluation créée avec succès';
|
|
case TypeOperationEvaluation.modification:
|
|
return 'Évaluation modifiée avec succès';
|
|
case TypeOperationEvaluation.soumission:
|
|
return 'Évaluation soumise avec succès';
|
|
case TypeOperationEvaluation.approbation:
|
|
return 'Évaluation approuvée avec succès';
|
|
case TypeOperationEvaluation.rejet:
|
|
return 'Évaluation rejetée avec succès';
|
|
case TypeOperationEvaluation.suppression:
|
|
return 'Évaluation supprimée avec succès';
|
|
case TypeOperationEvaluation.export:
|
|
return 'Export réalisé avec succès';
|
|
case TypeOperationEvaluation.signalement:
|
|
return 'Évaluation signalée avec succès';
|
|
}
|
|
}
|
|
}
|