feat(loading): Abschluss-Dialog 'Alles gescannt - Auslieferung starten?' im Scanner
Sobald im Beladen-Scanner der letzte Pflicht-Scan erledigt ist (alle eigenen, aktiven Lieferungen im Standardlager fertig - gleiche Bedingung wie der 'Auslieferungs-Phase starten'-Gate der Uebersicht), erscheint einmalig ein Dialog: bestaetigt 'alles gescannt' und fragt, ob die Auslieferung starten soll. 'Auslieferung starten' -> PhaseSet(ausliefern) + Scanner schliessen; 'Spaeter' -> nur schliessen. BlocConsumer<TourBloc>-Listener + Einmal-Flag (Reset wenn wieder etwas offen). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -11,9 +11,12 @@ import 'package:hl_lieferservice/feature/car_selection/bloc/bloc.dart';
|
||||
import 'package:hl_lieferservice/feature/car_selection/bloc/state.dart';
|
||||
import 'package:hl_lieferservice/feature/cars/bloc/cars_bloc.dart';
|
||||
import 'package:hl_lieferservice/feature/cars/bloc/cars_state.dart';
|
||||
import 'package:hl_lieferservice/feature/delivery/bloc/phase_bloc.dart';
|
||||
import 'package:hl_lieferservice/feature/delivery/bloc/phase_event.dart';
|
||||
import 'package:hl_lieferservice/feature/delivery/bloc/tour_bloc.dart';
|
||||
import 'package:hl_lieferservice/feature/delivery/bloc/tour_event.dart';
|
||||
import 'package:hl_lieferservice/feature/delivery/bloc/tour_state.dart';
|
||||
import 'package:hl_lieferservice/feature/delivery/model/delivery_phase.dart';
|
||||
import 'package:hl_lieferservice/feature/loading/widget/reason_catalog.dart';
|
||||
import 'package:hl_lieferservice/feature/loading/widget/reason_picker_sheet.dart';
|
||||
import 'package:hl_lieferservice/widget/scanner/article_scanner_stripe.dart';
|
||||
@ -57,6 +60,10 @@ class _LoadingCustomerPageState extends State<LoadingCustomerPage> {
|
||||
/// vom (lebenslang einen) Scanner für die Barcode-Auflösung benutzt.
|
||||
int _currentIndex = 0;
|
||||
|
||||
/// Verhindert, dass der „Alles gescannt"-Abschluss-Dialog mehrfach erscheint.
|
||||
/// Wird zurückgesetzt, sobald wieder etwas zu beladen offen ist.
|
||||
bool _completionPromptShown = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@ -331,13 +338,78 @@ class _LoadingCustomerPageState extends State<LoadingCustomerPage> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Reagiert auf jedes TourBloc-Update: Sind ALLE eigenen, **aktiven**
|
||||
/// Lieferungen im Standardlager fertig beladen (dieselbe Bedingung wie der
|
||||
/// „Auslieferungs-Phase starten"-Gate der Beladen-Übersicht)? Genau beim
|
||||
/// Übergang „noch offen → alles fertig" (also nach dem letzten Pflicht-Scan)
|
||||
/// erscheint einmalig der Abschluss-Dialog.
|
||||
void _maybePromptLoadingComplete(
|
||||
BuildContext context,
|
||||
TourState state,
|
||||
String carId,
|
||||
) {
|
||||
if (state is! TourLoaded) return;
|
||||
final deliveries = _ownInLoadingOrder(context, state.details, carId);
|
||||
final active =
|
||||
deliveries.where((d) => d.state == DeliveryState.active).toList();
|
||||
final allDone = active.isNotEmpty &&
|
||||
active.every(state.details.standardWarehouseLoadingDone);
|
||||
|
||||
if (!allDone) {
|
||||
// Wieder etwas offen (Item entfernt/zurückgesetzt) → Dialog darf erneut.
|
||||
_completionPromptShown = false;
|
||||
return;
|
||||
}
|
||||
if (_completionPromptShown) return;
|
||||
_completionPromptShown = true;
|
||||
_showLoadingCompleteDialog(carId);
|
||||
}
|
||||
|
||||
/// Abschluss-Dialog der Beladung: weist darauf hin, dass alles gescannt ist,
|
||||
/// und fragt, ob die Auslieferung gestartet werden soll. Bei „Ja" wird die
|
||||
/// Phase auf `ausliefern` gesetzt (PhaseBloc, app-weit) und der Scanner
|
||||
/// geschlossen — der Phasen-Router (`home`) zeigt dann die Auslieferungs-
|
||||
/// Übersicht. „Später" schließt nur den Dialog (Start wie bisher über die
|
||||
/// Übersicht möglich).
|
||||
Future<void> _showLoadingCompleteDialog(String carId) async {
|
||||
final start = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (ctx) => AlertDialog(
|
||||
icon: const Icon(Icons.check_circle, color: Colors.green, size: 40),
|
||||
title: const Text('Alles gescannt'),
|
||||
content: const Text(
|
||||
'Alle zu beladenden Artikel sind gescannt. '
|
||||
'Möchten Sie die Auslieferung starten?',
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(ctx).pop(false),
|
||||
child: const Text('Später'),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () => Navigator.of(ctx).pop(true),
|
||||
child: const Text('Auslieferung starten'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
if (start != true || !mounted) return;
|
||||
context
|
||||
.read<PhaseBloc>()
|
||||
.add(PhaseSet(carId: carId, phase: DeliveryPhase.ausliefern));
|
||||
// Scanner schließen → zurück zum Phasen-Router, der nun 'ausliefern' zeigt.
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<CarSelectBloc, CarSelectState>(
|
||||
builder: (context, carState) {
|
||||
final carId =
|
||||
carState is CarSelectComplete ? carState.selectedCar.id : '';
|
||||
return BlocBuilder<TourBloc, TourState>(
|
||||
return BlocConsumer<TourBloc, TourState>(
|
||||
listener: (context, tourState) =>
|
||||
_maybePromptLoadingComplete(context, tourState, carId),
|
||||
builder: (context, tourState) {
|
||||
if (tourState is! TourLoaded) {
|
||||
return const Scaffold(
|
||||
|
||||
Reference in New Issue
Block a user