import 'package:bloc/bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:injectable/injectable.dart' hide Order; import '../../../domain/order/order.dart'; import '../../../domain/printer/printer.dart'; part 'print_struck_event.dart'; part 'print_struck_state.dart'; part 'print_struck_bloc.freezed.dart'; @injectable class PrintStruckBloc extends Bloc { final IPrinterRepository _printerRepository; PrintStruckBloc(this._printerRepository) : super(PrintStruckState.initial()) { on(_onPrintStruckEvent); } Future _onPrintStruckEvent( PrintStruckEvent event, Emitter emit, ) => event.map( order: (e) => _print(emit, e.order, _stationsForOrder(e.order)), payment: (e) => _print(emit, e.order, const [PrintStation.receipt]), cashier: (e) => _print(emit, e.order, const [PrintStation.cashier]), checker: (e) => _print(emit, e.order, const [PrintStation.checker]), kitchen: (e) => _print(emit, e.order, const [PrintStation.kitchen]), bar: (e) => _print(emit, e.order, const [PrintStation.bar]), voided: (e) => _print(emit, e.order, const [PrintStation.voided]), splitBill: (e) => _print(emit, e.order, const [PrintStation.splitBill]), retryFailed: (_) { final order = state.order; final failed = [ for (final station in state.failedStations) station.station, ]; if (order == null || failed.isEmpty) return Future.value(); return _print(emit, order, failed); }, ); /// Struk pelanggan hanya ikut dicetak kalau ordernya sudah dibayar. List _stationsForOrder(Order order) => [ if (order.totalPaid > 0) PrintStation.receipt, PrintStation.cashier, PrintStation.checker, PrintStation.kitchen, PrintStation.bar, ]; Future _print( Emitter emit, Order order, List stations, ) async { // Tombol yang tertekan dua kali tidak boleh memulai job kedua — repository // akan mengantrikannya dan progres yang tampil jadi membingungkan. if (state.isPrinting) return; emit( state.copyWith( isPrinting: true, order: order, jobId: state.jobId + 1, stations: [ for (final station in stations) PrintStationResult.pending(station), ], ), ); await emit.forEach>( _printerRepository.printStations(order: order, stations: stations), onData: (results) => state.copyWith(stations: results), ); // Cetak bisa selesai setelah bloc ditutup (kasir keluar dari aplikasi). if (isClosed) return; emit(state.copyWith(isPrinting: false)); } }