import 'package:equatable/equatable.dart'; /// Entité représentant une demande d'aide dans le système de solidarité /// /// Cette entité encapsule toutes les informations relatives à une demande d'aide, /// incluant les détails du demandeur, le type d'aide, les montants et le statut. class DemandeAide extends Equatable { /// Identifiant unique de la demande final String id; /// Numéro de référence unique (format: DA-YYYY-NNNNNN) final String numeroReference; /// Titre de la demande d'aide final String titre; /// Description détaillée de la demande final String description; /// Type d'aide demandée final TypeAide typeAide; /// Statut actuel de la demande final StatutAide statut; /// Priorité de la demande final PrioriteAide priorite; /// Identifiant du demandeur final String demandeurId; /// Nom complet du demandeur final String nomDemandeur; /// Identifiant de l'organisation final String organisationId; /// Montant demandé (si applicable) final double? montantDemande; /// Montant approuvé (si applicable) final double? montantApprouve; /// Montant versé (si applicable) final double? montantVerse; /// Date de création de la demande final DateTime dateCreation; /// Date de modification final DateTime dateModification; /// Date de soumission final DateTime? dateSoumission; /// Date d'évaluation final DateTime? dateEvaluation; /// Date d'approbation final DateTime? dateApprobation; /// Date limite de traitement final DateTime? dateLimiteTraitement; /// Identifiant de l'évaluateur assigné final String? evaluateurId; /// Commentaires de l'évaluateur final String? commentairesEvaluateur; /// Motif de rejet (si applicable) final String? motifRejet; /// Informations complémentaires requises final String? informationsRequises; /// Justification de l'urgence final String? justificationUrgence; /// Contact d'urgence final ContactUrgence? contactUrgence; /// Localisation du demandeur final Localisation? localisation; /// Liste des bénéficiaires final List beneficiaires; /// Liste des pièces justificatives final List piecesJustificatives; /// Historique des changements de statut final List historiqueStatuts; /// Commentaires et échanges final List commentaires; /// Données personnalisées final Map donneesPersonnalisees; /// Indique si la demande est modifiable final bool estModifiable; /// Indique si la demande est urgente final bool estUrgente; /// Indique si le délai est dépassé final bool delaiDepasse; /// Indique si la demande est terminée final bool estTerminee; const DemandeAide({ required this.id, required this.numeroReference, required this.titre, required this.description, required this.typeAide, required this.statut, required this.priorite, required this.demandeurId, required this.nomDemandeur, required this.organisationId, this.montantDemande, this.montantApprouve, this.montantVerse, required this.dateCreation, required this.dateModification, this.dateSoumission, this.dateEvaluation, this.dateApprobation, this.dateLimiteTraitement, this.evaluateurId, this.commentairesEvaluateur, this.motifRejet, this.informationsRequises, this.justificationUrgence, this.contactUrgence, this.localisation, this.beneficiaires = const [], this.piecesJustificatives = const [], this.historiqueStatuts = const [], this.commentaires = const [], this.donneesPersonnalisees = const {}, this.estModifiable = false, this.estUrgente = false, this.delaiDepasse = false, this.estTerminee = false, }); /// Calcule le pourcentage d'avancement de la demande double get pourcentageAvancement { return statut.pourcentageAvancement; } /// Calcule le délai restant en heures int? get delaiRestantHeures { if (dateLimiteTraitement == null) return null; final maintenant = DateTime.now(); if (maintenant.isAfter(dateLimiteTraitement!)) return 0; return dateLimiteTraitement!.difference(maintenant).inHours; } /// Calcule la durée de traitement en jours int get dureeTraitementJours { if (dateSoumission == null) return 0; final dateFin = dateEvaluation ?? DateTime.now(); return dateFin.difference(dateSoumission!).inDays; } /// Indique si la demande nécessite une action urgente bool get necessiteActionUrgente { return estUrgente || delaiDepasse || priorite == PrioriteAide.critique; } /// Obtient la couleur associée au statut String get couleurStatut => statut.couleur; /// Obtient l'icône associée au type d'aide String get iconeTypeAide => typeAide.icone; @override List get props => [ id, numeroReference, titre, description, typeAide, statut, priorite, demandeurId, nomDemandeur, organisationId, montantDemande, montantApprouve, montantVerse, dateCreation, dateModification, dateSoumission, dateEvaluation, dateApprobation, dateLimiteTraitement, evaluateurId, commentairesEvaluateur, motifRejet, informationsRequises, justificationUrgence, contactUrgence, localisation, beneficiaires, piecesJustificatives, historiqueStatuts, commentaires, donneesPersonnalisees, estModifiable, estUrgente, delaiDepasse, estTerminee, ]; DemandeAide copyWith({ String? id, String? numeroReference, String? titre, String? description, TypeAide? typeAide, StatutAide? statut, PrioriteAide? priorite, String? demandeurId, String? nomDemandeur, String? organisationId, double? montantDemande, double? montantApprouve, double? montantVerse, DateTime? dateCreation, DateTime? dateModification, DateTime? dateSoumission, DateTime? dateEvaluation, DateTime? dateApprobation, DateTime? dateLimiteTraitement, String? evaluateurId, String? commentairesEvaluateur, String? motifRejet, String? informationsRequises, String? justificationUrgence, ContactUrgence? contactUrgence, Localisation? localisation, List? beneficiaires, List? piecesJustificatives, List? historiqueStatuts, List? commentaires, Map? donneesPersonnalisees, bool? estModifiable, bool? estUrgente, bool? delaiDepasse, bool? estTerminee, }) { return DemandeAide( id: id ?? this.id, numeroReference: numeroReference ?? this.numeroReference, titre: titre ?? this.titre, description: description ?? this.description, typeAide: typeAide ?? this.typeAide, statut: statut ?? this.statut, priorite: priorite ?? this.priorite, demandeurId: demandeurId ?? this.demandeurId, nomDemandeur: nomDemandeur ?? this.nomDemandeur, organisationId: organisationId ?? this.organisationId, montantDemande: montantDemande ?? this.montantDemande, montantApprouve: montantApprouve ?? this.montantApprouve, montantVerse: montantVerse ?? this.montantVerse, dateCreation: dateCreation ?? this.dateCreation, dateModification: dateModification ?? this.dateModification, dateSoumission: dateSoumission ?? this.dateSoumission, dateEvaluation: dateEvaluation ?? this.dateEvaluation, dateApprobation: dateApprobation ?? this.dateApprobation, dateLimiteTraitement: dateLimiteTraitement ?? this.dateLimiteTraitement, evaluateurId: evaluateurId ?? this.evaluateurId, commentairesEvaluateur: commentairesEvaluateur ?? this.commentairesEvaluateur, motifRejet: motifRejet ?? this.motifRejet, informationsRequises: informationsRequises ?? this.informationsRequises, justificationUrgence: justificationUrgence ?? this.justificationUrgence, contactUrgence: contactUrgence ?? this.contactUrgence, localisation: localisation ?? this.localisation, beneficiaires: beneficiaires ?? this.beneficiaires, piecesJustificatives: piecesJustificatives ?? this.piecesJustificatives, historiqueStatuts: historiqueStatuts ?? this.historiqueStatuts, commentaires: commentaires ?? this.commentaires, donneesPersonnalisees: donneesPersonnalisees ?? this.donneesPersonnalisees, estModifiable: estModifiable ?? this.estModifiable, estUrgente: estUrgente ?? this.estUrgente, delaiDepasse: delaiDepasse ?? this.delaiDepasse, estTerminee: estTerminee ?? this.estTerminee, ); } } /// Énumération des types d'aide disponibles enum TypeAide { aideFinanciereUrgente('Aide financière urgente', 'emergency_fund', '#F44336'), aideFinanciereMedicale('Aide financière médicale', 'medical_services', '#2196F3'), aideFinanciereEducation('Aide financière éducation', 'school', '#4CAF50'), aideMaterielleVetements('Aide matérielle vêtements', 'checkroom', '#FF9800'), aideMaterielleNourriture('Aide matérielle nourriture', 'restaurant', '#795548'), aideProfessionnelleFormation('Aide professionnelle formation', 'work', '#9C27B0'), aideSocialeAccompagnement('Aide sociale accompagnement', 'support', '#607D8B'), autre('Autre', 'help', '#9E9E9E'); const TypeAide(this.libelle, this.icone, this.couleur); final String libelle; final String icone; final String couleur; } /// Énumération des statuts de demande d'aide enum StatutAide { brouillon('Brouillon', 'draft', '#9E9E9E', 5.0), soumise('Soumise', 'send', '#2196F3', 10.0), enAttente('En attente', 'schedule', '#FF9800', 20.0), enCoursEvaluation('En cours d\'évaluation', 'assessment', '#9C27B0', 40.0), approuvee('Approuvée', 'check_circle', '#4CAF50', 70.0), approuveePartiellement('Approuvée partiellement', 'check_circle_outline', '#8BC34A', 70.0), rejetee('Rejetée', 'cancel', '#F44336', 100.0), informationsRequises('Informations requises', 'info', '#FF5722', 30.0), enCoursVersement('En cours de versement', 'payment', '#00BCD4', 85.0), versee('Versée', 'paid', '#4CAF50', 100.0), livree('Livrée', 'local_shipping', '#4CAF50', 100.0), terminee('Terminée', 'done_all', '#4CAF50', 100.0), cloturee('Clôturée', 'archive', '#607D8B', 100.0); const StatutAide(this.libelle, this.icone, this.couleur, this.pourcentageAvancement); final String libelle; final String icone; final String couleur; final double pourcentageAvancement; } /// Énumération des priorités de demande d'aide enum PrioriteAide { critique('Critique', '#F44336', 1, 24), urgente('Urgente', '#FF5722', 2, 72), elevee('Élevée', '#FF9800', 3, 168), normale('Normale', '#4CAF50', 4, 336), faible('Faible', '#9E9E9E', 5, 720); const PrioriteAide(this.libelle, this.couleur, this.niveau, this.delaiTraitementHeures); final String libelle; final String couleur; final int niveau; final int delaiTraitementHeures; } /// Classe représentant un contact d'urgence class ContactUrgence extends Equatable { final String nom; final String telephone; final String? email; final String relation; const ContactUrgence({ required this.nom, required this.telephone, this.email, required this.relation, }); @override List get props => [nom, telephone, email, relation]; } /// Classe représentant une localisation class Localisation extends Equatable { final String adresse; final String ville; final String? codePostal; final String? pays; final double? latitude; final double? longitude; const Localisation({ required this.adresse, required this.ville, this.codePostal, this.pays, this.latitude, this.longitude, }); @override List get props => [adresse, ville, codePostal, pays, latitude, longitude]; } /// Classe représentant un bénéficiaire d'aide class BeneficiaireAide extends Equatable { final String nom; final String prenom; final int age; final String relation; final String? telephone; const BeneficiaireAide({ required this.nom, required this.prenom, required this.age, required this.relation, this.telephone, }); @override List get props => [nom, prenom, age, relation, telephone]; } /// Classe représentant une pièce justificative class PieceJustificative extends Equatable { final String id; final String nom; final String type; final String url; final int taille; final DateTime dateAjout; const PieceJustificative({ required this.id, required this.nom, required this.type, required this.url, required this.taille, required this.dateAjout, }); @override List get props => [id, nom, type, url, taille, dateAjout]; } /// Classe représentant l'historique des statuts class HistoriqueStatut extends Equatable { final StatutAide ancienStatut; final StatutAide nouveauStatut; final DateTime dateChangement; final String? commentaire; final String? utilisateurId; const HistoriqueStatut({ required this.ancienStatut, required this.nouveauStatut, required this.dateChangement, this.commentaire, this.utilisateurId, }); @override List get props => [ancienStatut, nouveauStatut, dateChangement, commentaire, utilisateurId]; } /// Classe représentant un commentaire sur une demande class CommentaireAide extends Equatable { final String id; final String contenu; final String auteurId; final String nomAuteur; final DateTime dateCreation; final bool estPrive; const CommentaireAide({ required this.id, required this.contenu, required this.auteurId, required this.nomAuteur, required this.dateCreation, this.estPrive = false, }); @override List get props => [id, contenu, auteurId, nomAuteur, dateCreation, estPrive]; }