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:
68
lib/feature/loading/util/loading_order.dart
Normal file
68
lib/feature/loading/util/loading_order.dart
Normal file
@ -0,0 +1,68 @@
|
||||
import 'package:hl_lieferservice/feature/delivery/bloc/tour_state.dart';
|
||||
import 'package:hl_lieferservice/model/delivery.dart';
|
||||
|
||||
/// Hilfen rund um die Belade-Reihenfolge.
|
||||
///
|
||||
/// Die Beladereihenfolge ist die *Umkehrung* der vom Fahrer bestätigten
|
||||
/// Auslieferungs-Reihenfolge (Sortier-Phase): wer zuletzt ausgeliefert wird,
|
||||
/// kommt zuerst auf den LKW und liegt hinten. Diese Klasse liefert die
|
||||
/// gefilterte und gespiegelte ID-Liste — Quelle ist immer
|
||||
/// `TourLoaded.sortingInformation[carId]`.
|
||||
///
|
||||
/// Filterung:
|
||||
/// * Bei ≥2 Fahrzeugen im Team: nur Lieferungen mit
|
||||
/// `delivery.carId == selectedCarId`.
|
||||
/// * Bei genau 1 Fahrzeug: alle Tour-Lieferungen.
|
||||
///
|
||||
/// Konsistent mit der bestehenden Logik in [DeliverySortPage] und der
|
||||
/// alten `scan_page.dart:792`.
|
||||
class LoadingOrder {
|
||||
const LoadingOrder._();
|
||||
|
||||
/// Berechnet die Belade-Reihenfolge an Delivery-IDs.
|
||||
///
|
||||
/// [carIdStr] ist das String-Pendant der gewählten Auto-ID, weil die
|
||||
/// `sortingInformation` mit String-Keys arbeitet.
|
||||
static List<String> computeForCar({
|
||||
required TourLoaded state,
|
||||
required String carIdStr,
|
||||
}) {
|
||||
final cars = state.tour.driver.cars;
|
||||
final allowedIds = cars.length >= 2
|
||||
? state.tour.deliveries
|
||||
.where((d) => d.carId?.toString() == carIdStr)
|
||||
.map((d) => d.id)
|
||||
.toSet()
|
||||
: state.tour.deliveries.map((d) => d.id).toSet();
|
||||
|
||||
final raw = state.sortingInformation[carIdStr] ?? const <String>[];
|
||||
|
||||
// Mit reversed nach hinten kommt die zuletzt ausgelieferte Lieferung
|
||||
// nach vorne (zuerst beladen).
|
||||
final reversed = raw.reversed.where(allowedIds.contains).toList();
|
||||
|
||||
// Falls die Sortierung leer ist (kann bei frisch geladener Tour
|
||||
// vorkommen, bevor `EnsureSortingForCarEvent` durchlief), fallen wir
|
||||
// auf die unsortierten Tour-IDs zurück — der Fahrer sieht so wenigstens
|
||||
// alle Kunden, ohne dass die Page hängt.
|
||||
if (reversed.isEmpty && allowedIds.isNotEmpty) {
|
||||
return allowedIds.toList(growable: false);
|
||||
}
|
||||
return reversed;
|
||||
}
|
||||
|
||||
/// Komfort-Variante, die zusätzlich abgeschlossene Lieferungen rausfiltert
|
||||
/// (für Anzeigen, die nur "noch zu beladen" bzw. aktive Einträge möchten).
|
||||
static List<String> computeActive({
|
||||
required TourLoaded state,
|
||||
required String carIdStr,
|
||||
}) {
|
||||
final order = computeForCar(state: state, carIdStr: carIdStr);
|
||||
final byId = {for (final d in state.tour.deliveries) d.id: d};
|
||||
return order.where((id) {
|
||||
final d = byId[id];
|
||||
if (d == null) return false;
|
||||
return d.state != DeliveryState.finished;
|
||||
}).toList(growable: false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user