Files
apskel-pos-flutter-v2/lib/application/printer/print_struck/print_struck_bloc.dart
T

83 lines
2.7 KiB
Dart
Raw Normal View History

2025-11-07 16:29:26 +07:00
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<PrintStruckEvent, PrintStruckState> {
final IPrinterRepository _printerRepository;
PrintStruckBloc(this._printerRepository) : super(PrintStruckState.initial()) {
on<PrintStruckEvent>(_onPrintStruckEvent);
}
Future<void> _onPrintStruckEvent(
PrintStruckEvent event,
Emitter<PrintStruckState> 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,
];
2025-11-07 16:29:26 +07:00
if (order == null || failed.isEmpty) return Future.value();
2025-11-07 16:29:26 +07:00
return _print(emit, order, failed);
},
);
2025-11-07 16:29:26 +07:00
/// Struk pelanggan hanya ikut dicetak kalau ordernya sudah dibayar.
List<PrintStation> _stationsForOrder(Order order) => [
if (order.totalPaid > 0) PrintStation.receipt,
PrintStation.cashier,
PrintStation.checker,
PrintStation.kitchen,
PrintStation.bar,
];
2025-11-07 16:29:26 +07:00
Future<void> _print(
Emitter<PrintStruckState> emit,
Order order,
List<PrintStation> 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;
2025-11-07 16:29:26 +07:00
emit(
state.copyWith(
isPrinting: true,
order: order,
jobId: state.jobId + 1,
stations: [
for (final station in stations) PrintStationResult.pending(station),
],
),
2025-11-07 16:29:26 +07:00
);
await emit.forEach<List<PrintStationResult>>(
_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));
2025-11-07 16:29:26 +07:00
}
}