diff --git a/config.example.toml b/config.example.toml index bd8bd5e..291f72d 100644 --- a/config.example.toml +++ b/config.example.toml @@ -53,9 +53,9 @@ user = "sa" password = "" trust_cert = true writeback_enabled = false -# Gutschrift-Rückschreibung (GUTSCHRIFT10-Belegzeile) — bestandsneutral, -# daher unkritisch. true = Gutschriften werden ins ERP geschrieben. -# (Mengen-Reduktion wird generell NICHT mehr zurückgeschrieben.) +# Gutschrift-Rückschreibung (GUTSCHRIFT10-Belegzeile) separat togglebar. +# true = Gutschriften werden ins ERP geschrieben. Die Belegzeilen-Mengen +# werden ohnehin zurückgeschrieben (Lager verbucht den Bestand manuell). gutschrift_writeback_enabled = true # --- ERP-Import-Scheduler ------------------------------------------------- diff --git a/crates/infrastructure/src/erp/mssql_delivery_writeback.rs b/crates/infrastructure/src/erp/mssql_delivery_writeback.rs index 5408081..d326584 100644 --- a/crates/infrastructure/src/erp/mssql_delivery_writeback.rs +++ b/crates/infrastructure/src/erp/mssql_delivery_writeback.rs @@ -8,15 +8,15 @@ //! //! Reihenfolge: //! 1. `Belegkopf.row_id` aus (BelegartId, Belegnummer) auflösen. -//! 2. Gutschrift-Zeile (`GUTSCHRIFT10`) anlegen/aktualisieren. -//! 3. Belegsummen neu berechnen (`Σ Einzelpreis × Menge`, `Σ Brutto × Menge`). -//! 4. `_SV_DELIVERY_DELIVERED_AT` + `_SV_DELIVERY_STATE='geliefert'`. +//! 2. Je Belegzeile die `Menge` auf die ausgelieferte Menge setzen. +//! 3. Gutschrift-Zeile (`GUTSCHRIFT10`) anlegen/aktualisieren. +//! 4. Belegsummen neu berechnen (`Σ Einzelpreis × Menge`, `Σ Brutto × Menge`). +//! 5. `_SV_DELIVERY_DELIVERED_AT` + `_SV_DELIVERY_STATE='geliefert'`. //! -//! **Bewusst NICHT mehr:** das Setzen der Belegzeilen-`Menge`. Eine reduzierte -//! Liefermenge (entfernter Artikel) per Raw-`UPDATE` würde die ERPframe-Engine -//! umgehen und den Lagerbestand inkonsistent machen (keine Gegenbuchung). Der -//! ERP-Beleg bleibt daher im Original; geänderte Lieferungen werden im Backend -//! zur Vier-Augen-Prüfung markiert, die Fakturierung entscheidet manuell. +//! Hinweis: Das Setzen der Menge per Raw-`UPDATE` umgeht die ERPframe-Engine, +//! erzeugt also KEINE Lagerbuchung. Das ist gewollt — das Lager verbucht den +//! Bestand **manuell** nach Rückgabe des Geräts. Geänderte Lieferungen werden +//! zusätzlich zur Vier-Augen-Prüfung markiert. //! //! TODO (bewusst hardcoded, später konfigurierbar/aus Stammdaten): //! Gutschrift-Artikel `GUTSCHRIFT10`, Konto `8726`, Steuerschlüssel `M19`, @@ -125,6 +125,25 @@ impl MssqlErpDeliveryWriteback { }) } + /// Setzt die Menge einer Belegzeile (absolut, idempotent) auf die + /// tatsächlich ausgelieferte Menge. + async fn set_line_menge( + client: &mut TiberiusClient, + bk_row_id: i64, + belegzeilen_nr: i32, + menge: i32, + ) -> Result<(), ApplicationError> { + client + .execute( + r#"UPDATE Belegzeilen SET Menge = @P1 + WHERE ParentID = @P2 AND BelegzeilenNr = @P3"#, + &[&menge, &bk_row_id, &belegzeilen_nr], + ) + .await + .map_err(repo)?; + Ok(()) + } + /// Gutschrift-Upsert als EINE Belegzeile mit dem **tatsächlichen Betrag** /// (keine 10-€-Einheiten mehr → beliebige Beträge ≤ 150 € exakt abbildbar). /// `amount_cents` = Geld-Gutschrift in Cent (Brutto; 0 = keine). @@ -347,14 +366,15 @@ impl MssqlErpDeliveryWriteback { ) -> Result<(), ApplicationError> { let bk = Self::resolve_belegkopf(client, cmd.belegart_id, &cmd.belegnummer).await?; - // BEWUSST KEIN Setzen der Belegzeilen-Mengen mehr: eine reduzierte - // Liefermenge (entfernter Artikel) würde im ERP eine Bestands- - // Inkonsistenz erzeugen (die Engine bucht beim Raw-UPDATE nicht mit). - // Stattdessen bleibt der ERP-Beleg im Original; die Lieferung wird im - // Backend zur Vier-Augen-Prüfung markiert (siehe ReviewRepository) und - // die Fakturierung entscheidet manuell. Die Geld-Gutschrift wird - // (sofern per Config aktiviert) weiterhin geschrieben — bestandsneutral, - // daher unkritisch, nur Vier-Augen-Bestätigung. + // Je Belegzeile die Menge auf die ausgelieferte Menge setzen. Umgeht + // die ERPframe-Engine (keine Lagerbuchung) — das Lager verbucht den + // Bestand manuell nach Rückgabe des Geräts. Geänderte Lieferungen sind + // zusätzlich per Vier-Augen-Prüfung markiert. + for line in &cmd.lines { + Self::set_line_menge(client, bk, line.belegzeilen_nr, line.delivered_quantity).await?; + } + + // Geld-Gutschrift (sofern per Config aktiviert). if gutschrift_enabled { Self::upsert_gutschrift(client, bk, cmd.credit_amount_cents).await?; }