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,435 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/error/exceptions.dart';
import '../models/demande_aide_model.dart';
import '../models/proposition_aide_model.dart';
import '../models/evaluation_aide_model.dart';
/// Source de données locale pour le module solidarité
///
/// Cette classe gère le cache local des données de solidarité
/// pour permettre un fonctionnement hors ligne et améliorer les performances.
abstract class SolidariteLocalDataSource {
// Cache des demandes d'aide
Future<void> cacherDemandeAide(DemandeAideModel demande);
Future<DemandeAideModel?> obtenirDemandeAideCachee(String id);
Future<List<DemandeAideModel>> obtenirDemandesAideCachees();
Future<void> supprimerDemandeAideCachee(String id);
Future<void> viderCacheDemandesAide();
// Cache des propositions d'aide
Future<void> cacherPropositionAide(PropositionAideModel proposition);
Future<PropositionAideModel?> obtenirPropositionAideCachee(String id);
Future<List<PropositionAideModel>> obtenirPropositionsAideCachees();
Future<void> supprimerPropositionAideCachee(String id);
Future<void> viderCachePropositionsAide();
// Cache des évaluations
Future<void> cacherEvaluation(EvaluationAideModel evaluation);
Future<EvaluationAideModel?> obtenirEvaluationCachee(String id);
Future<List<EvaluationAideModel>> obtenirEvaluationsCachees();
Future<void> supprimerEvaluationCachee(String id);
Future<void> viderCacheEvaluations();
// Cache des statistiques
Future<void> cacherStatistiques(String organisationId, Map<String, dynamic> statistiques);
Future<Map<String, dynamic>?> obtenirStatistiquesCachees(String organisationId);
Future<void> supprimerStatistiquesCachees(String organisationId);
// Gestion du cache
Future<DateTime?> obtenirDateDerniereMiseAJour(String cacheKey);
Future<void> marquerMiseAJour(String cacheKey);
Future<bool> estCacheExpire(String cacheKey, Duration dureeValidite);
Future<void> viderToutCache();
}
/// Implémentation de la source de données locale
class SolidariteLocalDataSourceImpl implements SolidariteLocalDataSource {
final SharedPreferences sharedPreferences;
// Clés de cache
static const String _demandesAideKey = 'CACHED_DEMANDES_AIDE';
static const String _propositionsAideKey = 'CACHED_PROPOSITIONS_AIDE';
static const String _evaluationsKey = 'CACHED_EVALUATIONS';
static const String _statistiquesKey = 'CACHED_STATISTIQUES';
static const String _lastUpdatePrefix = 'LAST_UPDATE_';
// Durées de validité du cache
static const Duration _dureeValiditeDefaut = Duration(minutes: 15);
static const Duration _dureeValiditeStatistiques = Duration(hours: 1);
SolidariteLocalDataSourceImpl({required this.sharedPreferences});
// Cache des demandes d'aide
@override
Future<void> cacherDemandeAide(DemandeAideModel demande) async {
try {
final demandes = await obtenirDemandesAideCachees();
// Supprimer l'ancienne version si elle existe
demandes.removeWhere((d) => d.id == demande.id);
// Ajouter la nouvelle version
demandes.add(demande);
// Limiter le cache à 100 demandes maximum
if (demandes.length > 100) {
demandes.sort((a, b) => b.dateModification.compareTo(a.dateModification));
demandes.removeRange(100, demandes.length);
}
final jsonList = demandes.map((d) => d.toJson()).toList();
await sharedPreferences.setString(_demandesAideKey, jsonEncode(jsonList));
await marquerMiseAJour(_demandesAideKey);
} catch (e) {
throw CacheException(message: 'Erreur lors de la mise en cache de la demande: ${e.toString()}');
}
}
@override
Future<DemandeAideModel?> obtenirDemandeAideCachee(String id) async {
try {
final demandes = await obtenirDemandesAideCachees();
return demandes.cast<DemandeAideModel?>().firstWhere(
(d) => d?.id == id,
orElse: () => null,
);
} catch (e) {
return null;
}
}
@override
Future<List<DemandeAideModel>> obtenirDemandesAideCachees() async {
try {
final jsonString = sharedPreferences.getString(_demandesAideKey);
if (jsonString == null) return [];
final List<dynamic> jsonList = jsonDecode(jsonString);
return jsonList.map((json) => DemandeAideModel.fromJson(json)).toList();
} catch (e) {
return [];
}
}
@override
Future<void> supprimerDemandeAideCachee(String id) async {
try {
final demandes = await obtenirDemandesAideCachees();
demandes.removeWhere((d) => d.id == id);
final jsonList = demandes.map((d) => d.toJson()).toList();
await sharedPreferences.setString(_demandesAideKey, jsonEncode(jsonList));
} catch (e) {
throw CacheException(message: 'Erreur lors de la suppression de la demande du cache: ${e.toString()}');
}
}
@override
Future<void> viderCacheDemandesAide() async {
try {
await sharedPreferences.remove(_demandesAideKey);
await sharedPreferences.remove('$_lastUpdatePrefix$_demandesAideKey');
} catch (e) {
throw CacheException(message: 'Erreur lors de la suppression du cache des demandes: ${e.toString()}');
}
}
// Cache des propositions d'aide
@override
Future<void> cacherPropositionAide(PropositionAideModel proposition) async {
try {
final propositions = await obtenirPropositionsAideCachees();
// Supprimer l'ancienne version si elle existe
propositions.removeWhere((p) => p.id == proposition.id);
// Ajouter la nouvelle version
propositions.add(proposition);
// Limiter le cache à 100 propositions maximum
if (propositions.length > 100) {
propositions.sort((a, b) => b.dateModification.compareTo(a.dateModification));
propositions.removeRange(100, propositions.length);
}
final jsonList = propositions.map((p) => p.toJson()).toList();
await sharedPreferences.setString(_propositionsAideKey, jsonEncode(jsonList));
await marquerMiseAJour(_propositionsAideKey);
} catch (e) {
throw CacheException(message: 'Erreur lors de la mise en cache de la proposition: ${e.toString()}');
}
}
@override
Future<PropositionAideModel?> obtenirPropositionAideCachee(String id) async {
try {
final propositions = await obtenirPropositionsAideCachees();
return propositions.cast<PropositionAideModel?>().firstWhere(
(p) => p?.id == id,
orElse: () => null,
);
} catch (e) {
return null;
}
}
@override
Future<List<PropositionAideModel>> obtenirPropositionsAideCachees() async {
try {
final jsonString = sharedPreferences.getString(_propositionsAideKey);
if (jsonString == null) return [];
final List<dynamic> jsonList = jsonDecode(jsonString);
return jsonList.map((json) => PropositionAideModel.fromJson(json)).toList();
} catch (e) {
return [];
}
}
@override
Future<void> supprimerPropositionAideCachee(String id) async {
try {
final propositions = await obtenirPropositionsAideCachees();
propositions.removeWhere((p) => p.id == id);
final jsonList = propositions.map((p) => p.toJson()).toList();
await sharedPreferences.setString(_propositionsAideKey, jsonEncode(jsonList));
} catch (e) {
throw CacheException(message: 'Erreur lors de la suppression de la proposition du cache: ${e.toString()}');
}
}
@override
Future<void> viderCachePropositionsAide() async {
try {
await sharedPreferences.remove(_propositionsAideKey);
await sharedPreferences.remove('$_lastUpdatePrefix$_propositionsAideKey');
} catch (e) {
throw CacheException(message: 'Erreur lors de la suppression du cache des propositions: ${e.toString()}');
}
}
// Cache des évaluations
@override
Future<void> cacherEvaluation(EvaluationAideModel evaluation) async {
try {
final evaluations = await obtenirEvaluationsCachees();
// Supprimer l'ancienne version si elle existe
evaluations.removeWhere((e) => e.id == evaluation.id);
// Ajouter la nouvelle version
evaluations.add(evaluation);
// Limiter le cache à 200 évaluations maximum
if (evaluations.length > 200) {
evaluations.sort((a, b) => b.dateModification.compareTo(a.dateModification));
evaluations.removeRange(200, evaluations.length);
}
final jsonList = evaluations.map((e) => e.toJson()).toList();
await sharedPreferences.setString(_evaluationsKey, jsonEncode(jsonList));
await marquerMiseAJour(_evaluationsKey);
} catch (e) {
throw CacheException(message: 'Erreur lors de la mise en cache de l\'évaluation: ${e.toString()}');
}
}
@override
Future<EvaluationAideModel?> obtenirEvaluationCachee(String id) async {
try {
final evaluations = await obtenirEvaluationsCachees();
return evaluations.cast<EvaluationAideModel?>().firstWhere(
(e) => e?.id == id,
orElse: () => null,
);
} catch (e) {
return null;
}
}
@override
Future<List<EvaluationAideModel>> obtenirEvaluationsCachees() async {
try {
final jsonString = sharedPreferences.getString(_evaluationsKey);
if (jsonString == null) return [];
final List<dynamic> jsonList = jsonDecode(jsonString);
return jsonList.map((json) => EvaluationAideModel.fromJson(json)).toList();
} catch (e) {
return [];
}
}
@override
Future<void> supprimerEvaluationCachee(String id) async {
try {
final evaluations = await obtenirEvaluationsCachees();
evaluations.removeWhere((e) => e.id == id);
final jsonList = evaluations.map((e) => e.toJson()).toList();
await sharedPreferences.setString(_evaluationsKey, jsonEncode(jsonList));
} catch (e) {
throw CacheException(message: 'Erreur lors de la suppression de l\'évaluation du cache: ${e.toString()}');
}
}
@override
Future<void> viderCacheEvaluations() async {
try {
await sharedPreferences.remove(_evaluationsKey);
await sharedPreferences.remove('$_lastUpdatePrefix$_evaluationsKey');
} catch (e) {
throw CacheException(message: 'Erreur lors de la suppression du cache des évaluations: ${e.toString()}');
}
}
// Cache des statistiques
@override
Future<void> cacherStatistiques(String organisationId, Map<String, dynamic> statistiques) async {
try {
final key = '$_statistiquesKey$organisationId';
await sharedPreferences.setString(key, jsonEncode(statistiques));
await marquerMiseAJour(key);
} catch (e) {
throw CacheException(message: 'Erreur lors de la mise en cache des statistiques: ${e.toString()}');
}
}
@override
Future<Map<String, dynamic>?> obtenirStatistiquesCachees(String organisationId) async {
try {
final key = '$_statistiquesKey$organisationId';
final jsonString = sharedPreferences.getString(key);
if (jsonString == null) return null;
return Map<String, dynamic>.from(jsonDecode(jsonString));
} catch (e) {
return null;
}
}
@override
Future<void> supprimerStatistiquesCachees(String organisationId) async {
try {
final key = '$_statistiquesKey$organisationId';
await sharedPreferences.remove(key);
await sharedPreferences.remove('$_lastUpdatePrefix$key');
} catch (e) {
throw CacheException(message: 'Erreur lors de la suppression des statistiques du cache: ${e.toString()}');
}
}
// Gestion du cache
@override
Future<DateTime?> obtenirDateDerniereMiseAJour(String cacheKey) async {
try {
final timestamp = sharedPreferences.getInt('$_lastUpdatePrefix$cacheKey');
if (timestamp == null) return null;
return DateTime.fromMillisecondsSinceEpoch(timestamp);
} catch (e) {
return null;
}
}
@override
Future<void> marquerMiseAJour(String cacheKey) async {
try {
final timestamp = DateTime.now().millisecondsSinceEpoch;
await sharedPreferences.setInt('$_lastUpdatePrefix$cacheKey', timestamp);
} catch (e) {
throw CacheException(message: 'Erreur lors de la mise à jour du timestamp: ${e.toString()}');
}
}
@override
Future<bool> estCacheExpire(String cacheKey, Duration dureeValidite) async {
try {
final dateDerniereMiseAJour = await obtenirDateDerniereMiseAJour(cacheKey);
if (dateDerniereMiseAJour == null) return true;
final maintenant = DateTime.now();
final dureeEcoulee = maintenant.difference(dateDerniereMiseAJour);
return dureeEcoulee > dureeValidite;
} catch (e) {
return true; // En cas d'erreur, considérer le cache comme expiré
}
}
@override
Future<void> viderToutCache() async {
try {
await Future.wait([
viderCacheDemandesAide(),
viderCachePropositionsAide(),
viderCacheEvaluations(),
]);
// Supprimer toutes les statistiques cachées
final keys = sharedPreferences.getKeys();
final statistiquesKeys = keys.where((key) => key.startsWith(_statistiquesKey));
for (final key in statistiquesKeys) {
await sharedPreferences.remove(key);
await sharedPreferences.remove('$_lastUpdatePrefix$key');
}
} catch (e) {
throw CacheException(message: 'Erreur lors de la suppression complète du cache: ${e.toString()}');
}
}
/// Méthodes utilitaires pour la gestion du cache
/// Vérifie si le cache des demandes est valide
Future<bool> estCacheDemandesValide() async {
return !(await estCacheExpire(_demandesAideKey, _dureeValiditeDefaut));
}
/// Vérifie si le cache des propositions est valide
Future<bool> estCachePropositionsValide() async {
return !(await estCacheExpire(_propositionsAideKey, _dureeValiditeDefaut));
}
/// Vérifie si le cache des évaluations est valide
Future<bool> estCacheEvaluationsValide() async {
return !(await estCacheExpire(_evaluationsKey, _dureeValiditeDefaut));
}
/// Vérifie si le cache des statistiques est valide
Future<bool> estCacheStatistiquesValide(String organisationId) async {
final key = '$_statistiquesKey$organisationId';
return !(await estCacheExpire(key, _dureeValiditeStatistiques));
}
/// Obtient la taille approximative du cache en octets
Future<int> obtenirTailleCache() async {
try {
int taille = 0;
final demandes = sharedPreferences.getString(_demandesAideKey);
if (demandes != null) taille += demandes.length;
final propositions = sharedPreferences.getString(_propositionsAideKey);
if (propositions != null) taille += propositions.length;
final evaluations = sharedPreferences.getString(_evaluationsKey);
if (evaluations != null) taille += evaluations.length;
// Ajouter les statistiques
final keys = sharedPreferences.getKeys();
final statistiquesKeys = keys.where((key) => key.startsWith(_statistiquesKey));
for (final key in statistiquesKeys) {
final value = sharedPreferences.getString(key);
if (value != null) taille += value.length;
}
return taille;
} catch (e) {
return 0;
}
}
}

View File

@@ -0,0 +1,817 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../../../../core/error/exceptions.dart';
import '../../../../core/network/api_client.dart';
import '../models/demande_aide_model.dart';
import '../models/proposition_aide_model.dart';
import '../models/evaluation_aide_model.dart';
/// Source de données distante pour le module solidarité
///
/// Cette classe gère toutes les communications avec l'API REST
/// du backend UnionFlow pour les fonctionnalités de solidarité.
abstract class SolidariteRemoteDataSource {
// Demandes d'aide
Future<DemandeAideModel> creerDemandeAide(DemandeAideModel demande);
Future<DemandeAideModel> mettreAJourDemandeAide(DemandeAideModel demande);
Future<DemandeAideModel> obtenirDemandeAide(String id);
Future<DemandeAideModel> soumettreDemande(String demandeId);
Future<DemandeAideModel> evaluerDemande({
required String demandeId,
required String evaluateurId,
required String decision,
String? commentaire,
double? montantApprouve,
});
Future<List<DemandeAideModel>> rechercherDemandes({
String? organisationId,
String? typeAide,
String? statut,
String? demandeurId,
bool? urgente,
int page = 0,
int taille = 20,
});
Future<List<DemandeAideModel>> obtenirDemandesUrgentes(String organisationId);
Future<List<DemandeAideModel>> obtenirMesdemandes(String utilisateurId);
// Propositions d'aide
Future<PropositionAideModel> creerPropositionAide(PropositionAideModel proposition);
Future<PropositionAideModel> mettreAJourPropositionAide(PropositionAideModel proposition);
Future<PropositionAideModel> obtenirPropositionAide(String id);
Future<PropositionAideModel> changerStatutProposition({
required String propositionId,
required bool activer,
});
Future<List<PropositionAideModel>> rechercherPropositions({
String? organisationId,
String? typeAide,
String? proposantId,
bool? actives,
int page = 0,
int taille = 20,
});
Future<List<PropositionAideModel>> obtenirPropositionsActives(String typeAide);
Future<List<PropositionAideModel>> obtenirMeilleuresPropositions(int limite);
Future<List<PropositionAideModel>> obtenirMesPropositions(String utilisateurId);
// Matching
Future<List<PropositionAideModel>> trouverPropositionsCompatibles(String demandeId);
Future<List<DemandeAideModel>> trouverDemandesCompatibles(String propositionId);
Future<List<PropositionAideModel>> rechercherProposantsFinanciers(String demandeId);
// Évaluations
Future<EvaluationAideModel> creerEvaluation(EvaluationAideModel evaluation);
Future<EvaluationAideModel> mettreAJourEvaluation(EvaluationAideModel evaluation);
Future<EvaluationAideModel> obtenirEvaluation(String id);
Future<List<EvaluationAideModel>> obtenirEvaluationsDemande(String demandeId);
Future<List<EvaluationAideModel>> obtenirEvaluationsProposition(String propositionId);
Future<EvaluationAideModel> signalerEvaluation({
required String evaluationId,
required String motif,
});
Future<StatistiquesEvaluationModel> calculerMoyenneDemande(String demandeId);
Future<StatistiquesEvaluationModel> calculerMoyenneProposition(String propositionId);
// Statistiques
Future<Map<String, dynamic>> obtenirStatistiquesSolidarite(String organisationId);
}
/// Implémentation de la source de données distante
class SolidariteRemoteDataSourceImpl implements SolidariteRemoteDataSource {
final ApiClient apiClient;
static const String baseEndpoint = '/api/solidarite';
SolidariteRemoteDataSourceImpl({required this.apiClient});
// Demandes d'aide
@override
Future<DemandeAideModel> creerDemandeAide(DemandeAideModel demande) async {
try {
final response = await apiClient.post(
'$baseEndpoint/demandes',
data: demande.toJson(),
);
if (response.statusCode == 201) {
return DemandeAideModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors de la création de la demande d\'aide',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<DemandeAideModel> mettreAJourDemandeAide(DemandeAideModel demande) async {
try {
final response = await apiClient.put(
'$baseEndpoint/demandes/${demande.id}',
data: demande.toJson(),
);
if (response.statusCode == 200) {
return DemandeAideModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors de la mise à jour de la demande d\'aide',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<DemandeAideModel> obtenirDemandeAide(String id) async {
try {
final response = await apiClient.get('$baseEndpoint/demandes/$id');
if (response.statusCode == 200) {
return DemandeAideModel.fromJson(response.data);
} else if (response.statusCode == 404) {
throw NotFoundException(message: 'Demande d\'aide non trouvée');
} else {
throw ServerException(
message: 'Erreur lors de la récupération de la demande d\'aide',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException || e is NotFoundException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<DemandeAideModel> soumettreDemande(String demandeId) async {
try {
final response = await apiClient.post(
'$baseEndpoint/demandes/$demandeId/soumettre',
);
if (response.statusCode == 200) {
return DemandeAideModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors de la soumission de la demande',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<DemandeAideModel> evaluerDemande({
required String demandeId,
required String evaluateurId,
required String decision,
String? commentaire,
double? montantApprouve,
}) async {
try {
final data = {
'evaluateurId': evaluateurId,
'decision': decision,
if (commentaire != null) 'commentaire': commentaire,
if (montantApprouve != null) 'montantApprouve': montantApprouve,
};
final response = await apiClient.post(
'$baseEndpoint/demandes/$demandeId/evaluer',
data: data,
);
if (response.statusCode == 200) {
return DemandeAideModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors de l\'évaluation de la demande',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<List<DemandeAideModel>> rechercherDemandes({
String? organisationId,
String? typeAide,
String? statut,
String? demandeurId,
bool? urgente,
int page = 0,
int taille = 20,
}) async {
try {
final queryParams = <String, dynamic>{
'page': page,
'size': taille,
if (organisationId != null) 'organisationId': organisationId,
if (typeAide != null) 'typeAide': typeAide,
if (statut != null) 'statut': statut,
if (demandeurId != null) 'demandeurId': demandeurId,
if (urgente != null) 'urgente': urgente,
};
final response = await apiClient.get(
'$baseEndpoint/demandes/rechercher',
queryParameters: queryParams,
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data['content'];
return data.map((json) => DemandeAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la recherche des demandes',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<List<DemandeAideModel>> obtenirDemandesUrgentes(String organisationId) async {
try {
final response = await apiClient.get(
'$baseEndpoint/demandes/urgentes',
queryParameters: {'organisationId': organisationId},
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data;
return data.map((json) => DemandeAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la récupération des demandes urgentes',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<List<DemandeAideModel>> obtenirMesdemandes(String utilisateurId) async {
try {
final response = await apiClient.get(
'$baseEndpoint/demandes/mes-demandes',
queryParameters: {'utilisateurId': utilisateurId},
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data;
return data.map((json) => DemandeAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la récupération de vos demandes',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
// Propositions d'aide
@override
Future<PropositionAideModel> creerPropositionAide(PropositionAideModel proposition) async {
try {
final response = await apiClient.post(
'$baseEndpoint/propositions',
data: proposition.toJson(),
);
if (response.statusCode == 201) {
return PropositionAideModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors de la création de la proposition d\'aide',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<PropositionAideModel> mettreAJourPropositionAide(PropositionAideModel proposition) async {
try {
final response = await apiClient.put(
'$baseEndpoint/propositions/${proposition.id}',
data: proposition.toJson(),
);
if (response.statusCode == 200) {
return PropositionAideModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors de la mise à jour de la proposition d\'aide',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<PropositionAideModel> obtenirPropositionAide(String id) async {
try {
final response = await apiClient.get('$baseEndpoint/propositions/$id');
if (response.statusCode == 200) {
return PropositionAideModel.fromJson(response.data);
} else if (response.statusCode == 404) {
throw NotFoundException(message: 'Proposition d\'aide non trouvée');
} else {
throw ServerException(
message: 'Erreur lors de la récupération de la proposition d\'aide',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException || e is NotFoundException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<PropositionAideModel> changerStatutProposition({
required String propositionId,
required bool activer,
}) async {
try {
final endpoint = activer ? 'activer' : 'desactiver';
final response = await apiClient.post(
'$baseEndpoint/propositions/$propositionId/$endpoint',
);
if (response.statusCode == 200) {
return PropositionAideModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors du changement de statut de la proposition',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<List<PropositionAideModel>> rechercherPropositions({
String? organisationId,
String? typeAide,
String? proposantId,
bool? actives,
int page = 0,
int taille = 20,
}) async {
try {
final queryParams = <String, dynamic>{
'page': page,
'size': taille,
if (organisationId != null) 'organisationId': organisationId,
if (typeAide != null) 'typeAide': typeAide,
if (proposantId != null) 'proposantId': proposantId,
if (actives != null) 'actives': actives,
};
final response = await apiClient.get(
'$baseEndpoint/propositions/rechercher',
queryParameters: queryParams,
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data['content'];
return data.map((json) => PropositionAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la recherche des propositions',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<List<PropositionAideModel>> obtenirPropositionsActives(String typeAide) async {
try {
final response = await apiClient.get(
'$baseEndpoint/propositions/actives',
queryParameters: {'typeAide': typeAide},
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data;
return data.map((json) => PropositionAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la récupération des propositions actives',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<List<PropositionAideModel>> obtenirMeilleuresPropositions(int limite) async {
try {
final response = await apiClient.get(
'$baseEndpoint/propositions/meilleures',
queryParameters: {'limite': limite},
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data;
return data.map((json) => PropositionAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la récupération des meilleures propositions',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<List<PropositionAideModel>> obtenirMesPropositions(String utilisateurId) async {
try {
final response = await apiClient.get(
'$baseEndpoint/propositions/mes-propositions',
queryParameters: {'utilisateurId': utilisateurId},
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data;
return data.map((json) => PropositionAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la récupération de vos propositions',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
// Matching
@override
Future<List<PropositionAideModel>> trouverPropositionsCompatibles(String demandeId) async {
try {
final response = await apiClient.get(
'$baseEndpoint/matching/propositions-compatibles/$demandeId',
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data;
return data.map((json) => PropositionAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la recherche de propositions compatibles',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<List<DemandeAideModel>> trouverDemandesCompatibles(String propositionId) async {
try {
final response = await apiClient.get(
'$baseEndpoint/matching/demandes-compatibles/$propositionId',
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data;
return data.map((json) => DemandeAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la recherche de demandes compatibles',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<List<PropositionAideModel>> rechercherProposantsFinanciers(String demandeId) async {
try {
final response = await apiClient.get(
'$baseEndpoint/matching/proposants-financiers/$demandeId',
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data;
return data.map((json) => PropositionAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la recherche de proposants financiers',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
// Évaluations
@override
Future<EvaluationAideModel> creerEvaluation(EvaluationAideModel evaluation) async {
try {
final response = await apiClient.post(
'$baseEndpoint/evaluations',
data: evaluation.toJson(),
);
if (response.statusCode == 201) {
return EvaluationAideModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors de la création de l\'évaluation',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<EvaluationAideModel> mettreAJourEvaluation(EvaluationAideModel evaluation) async {
try {
final response = await apiClient.put(
'$baseEndpoint/evaluations/${evaluation.id}',
data: evaluation.toJson(),
);
if (response.statusCode == 200) {
return EvaluationAideModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors de la mise à jour de l\'évaluation',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<EvaluationAideModel> obtenirEvaluation(String id) async {
try {
final response = await apiClient.get('$baseEndpoint/evaluations/$id');
if (response.statusCode == 200) {
return EvaluationAideModel.fromJson(response.data);
} else if (response.statusCode == 404) {
throw NotFoundException(message: 'Évaluation non trouvée');
} else {
throw ServerException(
message: 'Erreur lors de la récupération de l\'évaluation',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException || e is NotFoundException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<List<EvaluationAideModel>> obtenirEvaluationsDemande(String demandeId) async {
try {
final response = await apiClient.get(
'$baseEndpoint/evaluations/demande/$demandeId',
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data;
return data.map((json) => EvaluationAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la récupération des évaluations de la demande',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<List<EvaluationAideModel>> obtenirEvaluationsProposition(String propositionId) async {
try {
final response = await apiClient.get(
'$baseEndpoint/evaluations/proposition/$propositionId',
);
if (response.statusCode == 200) {
final List<dynamic> data = response.data;
return data.map((json) => EvaluationAideModel.fromJson(json)).toList();
} else {
throw ServerException(
message: 'Erreur lors de la récupération des évaluations de la proposition',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<EvaluationAideModel> signalerEvaluation({
required String evaluationId,
required String motif,
}) async {
try {
final response = await apiClient.post(
'$baseEndpoint/evaluations/$evaluationId/signaler',
data: {'motif': motif},
);
if (response.statusCode == 200) {
return EvaluationAideModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors du signalement de l\'évaluation',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<StatistiquesEvaluationModel> calculerMoyenneDemande(String demandeId) async {
try {
final response = await apiClient.get(
'$baseEndpoint/evaluations/moyenne/demande/$demandeId',
);
if (response.statusCode == 200) {
return StatistiquesEvaluationModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors du calcul de la moyenne de la demande',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
@override
Future<StatistiquesEvaluationModel> calculerMoyenneProposition(String propositionId) async {
try {
final response = await apiClient.get(
'$baseEndpoint/evaluations/moyenne/proposition/$propositionId',
);
if (response.statusCode == 200) {
return StatistiquesEvaluationModel.fromJson(response.data);
} else {
throw ServerException(
message: 'Erreur lors du calcul de la moyenne de la proposition',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
// Statistiques
@override
Future<Map<String, dynamic>> obtenirStatistiquesSolidarite(String organisationId) async {
try {
final response = await apiClient.get(
'$baseEndpoint/statistiques',
queryParameters: {'organisationId': organisationId},
);
if (response.statusCode == 200) {
return Map<String, dynamic>.from(response.data);
} else {
throw ServerException(
message: 'Erreur lors de la récupération des statistiques',
statusCode: response.statusCode,
);
}
} catch (e) {
if (e is ServerException) rethrow;
throw ServerException(
message: 'Erreur de communication avec le serveur: ${e.toString()}',
);
}
}
}