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)
277 lines
6.4 KiB
Dart
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,
|
|
});
|
|
} |