13 Commits

Author SHA1 Message Date
2ff331294e fix: Tour-Datum — Leer-Texte, veraltete Antworten, Kalenderfenster
- Leer-Ansichten (Auswählen, Sortieren, Beladen, Ausliefern) nennen den
  gewählten Tag statt immer „heute": „Für den 02.09.2026 ist keine Tour
  zugewiesen." (TourDayText).
- TourBloc: Loads/Refreshes laufen nebenläufig; bei schnellem
  Datumswechsel konnte die langsamere Antwort des vorigen Tages die Tour
  des gewählten Tages überschreiben. Jetzt schreibt nur die jüngste
  Anfrage ihr Ergebnis.
- Kalender reicht 90 statt 14 Tage zurück (z. B. nachimportierte Touren
  vom Monatsanfang).
- Test: neuer Fahrer startet auf „heute", auch wenn der vorige einen
  anderen Tag gewählt hatte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 17:04:56 +02:00
335cf02a9f feat: Adresszusatz (Ortsteil/Etage/Hinweis) anzeigen, Land nur im Ausland
- Address.addition aus dem Backend (ERP-Freitext, praktisch Ortsteil,
  Etage oder Hinweis); API-Client neu generiert.
- Listen (Sortieren, Beladen, Liefer-Übersicht): Adresse mit Zusatz in
  Klammern, z. B. „… 41472 Neuss (Holzheim)".
- Lieferdetails: „Zusatz: …" unter der Anschrift von Empfänger und
  Besteller; Land nur außerhalb Deutschlands.
- Maps-Suche weiter ohne Zusatz (sonst stört „3 Etage" die Suche).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 16:13:28 +02:00
857c92031a feat: abweichende Lieferadresse und Empfänger vor Ort anzeigen
Belege können im ERP eine eigene Lieferadresse (LieferAdressId) mit
anderer Person tragen als der Besteller. Die App zeigt jetzt überall den
Empfänger vor Ort:

- TourDetails.recipientOf liefert Empfänger (Name aus der Lieferadresse,
  sonst Besteller), Lieferanschrift und differsFromOrderer.
- Sortieren, Auswählen, Beladen und Liefer-Übersicht: Empfängername +
  Lieferadresse, bei Abweichung „Bestellt von: <Kunde>".
- Lieferdetails: hervorgehobene Karte „Abweichende Lieferadresse" mit
  Empfänger, Anschrift und Kontakt; Kunden-Block als „Besteller (Kunde)"
  mit Adresse, Kundennummer und Kontaktdaten.
- Maps navigiert zur Lieferadresse statt zur Kundenadresse; AppBar,
  Unterschrift und Beladen-Avatar nutzen den Empfänger.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:51:31 +02:00
c239cdfd3e feat(retry): jeder dynamisch geladene Request hat im Fehlerfall einen Retry
Inventur aller Lese-Requests (Tour, Fahrzeuge, Zahlungsmethoden,
Foto-Vorschauen) und aller Stellen, an denen ihr Fehlerzustand gerendert wird.
Geschlossene Luecken:

- Sortieren-Seite: TourLoadFailed fiel in den Lade-Zweig -> Endlos-Spinner
  ohne Ausweg. Jetzt Fehlerseite mit 'Erneut versuchen' im Header-Rahmen
- Home: scheiterte beim Start CarLoad oder LoadTour, wurde die Phase nie
  geladen -> Endlos-Spinner. Jetzt Fehlerseite mit Retry (+ Drawer)
- Beladen-/Auswaehlen-Seite: Fehlerseite stand ohne Scaffold/Header/Drawer
  da; jetzt im selben Rahmen wie die uebrigen Zustaende
- Hintergrund-Reload (refreshError): Snackbar jetzt MIT Retry-Aktion und
  zentral im PhaseStepper-Header -> gilt in allen Phasen (vorher nur
  Ausliefern, ohne Retry; auf Sortieren/Beladen blieb der Fehler stumm)
- AttachmentImage: Fehleranzeige ist antippbar ('Erneut laden')

Zahlungsmethoden haben den Retry bereits aus dem vorigen Commit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 12:15:19 +03:00
c5219343a0 fix(beladen): Phasen-Header auch ohne/vor geladener Tour anzeigen
Bei TourEmpty/TourLoading rendert die Beladen-Seite jetzt denselben
PhaseStepper-Header wie im geladenen Zustand statt einer nackten
'Beladung'-AppBar. Damit bleiben Kopf-Kalender (Datumswechsel), Menue und
Reload an einem Tag ohne Tour erreichbar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-09-09 01:14:56 +02:00
f12ad5d3c0 feat(loading): Set-Kopf wird grün, wenn alle Komponenten geladen sind
Ein nicht-scanbarer Set-Kopf (Parent-Artikel) hat keinen eigenen
Scan-Status. Sobald alle scanbaren, nicht entfernten Komponenten fertig
(isDone) sind, wird der Kopf jetzt ebenfalls grün dargestellt
(effectiveDone = isDone || setParentComplete) und zeigt statt des
unterdrückten Hinweises ein grünes „Komplett geladen".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 11:11:21 +02:00
8b1b35b374 fix(loading): "Kein Scanvorgang notwendig"-Hinweis bei Set-Köpfen entfernen
Ein nicht-scanbarer Set-Kopf (Parent-Artikel) wird im Beladen-Screen über
seinen Komponenten gezeigt. Der Hinweis „Kein Scanvorgang notwendig" ist
dort irreführend, weil die (scanbaren) Komponenten darunter sehr wohl
gescannt werden. _ItemRow bekommt suppressScanHint; gesetzt nur für
Set-Köpfe (Artikelnummer wird von einer Komponente als parentArtikelNr
referenziert). Komponenten/echte Dienstleistungen behalten den Hinweis.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 11:05:35 +02:00
4c6bef6897 feat(delivery): Abschluss-Navigation, Mengen-Hinweis, Set-Handling
A) Nach erfolgreichem Abschluss (aktiv→completed) poppt die Detail-Page
   automatisch zurück zur Übersicht. Scaffold ist jetzt StatefulWidget
   mit BlocListener<TourBloc>; nur „gearmt", wenn die Lieferung beim
   Öffnen aktiv war → erneutes Öffnen einer fertigen Lieferung poppt nicht.

B) Step „Info": Artikelliste zeigt weiter die Ursprungsmenge
   (requiredQuantity). Bei entfernten/teilweise gutgeschriebenen Positionen
   erscheint pro Zeile ein „Menge geändert"-Hinweis + ein tappbares Banner,
   das zu Step 3 „Artikel" springt.

C) Beladen: nicht-scanbare Set-Köpfe (Parent-Komponenten) werden jetzt
   IMMER mit ihrem Set gezeigt — als Kopf in der Lagergruppe ihrer
   Komponenten statt isoliert unter „Dienstleistungen". _ItemRow leitet
   scanNotRequired aus der Artikel-Scanbarkeit ab.

D) Step „Übersicht": Wording der Zahlungsweise-Sperre bei offen==0
   präzisiert („Keine Zahlung mehr offen (bereits bezahlt)").

E) Step „Artikel": Komponenten eines Sets sind einzeln nicht mehr
   entfernbar (kein Button + Hinweis). Das Entfernen/Wiederherstellen läuft
   nur über den Oberartikel und kaskadiert auf das ganze Set (ganz oder
   gar nix). Set-Entfernen ist blockiert, solange eine Komponente noch
   nicht verladen ist.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 15:57:52 +02:00
446cf73347 feat(loading): Abschluss-Dialog 'Alles gescannt - Auslieferung starten?' im Scanner
Sobald im Beladen-Scanner der letzte Pflicht-Scan erledigt ist (alle eigenen,
aktiven Lieferungen im Standardlager fertig - gleiche Bedingung wie der
'Auslieferungs-Phase starten'-Gate der Uebersicht), erscheint einmalig ein
Dialog: bestaetigt 'alles gescannt' und fragt, ob die Auslieferung starten soll.
'Auslieferung starten' -> PhaseSet(ausliefern) + Scanner schliessen; 'Spaeter'
-> nur schliessen. BlocConsumer<TourBloc>-Listener + Einmal-Flag (Reset wenn
wieder etwas offen).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 16:07:22 +02:00
a206636ed0 feat(tour): Tour-Neuladen ueberall + Drawer in Leer-/Ladezustaenden
- PhaseStepper: Reload-Button (RefreshTour, Spinner waehrend Refresh)
- Beladen-Empty-State: 'Neu laden'-Button (LoadTour) + Hinweis 'keine Tour verfuegbar'
- Drawer + AppBar in TourEmpty/Lade-Branches (Beladen-Uebersicht, Lieferungen auswaehlen, Sortieren) -> kein Festsitzen ohne Logout

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:08:18 +02:00
a9bf8ecdd1 Final commit. 2026-06-01 17:12:28 +02:00
3ecbc82885 Phase C+D-1: Cars-Domain auf Rust-Backend umgestellt
Clean-Arch-Schichten für Cars:
- lib/domain/entity/car.dart: UUID-id, accountId (Personalnummer),
  plate, active. Pendant zum Backend-Schema.
- lib/domain/repository/cars_repository.dart: Port — listMine,
  create, update. Keine teamId/personalnummer-Parameter, der
  Account fließt serverseitig aus dem JWT.
- lib/data/mapper/car_mapper.dart: API-DTO (built_value) → Domain.
- lib/data/repository/cars_repository_impl.dart: konkrete Impl via
  generierter CarsApi (dio), mit DioException → CarsRepositoryException-
  Übersetzung.

Feature-Cars-Refactoring:
- CarsBloc nimmt jetzt die Domain-Repository-Schnittstelle. Events:
  CarLoad/CarAdd/CarEdit/CarDeactivate (statt CarDelete). Keine
  teamId-Parameter mehr. Kein authBloc-Bezug, Session-Expiry läuft
  über den globalen Provider-Stream.
- CarsState sealed mit CarsInitial/Loading/LoadingFailed/Loaded.
- Pages: car_management_page, car_management, car_card, car_fail_page,
  car_selection_page komplett auf die neue Entity und Event-Signaturen.
- Alte lib/feature/cars/service/cars_service.dart und
  lib/feature/cars/repository/cars_repository.dart gelöscht.

CarSelectBloc + Storage:
- CarSelection.selectedCarId von int? auf String? umgestellt.
- CarSelectionRepository persistiert die UUID jetzt als String;
  defensive Migration für noch vorhandene int-Werte (alte
  Pre-Migration-Installations) verwirft den Wert leise und
  erzwingt Neuauswahl.

Konsequenz-Cleanup im Tour-Code (Phase-D-Vorbereitung):
- Delivery.carId String? statt int?.
- Tour.hasUndeliveredLoadedArticles / getFinishedDeliveries auf
  String carId.
- _selectedCarId / int? carId / int selectedCarId in DeliveryOverview,
  LoadingCustomerPage/OverviewPage, Home, DeliverySelection/SortPage,
  DeliveryInfo/List, CustomSortDialog, SortableDeliveryList auf
  String umgestellt.
- TourRepository ersetzt int.parse(carId)/int.tryParse-Zuweisungen
  direkt durch String.
- lib/model/car.dart wird zum Re-Export der neuen Domain-Entity,
  damit Legacy-Imports während Phase-D-Übergang weiter compilieren.

DI:
- app.dart: CarsBloc bekommt CarsRepositoryImpl(locator<HolzleitnerApi>())
  statt der alten CarsRepository(service: CarService()).

Build (flutter build apk --debug) durch, flutter analyze ohne
errors.
2026-05-15 11:55:24 +02:00
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