Files
unionflow-mobile-apps/lib/features/finance_workflow/presentation/bloc/budget_bloc.dart
dahoud d094d6db9c Initial commit: unionflow-mobile-apps
Application Flutter complète (sans build artifacts).

Signed-off-by: lions dev Team
2026-03-15 16:30:08 +00:00

188 lines
4.8 KiB
Dart

/// BLoC pour la gestion des budgets
library budget_bloc;
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart';
import '../../domain/usecases/get_budgets.dart';
import '../../domain/usecases/get_budget_by_id.dart';
import '../../domain/usecases/create_budget.dart';
import '../../domain/usecases/get_budget_tracking.dart';
import 'budget_event.dart';
import 'budget_state.dart';
@injectable
class BudgetBloc extends Bloc<BudgetEvent, BudgetState> {
final GetBudgets getBudgets;
final GetBudgetById getBudgetById;
final CreateBudget createBudget;
final GetBudgetTracking getBudgetTracking;
BudgetBloc({
required this.getBudgets,
required this.getBudgetById,
required this.createBudget,
required this.getBudgetTracking,
}) : super(const BudgetInitial()) {
on<LoadBudgets>(_onLoadBudgets);
on<LoadBudgetById>(_onLoadBudgetById);
on<CreateBudgetEvent>(_onCreateBudget);
on<LoadBudgetTracking>(_onLoadBudgetTracking);
on<RefreshBudgets>(_onRefreshBudgets);
on<FilterBudgets>(_onFilterBudgets);
}
Future<void> _onLoadBudgets(
LoadBudgets event,
Emitter<BudgetState> emit,
) async {
emit(const BudgetsLoading());
final result = await getBudgets(
organizationId: event.organizationId,
status: event.status,
year: event.year,
);
result.fold(
(failure) => emit(BudgetError(failure.message)),
(budgets) {
if (budgets.isEmpty) {
emit(const BudgetsEmpty());
} else {
emit(BudgetsLoaded(
budgets: budgets,
filterStatus: event.status,
filterYear: event.year,
));
}
},
);
}
Future<void> _onLoadBudgetById(
LoadBudgetById event,
Emitter<BudgetState> emit,
) async {
emit(const BudgetsLoading());
final result = await getBudgetById(event.budgetId);
result.fold(
(failure) => emit(BudgetError(failure.message)),
(budget) => emit(BudgetDetailLoaded(budget)),
);
}
Future<void> _onCreateBudget(
CreateBudgetEvent event,
Emitter<BudgetState> emit,
) async {
emit(const BudgetActionInProgress('create'));
final result = await createBudget(
name: event.name,
description: event.description,
organizationId: event.organizationId,
period: event.period,
year: event.year,
month: event.month,
lines: event.lines,
);
result.fold(
(failure) => emit(BudgetError(failure.message)),
(budget) => emit(BudgetCreated(budget: budget)),
);
}
Future<void> _onLoadBudgetTracking(
LoadBudgetTracking event,
Emitter<BudgetState> emit,
) async {
emit(const BudgetsLoading());
// Load budget first
final budgetResult = await getBudgetById(event.budgetId);
await budgetResult.fold(
(failure) async => emit(BudgetError(failure.message)),
(budget) async {
// Then load tracking
final trackingResult = await getBudgetTracking(budgetId: event.budgetId);
trackingResult.fold(
(failure) => emit(BudgetError(failure.message)),
(tracking) => emit(BudgetTrackingLoaded(
budget: budget,
tracking: tracking,
)),
);
},
);
}
Future<void> _onRefreshBudgets(
RefreshBudgets event,
Emitter<BudgetState> emit,
) async {
final result = await getBudgets(
organizationId: event.organizationId,
status: event.status,
year: event.year,
);
result.fold(
(failure) => emit(BudgetError(failure.message)),
(budgets) {
if (budgets.isEmpty) {
emit(const BudgetsEmpty());
} else {
emit(BudgetsLoaded(
budgets: budgets,
filterStatus: event.status,
filterYear: event.year,
));
}
},
);
}
Future<void> _onFilterBudgets(
FilterBudgets event,
Emitter<BudgetState> emit,
) async {
// Keep current organization if in loaded state
String? organizationId;
if (state is BudgetsLoaded) {
final currentState = state as BudgetsLoaded;
// Extract org ID from first budget if available
if (currentState.budgets.isNotEmpty) {
organizationId = currentState.budgets.first.organizationId;
}
}
emit(const BudgetsLoading());
final result = await getBudgets(
organizationId: organizationId,
status: event.status,
year: event.year,
);
result.fold(
(failure) => emit(BudgetError(failure.message)),
(budgets) {
if (budgets.isEmpty) {
emit(const BudgetsEmpty());
} else {
emit(BudgetsLoaded(
budgets: budgets,
filterStatus: event.status,
filterYear: event.year,
));
}
},
);
}
}