Files
Holzleitner-Lieferservice-App/lib/feature/delivery/model/delivery_phase.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

95 lines
3.3 KiB
Dart

/// Die expliziten Phasen des Lieferprozesses nach der Fahrzeugauswahl.
///
/// Die Reihenfolge im Enum entspricht der logischen Tagesabfolge:
/// 1. [auswaehlen] (nur bei Teams mit mehreren Fahrzeugen)
/// 2. [sortieren]
/// 3. [beladen]
/// 4. [ausliefern]
///
/// Wichtig: Die Schrittnummer ist NICHT statisch (z. B. "Sortieren = 2"),
/// sondern hängt von der für den Fahrer sichtbaren Phasenmenge ab — bei
/// Ein-Auto-Teams entfällt [auswaehlen] und [sortieren] wird zu Schritt 1.
/// Die Berechnung erfolgt deshalb dynamisch im [PhaseStepper] bzw. in der
/// BLoC-Schicht und nicht auf dem Enum selbst.
///
/// Der Fahrer darf zwischen bereits erreichten Phasen frei zurückspringen
/// — die Phase ist daher kein Zwangs-Stepper, sondern markiert lediglich
/// die aktuelle Bühne des Tages.
enum DeliveryPhase {
/// Aus den Tour-Lieferungen die eigenen Aufträge auswählen / umladen
/// (nur bei ≥2 Fahrzeugen im Team relevant).
auswaehlen,
/// Reihenfolge der Lieferungen festlegen (Drag & Drop).
sortieren,
/// Beladung mit Scan, geführt nach der gewählten Reihenfolge.
beladen,
/// Beladung abgeschlossen, Auslieferung läuft.
ausliefern,
}
extension DeliveryPhaseExtension on DeliveryPhase {
/// Stabile Schlüssel für die Persistenz. Bewusst entkoppelt von der
/// enum-Reihenfolge, damit zukünftige Umbenennungen den Disk-State nicht
/// brechen.
String get persistenceKey => switch (this) {
DeliveryPhase.auswaehlen => "auswaehlen",
DeliveryPhase.sortieren => "sortieren",
DeliveryPhase.beladen => "beladen",
DeliveryPhase.ausliefern => "ausliefern",
};
/// Anzeigename für die UI (Banner, Stepper).
String get displayName => switch (this) {
DeliveryPhase.auswaehlen => "Auswählen",
DeliveryPhase.sortieren => "Sortieren",
DeliveryPhase.beladen => "Beladen",
DeliveryPhase.ausliefern => "Ausliefern",
};
/// Schrittnummer (1-basiert) in einer gegebenen Phasen-Sichtbarkeitsliste.
///
/// Dynamische Variante, die [stepNumber] (statisch) ersetzt — der Stepper
/// erhält je nach Team-Konfiguration eine andere [visiblePhases]-Liste und
/// bestimmt darüber, welche Nummer hier angezeigt wird.
///
/// Liefert `-1`, wenn die Phase nicht in [visiblePhases] enthalten ist.
int stepNumberIn(List<DeliveryPhase> visiblePhases) {
final idx = visiblePhases.indexOf(this);
return idx == -1 ? -1 : idx + 1;
}
static DeliveryPhase? fromPersistenceKey(String? key) {
if (key == null) return null;
for (final phase in DeliveryPhase.values) {
if (phase.persistenceKey == key) return phase;
}
return null;
}
/// Liefert die für den Fahrer sichtbaren Phasen abhängig von der Anzahl
/// der Team-Fahrzeuge:
///
/// * 0 oder 1 Auto → [sortieren, beladen, ausliefern]
/// * ≥2 Autos → [auswaehlen, sortieren, beladen, ausliefern]
///
/// Single source of truth für Stepper und Banner.
static List<DeliveryPhase> visiblePhasesForCarCount(int carCount) {
if (carCount >= 2) {
return const [
DeliveryPhase.auswaehlen,
DeliveryPhase.sortieren,
DeliveryPhase.beladen,
DeliveryPhase.ausliefern,
];
}
return const [
DeliveryPhase.sortieren,
DeliveryPhase.beladen,
DeliveryPhase.ausliefern,
];
}
}