Final commit.

This commit is contained in:
Dennis Nemec
2026-06-01 17:12:28 +02:00
parent 3ecbc82885
commit a9bf8ecdd1
385 changed files with 29081 additions and 12089 deletions

View File

@ -1,57 +1,52 @@
import 'package:hl_lieferservice/feature/delivery/model/delivery_phase.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// Persistiert die aktuelle Phase pro Fahrzeug. Der Key ist datumsspezifisch,
/// damit ein App-Neustart am nächsten Tag automatisch wieder mit Phase 1
/// (Sortieren) startet — die Phase eines Vortags hat keine Bedeutung mehr.
/// Persistiert die aktuelle Phase pro Fahrzeug.
///
/// Zusätzlich wird die **höchste am Tag erreichte Phase** pro Fahrzeug
/// persistiert (eigener Key-Suffix `_max`). Der Stepper nutzt diesen Wert,
/// um Vorwärts-Sprünge auf bereits besuchte Phasen zu erlauben — auch wenn
/// der Fahrer zwischenzeitlich zurückgesprungen ist.
/// Der Key ist an einen **Tour-Token** gebunden (abgeleitet aus
/// `Tour.syncedAt`) statt nur an das Datum. Vorteile:
///
/// * Ein erneuter ERP-Sync / Demo-Seed schreibt eine neue `syncedAt` → neuer
/// Token → die Phasen (inkl. der „erledigt"-Häkchen im Stepper) starten
/// frisch. So bleibt ein „Daten-Reset" im Backend nicht an alten lokalen
/// Häkchen hängen.
/// * Eine Tour von heute hat heutiges `syncedAt` — die Tagesbindung ist
/// damit implizit (am nächsten Tag gibt es ohnehin eine neue Tour).
/// * Bloßes Weiterscannen (Item-Status) ändert `syncedAt` nicht → der
/// Fahrer-Fortschritt bleibt über App-Neustarts derselben Tour erhalten.
///
/// Zusätzlich wird die **höchste erreichte Phase** pro Fahrzeug persistiert
/// (Key-Suffix `_max`). Der Stepper nutzt das, um Vorwärts-Sprünge auf
/// bereits besuchte Phasen zu erlauben — auch nach einem Rücksprung.
class PhaseService {
static const _prefix = "delivery_phase";
String _key(String carId) {
final now = DateTime.now();
final date = "${now.year}_${now.month}_${now.day}";
return "${_prefix}_${date}_$carId";
}
String _key(String carId, String token) => "${_prefix}_${token}_$carId";
String _maxKey(String carId) {
final now = DateTime.now();
final date = "${now.year}_${now.month}_${now.day}";
return "${_prefix}_max_${date}_$carId";
}
String _maxKey(String carId, String token) =>
"${_prefix}_max_${token}_$carId";
Future<void> save(String carId, DeliveryPhase phase) async {
Future<void> save(String carId, String token, DeliveryPhase phase) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_key(carId), phase.persistenceKey);
await prefs.setString(_key(carId, token), phase.persistenceKey);
}
Future<DeliveryPhase?> load(String carId) async {
final prefs = await SharedPreferences.getInstance();
return DeliveryPhaseExtension.fromPersistenceKey(prefs.getString(_key(carId)));
}
Future<void> saveMax(String carId, DeliveryPhase phase) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_maxKey(carId), phase.persistenceKey);
}
Future<DeliveryPhase?> loadMax(String carId) async {
Future<DeliveryPhase?> load(String carId, String token) async {
final prefs = await SharedPreferences.getInstance();
return DeliveryPhaseExtension.fromPersistenceKey(
prefs.getString(_maxKey(carId)),
prefs.getString(_key(carId, token)),
);
}
Future<Map<String, DeliveryPhase>> loadAll(Iterable<String> carIds) async {
final result = <String, DeliveryPhase>{};
for (final carId in carIds) {
final phase = await load(carId);
if (phase != null) result[carId] = phase;
}
return result;
Future<void> saveMax(String carId, String token, DeliveryPhase phase) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_maxKey(carId, token), phase.persistenceKey);
}
Future<DeliveryPhase?> loadMax(String carId, String token) async {
final prefs = await SharedPreferences.getInstance();
return DeliveryPhaseExtension.fromPersistenceKey(
prefs.getString(_maxKey(carId, token)),
);
}
}