feat(zahlung): Zahlungsabwicklung als eigenes Protokoll (POST /deliveries/{id}/payment)
- Neue Tabelle delivery_payments (append-only, idempotent ueber client_event_id): Methode + Code-Snapshot, server-seitig berechneter offener Betrag, Fahrer, Fahrzeug, Zeitpunkt - Endpoint prueft unter Zeilen-Lock: Lieferung aktiv, Methode aktiv, offener Betrag > 0 und identisch mit dem vom Fahrer bestaetigten Betrag - Offener Betrag als gemeinsamer Helper (open_amount_cents) fuer Zahlungsprotokoll und Abschluss - Abschluss-Gate: gueltige protokollierte Zahlung erfuellt die Inkasso-Pflicht und liefert die Methode; delivery_completions.payment_id verknuepft den Abschluss mit der Zahlung. Altes payment_collected-Flag bleibt fuer aeltere App-Versionen gueltig - Tour-Aggregat und Admin-Belegdetails liefern die juengste Zahlung - Einzel-Reset loescht auch das Zahlungsprotokoll - Integrationstest (ignored, braucht Wegwerf-DB) fuer Protokoll + Gate Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@ -204,3 +204,26 @@ pub struct DeliveryCredit {
|
||||
pub amount_cents: i64,
|
||||
pub reason: String,
|
||||
}
|
||||
|
||||
/// Protokollierte Zahlungsabwicklung („Abkassieren") einer Lieferung.
|
||||
///
|
||||
/// Append-only: jede Bestätigung des Fahrers ist ein eigener Eintrag; im
|
||||
/// Tour-Aggregat wird pro Lieferung nur der jüngste mitgeliefert. Der Betrag
|
||||
/// ist der server-seitig berechnete offene Betrag zum Zeitpunkt der
|
||||
/// Bestätigung. Weicht der aktuelle offene Betrag davon ab (z. B. nach einer
|
||||
/// neuen Gutschrift), ist der Eintrag veraltet und muss erneuert werden.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DeliveryPayment {
|
||||
pub id: Uuid,
|
||||
pub delivery_id: Uuid,
|
||||
pub payment_method_id: Uuid,
|
||||
/// Snapshot des Methoden-Codes (`cash`, `ec_card`, `invoice`, …).
|
||||
pub payment_method_code: String,
|
||||
/// Abgewickelter Betrag in Cent (offener Betrag bei Bestätigung).
|
||||
pub amount_cents: i64,
|
||||
pub recorded_by_personalnummer: i64,
|
||||
pub recorded_by_car_id: Option<Uuid>,
|
||||
pub recorded_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
@ -37,7 +37,8 @@ pub use common::Address;
|
||||
pub use contact::{ContactChannel, ContactKind, ContactRole, ContactSource};
|
||||
pub use customer::{Customer, CustomerContact};
|
||||
pub use delivery::{
|
||||
Delivery, DeliveryCredit, DeliveryItem, DeliveryNote, DeliveryState, ScanState, ScanStatus,
|
||||
Delivery, DeliveryCredit, DeliveryItem, DeliveryNote, DeliveryPayment, DeliveryState, ScanState,
|
||||
ScanStatus,
|
||||
};
|
||||
pub use payment::PaymentMethod;
|
||||
pub use process_state::{DeliveryPhase, DeliveryProcessState};
|
||||
|
||||
Reference in New Issue
Block a user