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)
This commit is contained in:
58
lib/feature/delivery/bloc/phase_state.dart
Normal file
58
lib/feature/delivery/bloc/phase_state.dart
Normal file
@ -0,0 +1,58 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user