/// Repository pour la gestion des adhésions (demandes d'adhésion) /// Interface avec l'API backend AdhesionResource library adhesion_repository; import 'package:dio/dio.dart'; import 'package:injectable/injectable.dart'; import 'package:unionflow_mobile_apps/core/network/api_client.dart'; import '../models/adhesion_model.dart'; abstract class AdhesionRepository { Future> getAll({int page = 0, int size = 20}); Future getById(String id); Future create(AdhesionModel adhesion); Future approuver(String id, {String? approuvePar}); Future rejeter(String id, String motifRejet); Future enregistrerPaiement( String id, { required double montantPaye, String? methodePaiement, String? referencePaiement, }); Future> getByMembre(String membreId, {int page = 0, int size = 20}); Future> getByOrganisation(String organisationId, {int page = 0, int size = 20}); Future> getByStatut(String statut, {int page = 0, int size = 20}); Future> getEnAttente({int page = 0, int size = 20}); Future?> getStats(); } @LazySingleton(as: AdhesionRepository) class AdhesionRepositoryImpl implements AdhesionRepository { final ApiClient _apiClient; static const String _base = '/api/adhesions'; AdhesionRepositoryImpl(this._apiClient); /// Parse une réponse API : liste directe ou objet paginé avec clé "content". List _parseListResponse(dynamic data) { if (data is List) { return data .map((e) => AdhesionModel.fromJson(e as Map)) .toList(); } if (data is Map && data.containsKey('content')) { final content = data['content'] as List? ?? []; return content .map((e) => AdhesionModel.fromJson(e as Map)) .toList(); } return []; } @override Future> getAll({int page = 0, int size = 20}) async { final response = await _apiClient.get( _base, queryParameters: {'page': page, 'size': size}, ); if (response.statusCode == 200) { return _parseListResponse(response.data); } throw Exception('Erreur ${response.statusCode}'); } @override Future getById(String id) async { final response = await _apiClient.get('$_base/$id'); if (response.statusCode == 200) { return AdhesionModel.fromJson(response.data as Map); } if (response.statusCode == 404) return null; throw Exception('Erreur ${response.statusCode}'); } @override Future create(AdhesionModel adhesion) async { final body = adhesion.toJson(); // Backend attend membreId, organisationId, fraisAdhesion, codeDevise (optionnel) final response = await _apiClient.post(_base, data: body); if (response.statusCode == 201 || response.statusCode == 200) { return AdhesionModel.fromJson(response.data as Map); } throw Exception('Erreur création: ${response.statusCode}'); } @override Future approuver(String id, {String? approuvePar}) async { final response = await _apiClient.post( '$_base/$id/approuver', queryParameters: approuvePar != null ? {'approuvePar': approuvePar} : null, ); if (response.statusCode == 200) { return AdhesionModel.fromJson(response.data as Map); } throw Exception('Erreur approbation: ${response.statusCode}'); } @override Future rejeter(String id, String motifRejet) async { final response = await _apiClient.post( '$_base/$id/rejeter', queryParameters: {'motifRejet': motifRejet}, ); if (response.statusCode == 200) { return AdhesionModel.fromJson(response.data as Map); } throw Exception('Erreur rejet: ${response.statusCode}'); } @override Future enregistrerPaiement( String id, { required double montantPaye, String? methodePaiement, String? referencePaiement, }) async { final q = {'montantPaye': montantPaye}; if (methodePaiement != null) q['methodePaiement'] = methodePaiement; if (referencePaiement != null) q['referencePaiement'] = referencePaiement; final response = await _apiClient.post('$_base/$id/paiement', queryParameters: q); if (response.statusCode == 200) { return AdhesionModel.fromJson(response.data as Map); } throw Exception('Erreur paiement: ${response.statusCode}'); } @override Future> getByMembre(String membreId, {int page = 0, int size = 20}) async { final response = await _apiClient.get( '$_base/membre/$membreId', queryParameters: {'page': page, 'size': size}, ); if (response.statusCode == 200) { return _parseListResponse(response.data); } throw Exception('Erreur ${response.statusCode}'); } @override Future> getByOrganisation(String organisationId, {int page = 0, int size = 20}) async { final response = await _apiClient.get( '$_base/organisation/$organisationId', queryParameters: {'page': page, 'size': size}, ); if (response.statusCode == 200) { return _parseListResponse(response.data); } throw Exception('Erreur ${response.statusCode}'); } @override Future> getByStatut(String statut, {int page = 0, int size = 20}) async { final response = await _apiClient.get( '$_base/statut/$statut', queryParameters: {'page': page, 'size': size}, ); if (response.statusCode == 200) { return _parseListResponse(response.data); } throw Exception('Erreur ${response.statusCode}'); } @override Future> getEnAttente({int page = 0, int size = 20}) async { final response = await _apiClient.get( '$_base/en-attente', queryParameters: {'page': page, 'size': size}, ); if (response.statusCode == 200) { return _parseListResponse(response.data); } throw Exception('Erreur ${response.statusCode}'); } @override Future?> getStats() async { final response = await _apiClient.get('$_base/stats'); if (response.statusCode == 200) { return response.data as Map; } return null; } }