Files
Holzleitner-Lieferservice-App/lib/feature/delivery/detail/bloc/workflow_state.dart
Dennis Nemec dd7fe9a8eb feat(zahlung): eigener Step "Zahlung" vor der Uebersicht
- Neuer Workflow-Step "Zahlung" zeigt ausgelieferte Artikel mit Menge und
  Preis, Betragsaufstellung, Zahlungsstatus und einen grossen Button
  "Zahlung abwickeln" (fest unten)
- Zahlungs-Modal: grosser offener Betrag, Methoden als Cards aus den
  Backend-Stammdaten, bei EC-Karte gross die Kundennummer; schliesst nur
  ueber Abbrechen, "Zahlung erhalten" oder "Lieferung abbrechen" (mit Grund)
- Bestaetigung wird am Server protokolliert (RecordDeliveryPayment); bis
  dahin sind "Weiter" und die Uebersicht gesperrt, ausser es ist nichts
  offen (bereits bezahlt). Aendert sich der Betrag danach, wird die Zahlung
  als veraltet markiert und muss erneut abgewickelt werden
- Uebersicht zeigt die abgewickelte Zahlung statt eigener Methodenauswahl;
  Unterschrift-Flow ohne doppelte Inkasso-Stufe; Abschluss sendet Methode
  und Inkasso-Flag der gueltigen Zahlung
- DeliveryPaymentStatus als einzige Quelle fuer offenen Betrag
  (gleiche Formel wie Backend); Artikelliste/Betragskarte als geteilte
  Widgets; Begruendungs-Dialog geteilt mit Info-Step
- API-Client aus aktueller Backend-Spec neu generiert
- Tests fuer Zahlungsstatus und Modal

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 14:04:36 +02:00

80 lines
2.5 KiB
Dart

import 'package:image_picker/image_picker.dart';
/// Die 6 Steps der Auslieferungs-Detail-Page. Reihenfolge ≙ Index.
enum WorkflowStep {
info,
notes,
articles,
services,
payment,
summary,
}
extension WorkflowStepX on WorkflowStep {
String get displayName => switch (this) {
WorkflowStep.info => 'Info',
WorkflowStep.notes => 'Notizen',
WorkflowStep.articles => 'Artikel & Gutschriften',
WorkflowStep.services => 'Checkliste',
WorkflowStep.payment => 'Zahlung',
WorkflowStep.summary => 'Übersicht',
};
/// Kurze Bezeichnung für den Header-Step (Platz ist eng auf Mobilgeräten).
String get shortName => switch (this) {
WorkflowStep.info => 'Info',
WorkflowStep.notes => 'Notizen',
WorkflowStep.articles => 'Artikel',
WorkflowStep.services => 'Checkliste',
WorkflowStep.payment => 'Zahlung',
WorkflowStep.summary => 'Übersicht',
};
}
/// Eine im Workflow geparkte Bild-Notiz, die noch nicht hochgeladen werden
/// kann — wartet auf den Foto-Upload-Endpoint.
class PendingImageNote {
const PendingImageNote({required this.file, required this.pickedAt});
/// Das vom `image_picker` zurückgegebene File-Handle.
final XFile file;
final DateTime pickedAt;
}
/// State des Detail-Workflows. Ein State, ein Bloc — der Step-Wechsel und
/// die Drafts liegen hier. Die Zahlung ist KEIN lokaler Draft mehr: Sie wird
/// im Step „Zahlung" am Server protokolliert und kommt über die Tour zurück. So sieht jede
/// Step-Page denselben kohärenten Zustand und ein Step kann Daten aus
/// einem anderen lesen (z. B. Summary liest Article-Drafts).
class DeliveryWorkflowState {
const DeliveryWorkflowState({
required this.deliveryId,
required this.step,
required this.pendingImageNotes,
});
factory DeliveryWorkflowState.initial(String deliveryId) =>
DeliveryWorkflowState(
deliveryId: deliveryId,
step: WorkflowStep.info,
pendingImageNotes: const [],
);
final String deliveryId;
final WorkflowStep step;
/// Lokal gehaltene Bild-Notizen — solange kein Upload-Endpoint da ist.
final List<PendingImageNote> pendingImageNotes;
DeliveryWorkflowState copyWith({
WorkflowStep? step,
List<PendingImageNote>? pendingImageNotes,
}) {
return DeliveryWorkflowState(
deliveryId: deliveryId,
step: step ?? this.step,
pendingImageNotes: pendingImageNotes ?? this.pendingImageNotes,
);
}
}