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

277 lines
6.4 KiB
Dart

import 'dart:typed_data';
import 'package:hl_lieferservice/model/car.dart';
import 'package:hl_lieferservice/model/tour.dart';
import '../../../../model/delivery.dart';
abstract class TourEvent {}
class LoadTour extends TourEvent {
String teamId;
LoadTour({required this.teamId});
}
class RequestDeliveryDistanceEvent extends TourEvent {
Tour tour;
RequestDeliveryDistanceEvent({required this.tour});
}
class RequestSortingInformationEvent extends TourEvent {
Tour tour;
List<Payment> payments;
RequestSortingInformationEvent({
required this.tour,
required this.payments,
});
}
class ReorderDeliveryEvent extends TourEvent {
int newPosition;
int oldPosition;
String carId;
ReorderDeliveryEvent({required this.newPosition, required this.oldPosition, required this.carId});
}
/// Ersetzt die komplette Sortier-Information (z. B. beim Zurücksetzen auf
/// die Default-Reihenfolge in der Sortier-Page). Persistiert lokal über
/// den ReorderService, kein Backend-Call.
class ReplaceSortingEvent extends TourEvent {
final String carId;
final Map<String, List<String>> newSortingInformation;
ReplaceSortingEvent({
required this.carId,
required this.newSortingInformation,
});
}
/// Bestätigung der Sortierung durch den Fahrer. Löst den (aktuell ge-
/// stubbten) Backend-Call zur Persistierung der Reihenfolge aus und
/// schaltet bei Erfolg in Phase [DeliveryPhase.beladen].
class ConfirmSortingEvent extends TourEvent {
final String carId;
ConfirmSortingEvent({required this.carId});
}
/// Stellt sicher, dass der Sortier-Bucket für [carId] alle aktuell in der
/// Tour vorhandenen Lieferungen enthält — und zwar UNABHÄNGIG von
/// `delivery.carId`. Hintergrund: zum Sortier-Zeitpunkt sind die Lieferungen
/// dem Fahrzeug oft noch nicht zugeordnet (das passiert erst beim Scannen
/// während des Beladens). Der Fahrer hat aber bereits sein Tagesfahrzeug
/// gewählt, also gehören alle Tour-Lieferungen in diesen Bucket. Bestehende
/// Reihenfolge bleibt erhalten, fehlende IDs werden hinten angehängt.
class EnsureSortingForCarEvent extends TourEvent {
final String carId;
EnsureSortingForCarEvent({required this.carId});
}
class TourUpdated extends TourEvent {
Tour tour;
List<Payment> payments;
TourUpdated({required this.tour, required this.payments});
}
class PaymentOptionsUpdated extends TourEvent {
List<Payment> options;
PaymentOptionsUpdated({required this.options});
}
class UpdateTour extends TourEvent {
Tour tour;
UpdateTour({required this.tour});
}
class AssignCarEvent extends TourEvent {
String deliveryId;
String carId;
AssignCarEvent({required this.deliveryId, required this.carId});
}
/// Hebt die Fahrzeug-Zuordnung einer Lieferung wieder auf. Wird im
/// Auswahl-Schritt ausgelöst, wenn der Fahrer eine eigene Lieferung
/// "freigibt", damit ein Kollege sie übernehmen kann. Aktuell ruft der
/// Handler nur den ProcessRepository-Stub auf — ein echtes Update der
/// Tour erfolgt erst mit dem realen Backend-Endpoint (siehe Repository).
class UnassignDeliveryEvent extends TourEvent {
final String deliveryId;
UnassignDeliveryEvent({required this.deliveryId});
}
class IncrementArticleScanAmount extends TourEvent {
String internalArticleId;
String deliveryId;
String carId;
IncrementArticleScanAmount({
required this.internalArticleId,
required this.deliveryId,
required this.carId,
});
}
class ScanArticleEvent extends TourEvent {
ScanArticleEvent({
required this.articleNumber,
required this.carId,
required this.deliveryId,
});
String articleNumber;
String deliveryId;
String carId;
}
/// Scan a single BOM component. The server call for the parent article is
/// deferred until *all* components are fully scanned.
class ScanComponentEvent extends TourEvent {
ScanComponentEvent({
required this.componentArticleNumber,
required this.carId,
required this.deliveryId,
});
String componentArticleNumber;
String deliveryId;
String carId;
}
class CancelDeliveryEvent extends TourEvent {
String deliveryId;
CancelDeliveryEvent({required this.deliveryId});
}
class HoldDeliveryEvent extends TourEvent {
String deliveryId;
HoldDeliveryEvent({required this.deliveryId});
}
class ReactivateDeliveryEvent extends TourEvent {
String deliveryId;
ReactivateDeliveryEvent({required this.deliveryId});
}
class LoadDeliveryEvent extends TourEvent {
LoadDeliveryEvent({required this.delivery});
Delivery delivery;
}
class UnscanArticleEvent extends TourEvent {
UnscanArticleEvent({
required this.articleId,
required this.newAmount,
required this.reason,
required this.deliveryId,
});
String articleId;
String deliveryId;
String reason;
int newAmount;
}
class ResetScanAmountEvent extends TourEvent {
ResetScanAmountEvent({required this.articleId, required this.deliveryId});
String articleId;
String deliveryId;
}
class AddDiscountEvent extends TourEvent {
AddDiscountEvent({
required this.deliveryId,
required this.value,
required this.reason,
});
String deliveryId;
String reason;
int value;
}
class RemoveDiscountEvent extends TourEvent {
RemoveDiscountEvent({required this.deliveryId});
String deliveryId;
}
class UpdateDiscountEvent extends TourEvent {
UpdateDiscountEvent({
required this.deliveryId,
required this.value,
required this.reason,
});
String deliveryId;
String? reason;
int? value;
}
class CarsLoadedEvent extends TourEvent {
List<Car> cars;
CarsLoadedEvent({required this.cars});
}
class UpdateDeliveryOptionEvent extends TourEvent {
UpdateDeliveryOptionEvent({
required this.key,
required this.value,
required this.deliveryId,
});
String deliveryId;
String key;
dynamic value;
}
class UpdateSelectedPaymentMethodEvent extends TourEvent {
UpdateSelectedPaymentMethodEvent({
required this.payment,
required this.deliveryId,
});
Payment payment;
String deliveryId;
}
class FinishDeliveryEvent extends TourEvent {
FinishDeliveryEvent({
required this.deliveryId,
required this.driverSignature,
required this.customerSignature,
});
String deliveryId;
Uint8List customerSignature;
Uint8List driverSignature;
}
class SetArticleAmountEvent extends TourEvent {
final String deliveryId;
final String articleId;
final String? reason;
final int amount;
SetArticleAmountEvent({
required this.deliveryId,
required this.articleId,
required this.amount,
this.reason,
});
}