/// BLoC pour la gestion des contributions library contributions_bloc; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../core/utils/logger.dart'; import '../data/models/contribution_model.dart'; import '../data/repositories/contribution_repository.dart'; import 'contributions_event.dart'; import 'contributions_state.dart'; /// BLoC pour gérer l'état des contributions via l'API backend class ContributionsBloc extends Bloc { final ContributionRepository _repository; ContributionsBloc(this._repository) : super(const ContributionsInitial()) { on(_onLoadContributions); on(_onLoadContributionById); on(_onCreateContribution); on(_onUpdateContribution); on(_onDeleteContribution); on(_onSearchContributions); on(_onLoadContributionsByMembre); on(_onLoadContributionsPayees); on(_onLoadContributionsNonPayees); on(_onLoadContributionsEnRetard); on(_onRecordPayment); on(_onLoadContributionsStats); on(_onGenerateAnnualContributions); on(_onSendPaymentReminder); } Future _onLoadContributions( LoadContributions event, Emitter emit, ) async { try { AppLogger.blocEvent('ContributionsBloc', 'LoadContributions', data: { 'page': event.page, 'size': event.size, }); emit(const ContributionsLoading(message: 'Chargement des contributions...')); final result = await _repository.getCotisations( page: event.page, size: event.size, ); emit(ContributionsLoaded( contributions: result.contributions, total: result.total, page: result.page, size: result.size, totalPages: result.totalPages, )); AppLogger.blocState('ContributionsBloc', 'ContributionsLoaded', data: { 'count': result.contributions.length, 'total': result.total, }); } catch (e, stackTrace) { AppLogger.error('Erreur lors du chargement des contributions', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur lors du chargement des contributions', error: e)); } } Future _onLoadContributionById( LoadContributionById event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Chargement de la contribution...')); final contribution = await _repository.getCotisationById(event.id); emit(ContributionDetailLoaded(contribution: contribution)); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Contribution non trouvée', error: e)); } } Future _onCreateContribution( CreateContribution event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Création de la contribution...')); final created = await _repository.createCotisation(event.contribution); emit(ContributionCreated(contribution: created)); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur lors de la création de la contribution', error: e)); } } Future _onUpdateContribution( UpdateContribution event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Mise à jour de la contribution...')); final updated = await _repository.updateCotisation(event.id, event.contribution); emit(ContributionUpdated(contribution: updated)); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur lors de la mise à jour', error: e)); } } Future _onDeleteContribution( DeleteContribution event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Suppression de la contribution...')); await _repository.deleteCotisation(event.id); emit(ContributionDeleted(id: event.id)); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur lors de la suppression', error: e)); } } Future _onSearchContributions( SearchContributions event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Recherche en cours...')); final result = await _repository.getCotisations( page: event.page, size: event.size, membreId: event.membreId, statut: event.statut?.name, type: event.type?.name, annee: event.annee, ); emit(ContributionsLoaded( contributions: result.contributions, total: result.total, page: result.page, size: result.size, totalPages: result.totalPages, )); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur lors de la recherche', error: e)); } } Future _onLoadContributionsByMembre( LoadContributionsByMembre event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Chargement des contributions du membre...')); final result = await _repository.getCotisations( page: event.page, size: event.size, membreId: event.membreId, ); emit(ContributionsLoaded( contributions: result.contributions, total: result.total, page: result.page, size: result.size, totalPages: result.totalPages, )); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur lors du chargement', error: e)); } } Future _onLoadContributionsPayees( LoadContributionsPayees event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Chargement des contributions payées...')); final result = await _repository.getCotisations( page: event.page, size: event.size, statut: 'PAYEE', ); emit(ContributionsLoaded( contributions: result.contributions, total: result.total, page: result.page, size: result.size, totalPages: result.totalPages, )); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur', error: e)); } } Future _onLoadContributionsNonPayees( LoadContributionsNonPayees event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Chargement des contributions non payées...')); final result = await _repository.getCotisations( page: event.page, size: event.size, statut: 'NON_PAYEE', ); emit(ContributionsLoaded( contributions: result.contributions, total: result.total, page: result.page, size: result.size, totalPages: result.totalPages, )); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur', error: e)); } } Future _onLoadContributionsEnRetard( LoadContributionsEnRetard event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Chargement des contributions en retard...')); final result = await _repository.getCotisations( page: event.page, size: event.size, statut: 'EN_RETARD', ); emit(ContributionsLoaded( contributions: result.contributions, total: result.total, page: result.page, size: result.size, totalPages: result.totalPages, )); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur', error: e)); } } Future _onRecordPayment( RecordPayment event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Enregistrement du paiement...')); final updated = await _repository.enregistrerPaiement( event.contributionId, montant: event.montant, datePaiement: event.datePaiement, methodePaiement: event.methodePaiement.name, numeroPaiement: event.numeroPaiement, referencePaiement: event.referencePaiement, ); emit(PaymentRecorded(contribution: updated)); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur lors de l\'enregistrement du paiement', error: e)); } } Future _onLoadContributionsStats( LoadContributionsStats event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Chargement des statistiques...')); final stats = await _repository.getStatistiques(); emit(ContributionsStatsLoaded(stats: stats.map((k, v) => MapEntry(k, (v is num) ? v.toDouble() : 0.0)))); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur', error: e)); } } Future _onGenerateAnnualContributions( GenerateAnnualContributions event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Génération des contributions...')); final count = await _repository.genererCotisationsAnnuelles(event.annee); emit(ContributionsGenerated(nombreGenere: count)); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur', error: e)); } } Future _onSendPaymentReminder( SendPaymentReminder event, Emitter emit, ) async { try { emit(const ContributionsLoading(message: 'Envoi du rappel...')); await _repository.envoyerRappel(event.contributionId); emit(ReminderSent(contributionId: event.contributionId)); } catch (e, stackTrace) { AppLogger.error('Erreur', error: e, stackTrace: stackTrace); emit(ContributionsError(message: 'Erreur', error: e)); } } }