import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../domain/usecases/get_attendance_records_usecase.dart'; import '../../../domain/usecases/get_extra_hours_usecase.dart'; import '../../../domain/usecases/get_rewards_usecase.dart'; import '../../../domain/usecases/get_punishments_usecase.dart'; import '../../../domain/usecases/get_salary_summary_usecase.dart'; import '../../../domain/models/finance_record.dart'; import '../../../domain/models/finance_category.dart'; import '../../../core/error/exceptions.dart'; // Events abstract class FinanceEvent {} class LoadFinanceDataEvent extends FinanceEvent { final String employeeId; final FinanceCategory category; final int? month; final int? year; LoadFinanceDataEvent({ required this.employeeId, required this.category, this.month, this.year, }); } // States abstract class FinanceState {} class FinanceInitial extends FinanceState {} class FinanceLoading extends FinanceState {} class FinanceLoaded extends FinanceState { final List records; final FinanceCategory category; final double netSalary; FinanceLoaded({ required this.records, required this.category, this.netSalary = 0.0, }); } class FinanceError extends FinanceState { final String message; FinanceError({required this.message}); } // Bloc class FinanceBloc extends Bloc { final GetAttendanceRecordsUseCase getAttendanceRecordsUseCase; final GetExtraHoursUseCase getExtraHoursUseCase; final GetRewardsUseCase getRewardsUseCase; final GetPunishmentsUseCase getPunishmentsUseCase; final GetSalarySummaryUseCase getSalarySummaryUseCase; FinanceBloc({ required this.getAttendanceRecordsUseCase, required this.getExtraHoursUseCase, required this.getRewardsUseCase, required this.getPunishmentsUseCase, required this.getSalarySummaryUseCase, }) : super(FinanceInitial()) { on(_onLoadFinanceData); } Future _onLoadFinanceData( LoadFinanceDataEvent event, Emitter emit, ) async { if (event.employeeId.isEmpty) { emit(FinanceError(message: 'Employee ID is missing or invalid')); return; } emit(FinanceLoading()); try { final now = DateTime.now(); final month = event.month ?? now.month; final year = event.year ?? now.year; double netSalary = 0.0; print( 'Fetching salary for Employee: ${event.employeeId}, Month: $month, Year: $year', ); try { final salaryModel = await getSalarySummaryUseCase.execute( employeeId: event.employeeId, month: month, year: year, ); print('Salary Model fetched: ${salaryModel.netAmount}'); netSalary = salaryModel.netAmount; } catch (e) { print('Error fetching salary: $e'); // We continue even if salary fails, to show the list at least } List records; switch (event.category) { case FinanceCategory.attendance: records = await getAttendanceRecordsUseCase.execute( employeeId: event.employeeId, ); break; case FinanceCategory.overtime: records = await getExtraHoursUseCase.execute( employeeId: event.employeeId, ); break; case FinanceCategory.bonus: records = await getRewardsUseCase.execute( employeeId: event.employeeId, ); break; case FinanceCategory.penalty: records = await getPunishmentsUseCase.execute( employeeId: event.employeeId, ); break; } emit( FinanceLoaded( records: records, category: event.category, netSalary: netSalary, ), ); } on ServerException catch (e) { emit(FinanceError(message: e.message)); } on NetworkException catch (e) { emit(FinanceError(message: e.message)); } catch (e) { emit(FinanceError(message: 'Unexpected error occurred: ${e.toString()}')); } } }