From 671cd2de67081f18b82b60eaf4bde7f514c7db87 Mon Sep 17 00:00:00 2001 From: HirschleM Date: Wed, 27 May 2026 16:09:26 +0200 Subject: [PATCH] MH: EndartFabrik Kappung von InvoiceItems Faktor Fix --- .../Invoicing/CustomInvoiceCreation.cs | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/ReportImp/EndartFabrik/Invoicing/CustomInvoiceCreation.cs b/ReportImp/EndartFabrik/Invoicing/CustomInvoiceCreation.cs index 73bea137e..2a0727f9e 100644 --- a/ReportImp/EndartFabrik/Invoicing/CustomInvoiceCreation.cs +++ b/ReportImp/EndartFabrik/Invoicing/CustomInvoiceCreation.cs @@ -74,26 +74,24 @@ namespace EndartFabrik.Invoicing if (!ii.UnitCount.HasValue) continue; - // Claude: Multiplikator aus dem RateFactor berechnen (z.B. 20% → rf = 1,2) + // Claude: RateFactor-Multiplikator nur für die Betragsberechnung vormerken, NICHT für den Budgetvergleich decimal rf = 1; if (ii.RateFactor.HasValue && ii.RateFactor.Value != 0) rf = (100 + ii.RateFactor.Value) / 100; - // Claude: Effektive Stunden inkl. Faktor ermitteln, dann auf verbleibendes Budget kappen - var countMitFactorVoll = Math.Round(ii.UnitCount.Value * rf, 2, MidpointRounding.AwayFromZero); - var countMitFactor = countMitFactorVoll; - if (maxApproved < countMitFactor) - countMitFactor = maxApproved; + // Claude: Rohstunden (ohne Faktor) ermitteln und gegen verbleibendes Budget kappen + var rawCount = Math.Round(ii.UnitCount.Value, 2, MidpointRounding.AwayFromZero); + var cappedRawCount = rawCount; + if (maxApproved < cappedRawCount) + cappedRawCount = maxApproved; - // Claude: Verbrauchte effektive Stunden vom Restbudget abziehen - maxApproved -= countMitFactor; + // Claude: Verbrauchte Rohstunden vom Restbudget abziehen (Faktor hat keinen Einfluss auf das Budget) + maxApproved -= cappedRawCount; if (ii.AmountPerUnit.HasValue) { - var unitCountVoll = ii.UnitCount; - - // Claude: Teilkappung – ein separates Item für die weggekappten Stunden anlegen (wird ohne Betrag dargestellt) - if (countMitFactorVoll - countMitFactor > 0 && countMitFactor != 0) + // Claude: Teilkappung – separates Item für die weggekappten Rohstunden anlegen (ohne Betrag) + if (rawCount - cappedRawCount > 0 && cappedRawCount != 0) { gekapptesItem = new InvoiceItem { @@ -106,25 +104,25 @@ namespace EndartFabrik.Invoicing MaxApprovedUnitCount = ii.MaxApprovedUnitCount, RateFactor = ii.RateFactor, SupportConceptApprovalPeriodOid = ii.SupportConceptApprovalPeriodOid, - UnitCount = countMitFactorVoll - countMitFactor, + UnitCount = rawCount - cappedRawCount, UnitDescription = ii.UnitDescription // GrossAmountTotal bleibt null → 0 EUR }; } - // Claude: UnitCount auf die abrechenbaren effektiven Stunden (inkl. Faktor) setzen - ii.UnitCount = countMitFactor; + // Claude: UnitCount auf die abrechenbaren Rohstunden setzen (ohne Faktor) + ii.UnitCount = cappedRawCount; - if (countMitFactor != 0) + if (cappedRawCount != 0) { - // Claude: Betrag aus abrechenbaren Stunden × Stundensatz berechnen (Faktor bereits in UnitCount enthalten) + // Claude: Nettobetrag aus Rohstunden × Stundensatz, Faktor erst beim Bruttobetrag anwenden ii.AmountTotal = ii.UnitCount.Value * ii.AmountPerUnit.Value; - ii.GrossAmountTotal = Math.Round(ii.AmountTotal.Value, 2, MidpointRounding.AwayFromZero); + ii.GrossAmountTotal = Math.Round(ii.AmountTotal.Value * rf, 2, MidpointRounding.AwayFromZero); } else { - // Claude: Vollständige Kappung – UnitCount für Anzeige wiederherstellen, aber 0 EUR abrechnen - ii.UnitCount = unitCountVoll.Value * rf; + // Claude: Vollständige Kappung – Rohstunden für Anzeige wiederherstellen, aber 0 EUR abrechnen + ii.UnitCount = rawCount; ii.AmountTotal = null; ii.GrossAmountTotal = null; }