Files
Holzleitner-Lieferservice-App/lib/feature/delivery/bloc/phase_state.dart
Dennis Nemec 456fb59668 Phasenbasierte Lieferübersicht + Beladen-Flow, plus Migrationsplan für Rust-Backend
UI-Restructuring:
- TabBar in scan_page durch dedizierte Phasen ersetzt: Sortieren / Beladen / Ausliefern
- PhaseBloc + PhaseService leiten Phase aus Tour-/Item-States ab
- DeliverySelectionPage (ab 2 Autos) und DeliverySortPage als eigene Flows
- LoadingOverviewPage / LoadingCustomerPage für die Beladephase
- PhaseStepper-Widget im Home für Phasen-Anzeige
- Lager-Differenzierung (Standardlager 0 vs. Außenlager) via WarehouseBadge

Process-Stubs:
- ProcessRepository für Hold/Cancel/Sort/Assign-Flows (stub, bereit für Backend-Anbindung)

Doku:
- docs/BACKEND_MIGRATION.md: Phasenplan für Umstellung auf das neue
  Rust-Backend (OpenAPI-Generator, Keycloak OIDC, Clean-Arch-Layering)
2026-05-14 22:27:56 +02:00

59 lines
2.2 KiB
Dart

import 'package:hl_lieferservice/feature/delivery/model/delivery_phase.dart';
abstract class PhaseState {}
class PhaseInitial extends PhaseState {}
/// Die aktive Phase pro Fahrzeug. Die Map ist pro Auto-ID separiert,
/// weil zwei Lieferketten am selben Tag (selten, aber möglich) parallel
/// laufen könnten und sich gegenseitig nicht überschreiben dürfen.
///
/// Zusätzlich wird die **höchste je heute erreichte Phase** pro Fahrzeug
/// gehalten ([maxPhaseByCar]). Damit kann der Stepper Vorwärts-Sprünge
/// auf bereits besuchte Phasen erlauben, auch wenn der Fahrer vorher
/// zurückgesprungen ist.
class PhaseReady extends PhaseState {
final Map<String, DeliveryPhase> phaseByCar;
final Map<String, DeliveryPhase> maxPhaseByCar;
PhaseReady({
required this.phaseByCar,
this.maxPhaseByCar = const {},
});
DeliveryPhase? phaseFor(String carId) => phaseByCar[carId];
/// Höchste am Tag erreichte Phase für [carId]. Fallback: aktuelle Phase
/// — wenn nichts gemerkt ist, gilt die aktuelle Phase als "höchste".
DeliveryPhase? maxPhaseFor(String carId) =>
maxPhaseByCar[carId] ?? phaseByCar[carId];
/// Setzt eine neue Phase und bumpt das Max-Tracking, falls die neue Phase
/// in der Enum-Reihenfolge höher ist als das bisherige Max.
PhaseReady withPhase(String carId, DeliveryPhase phase) {
final next = Map<String, DeliveryPhase>.from(phaseByCar);
next[carId] = phase;
final nextMax = Map<String, DeliveryPhase>.from(maxPhaseByCar);
final currentMax = nextMax[carId];
if (currentMax == null || phase.index > currentMax.index) {
nextMax[carId] = phase;
}
return PhaseReady(phaseByCar: next, maxPhaseByCar: nextMax);
}
/// Wird nach dem Laden aus dem [PhaseService] verwendet, damit die echte
/// historische Max-Phase übernommen wird (nicht automatisch geboostet).
PhaseReady withLoaded(
String carId,
DeliveryPhase phase,
DeliveryPhase maxPhase,
) {
final next = Map<String, DeliveryPhase>.from(phaseByCar);
next[carId] = phase;
final nextMax = Map<String, DeliveryPhase>.from(maxPhaseByCar);
nextMax[carId] = maxPhase;
return PhaseReady(phaseByCar: next, maxPhaseByCar: nextMax);
}
}