feat(abschluss): interne Notiz des Fahrers beim Abschluss

- CompleteDeliveryAcknowledgements.internalNote (optional, getrimmt,
  max. 2000 Zeichen) wird atomar mit dem Abschluss gespeichert
  (delivery_completions.internal_note)
- Bewusst keine delivery_notes-Zeile: loest weder die Kunden-Bestaetigung
  der Notizen aus noch erscheint sie im Notizen-Step der App
- Lieferbericht: eigener Abschnitt "Interne Notiz" mit Zeitpunkt und Fahrer
- Bericht: Betrag in "Betrag erhalten" ans Zeilenende (Helvetica setzt nach
  dem Euro-Zeichen zu eng)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dennis Nemec
2026-09-25 14:41:05 +02:00
parent caaf88ac3d
commit 695ac39c19
9 changed files with 81 additions and 5 deletions

View File

@ -81,6 +81,7 @@ fn input(delivery_id: Uuid, payment_collected: bool) -> CompleteDeliveryInput {
payment_method_id: None,
completed_by_personalnummer: 1,
completed_by_car_id: None,
internal_note: None,
}
}
@ -156,8 +157,15 @@ async fn payment_protocol_and_completion_gate() {
assert_eq!(payment_id, Some(inv.id));
// 8) Alte App: Flag ohne Protokoll funktioniert weiterhin.
// Dazu interne Notiz: wird am Abschluss gespeichert.
let d4 = seed(&pool, CASH).await;
completions.complete(input(d4, true)).await.unwrap();
let mut with_note = input(d4, true);
with_note.internal_note = Some("Kunde wünscht Rückruf wegen Montage".into());
completions.complete(with_note).await.unwrap();
let note: Option<String> =
sqlx::query_scalar("SELECT internal_note FROM delivery_completions WHERE delivery_id = $1")
.bind(d4).fetch_one(&pool).await.unwrap();
assert_eq!(note.as_deref(), Some("Kunde wünscht Rückruf wegen Montage"));
// 9) Tour-Aggregat liefert die jüngste Zahlung; Einzel-Reset löscht sie.
let tours = PgTourRepository::new(pool.clone());