From 5c654ad848f6e1d57b323cecf236501ca5bcbb53 Mon Sep 17 00:00:00 2001 From: metacube Date: Tue, 19 May 2026 08:07:29 +0200 Subject: [PATCH] Document finance formulas by country --- ...E_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md | 510 ++++++++++++++++++ 1 file changed, 510 insertions(+) create mode 100644 TrafagSalesExporter/docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md diff --git a/TrafagSalesExporter/docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md b/TrafagSalesExporter/docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md new file mode 100644 index 0000000..04dc293 --- /dev/null +++ b/TrafagSalesExporter/docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md @@ -0,0 +1,510 @@ +# Finance Berechnungsformeln pro Land + +Stand: 2026-05-19 + +Zweck: Dieses Dokument beschreibt die aktuell im Programm verwendeten Formeln fuer den Soll/Ist-Vergleich 2025. Es ist fuer eine zweite KI oder eine fachliche Gegenpruefung geschrieben. + +## Gemeinsame Vergleichslogik + +Die echte Webseite `/finance-cockpit/vergleich` und das Testprogramm `/finance` verwenden beide `FinanceReconciliationService`. + +Quelle fuer den Ist-Wert ist immer `CentralSalesRecords`. Die Jahresabgrenzung ist: + +```text +Jahr = Year(PostingDate ?? InvoiceDate ?? ExtractionDate) +``` + +Fuer 2025 werden die Zeilen je Land gruppiert. Die Gruppierung laeuft ueber `ResolveReferenceKey(Land, Tsc)`. + +Pro Land berechnet das Programm mehrere Kandidaten: + +```text +SalesPriceValue + = Sum(CentralSalesRecords.SalesPriceValue) + +DocTotalFC - VatSumFC + = Sum(DocumentTotalForeignCurrency - VatSumForeignCurrency) + = pro Beleg dedupliziert + +Nettofakturawert Hauswaehrung pro Position + = Sum(DocumentTotalLocalCurrency - VatSumLocalCurrency) + = ueber alle Positionen + +Nettofakturawert Hauswaehrung pro Beleg dedupliziert + = Sum(DocumentTotalLocalCurrency - VatSumLocalCurrency) + = pro Beleg nur einmal + +Nettofakturawert Hauswaehrung -> CHF Budget 2025 + = Sum((DocumentTotalLocalCurrency - VatSumLocalCurrency) * Budgetkurs nach CHF) +``` + +Belegschluessel fuer Deduplizierung: + +```text +DocumentEntry > 0: + Tsc + DocumentType + DocumentEntry +sonst: + Tsc + DocumentType + InvoiceNumber +``` + +Auswahl des Haupt-Ist-Werts: + +```text +1. Kandidat mit IsPreferred = true +2. sonst Nettofakturawert Hauswaehrung pro Position +3. sonst Nettofakturawert Hauswaehrung pro Beleg dedupliziert +4. sonst SalesPriceValue +``` + +`IsPreferred` wird so gesetzt: + +```text +SalesPriceValue: + bevorzugt, wenn Belegkopfwerte wiederholt aussehen und SalesPriceValue != 0 + +Nettofakturawert Hauswaehrung pro Position: + bevorzugt, wenn Belegkopfwerte nicht wiederholt aussehen + +Nettofakturawert Hauswaehrung pro Beleg dedupliziert: + bevorzugt, wenn Belegkopfwerte wiederholt aussehen und SalesPriceValue == 0 +``` + +Vergleich gegen Soll: + +```text +ReferenceValue = FinanceReference.CheckValue ?? FinanceReference.LocalCurrencyValue +Differenz = IstValue - ReferenceValue +Status OK, wenn Abs(Differenz) <= 1 +``` + +Intercompany-Abzug ist aktuell nur Diagnose: + +```text +ValueExcludingIntercompany = Value - IntercompanyValue +``` + +Der IC-Abzug veraendert die Originaldaten und den Haupt-Ist-Wert nicht. + +## Quellen und Formeln pro Land + +| Land | Key | Quelle | Hauswaehrung | Soll/Referenz 2025 | Aktueller Haupt-Ist-Wert | +|---|---:|---|---|---:|---| +| Schweiz | CH | SAP OData `ZSCHWEIZ`, falls importiert | CHF | leer | kein Sollwert im Seed | +| Oesterreich | AT | SAP OData `ZSCHWEIZ`, falls importiert | EUR | 3'443'863 | gemeinsame Logik | +| Deutschland | DE | nur falls Daten in `CentralSalesRecords` vorhanden | EUR | 3'635'923 | gemeinsame Logik | +| Spanien | ES | Sage SQL CSV / Manual Excel | EUR | 3'102'333.61 | SalesPriceValue aus Sage `ImporteNeto` | +| Frankreich | FR | SAP B1/HANA Schema `fr01_p` | EUR | CheckValue 1'471'218 | SalesPriceValue / B1 Positions-Netto | +| Indien | IN | Sage/HANA `TRAFAG_LIVE` | INR | CheckValue 750'936'591 | Hauswaehrung INR | +| Italien | IT | SAP B1/HANA Schema `it01_p` | EUR | 7'669'840 | B1 Positions-Netto mit provisorischem Filter | +| UK | UK | Manual Excel aus Sage, Ordnername `UK_B1` nur technisch | GBP | 3'538'972 | SageNetSales in GBP | +| USA | US | SAP B1/HANA Schema `us01_p` | USD | CheckValue 3'749'865 | SalesPriceValue / B1 Positions-Netto | + +Hinweis: Der Nutzer schrieb frueher teilweise `AZ`; im Programm ist der Referenz-Key fuer Oesterreich `AT`. + +## CH und AT + +Aktuelle Quelle: + +```text +SourceSystem = SAP +TSC = ZSCHWEIZ +EntitySet = FinanzdataSchweizOeSet +``` + +Aktuelles Mapping: + +```text +SalesPriceValue = Z.NetwrHc +SalesCurrency = Z.Hwaer +DocumentCurrency = Z.Waerk +DocumentTotalForeignCurrency = Z.NetwrDc +DocumentTotalLocalCurrency = Z.NetwrHc +VatSumForeignCurrency = 0 +VatSumLocalCurrency = 0 +PostingDate = Z.Fkdat +InvoiceDate = Z.Fkdat +DocumentType = Z.Fkart +``` + +Formel: + +```text +Ist = Sum(Z.NetwrHc) +``` + +Da `VatSumLocalCurrency = 0` und `DocumentTotalLocalCurrency = SalesPriceValue = Z.NetwrHc`, fuehren `SalesPriceValue` und `Nettofakturawert Hauswaehrung` auf denselben fachlichen Wert, sofern die SAP-OData-Zeilen positionsbezogen sind. + +Offen: + +```text +CH hat aktuell keinen FinanceReference-Sollwert. +AT hat Soll 3'443'863 EUR. +Ob FKDAT fuer diese Quelle fachlich Buchungsdatum oder Fakturadatum ist, muss bei Bedarf noch bestaetigt werden. +``` + +## DE + +Aktueller Referenzwert: + +```text +FinanceReference.DE.LocalCurrencyValue = 3'635'923 +Hauswaehrung = EUR +``` + +Formel im Vergleich: + +```text +Ist = gemeinsame Auswahl aus CentralSalesRecords fuer Key DE +``` + +Das heisst konkret: + +```text +bevorzugt SalesPriceValue, wenn Belegkopfwerte wiederholt aussehen +sonst Nettofakturawert Hauswaehrung pro Position +sonst Nettofakturawert Hauswaehrung pro Beleg dedupliziert +sonst SalesPriceValue +``` + +Offen: + +```text +Fuer DE ist in diesem Dokument keine bestaetigte landesspezifische Importformel dokumentiert. +Wenn DE aus Sage kommt, muss in einer Sitzung geklaert werden: +- welche Datei/CSV geladen wird +- welches Betragsfeld Rhino verwendet +- wie Gutschriften, Zuschlaege, Freight/Charges und Steuer getrennt werden +``` + +## ES + +Aktuelle Quelle: + +```text +SourceSystem = MANUAL_EXCEL / Sage CSV +TSC = TRES +Land = Spanien +``` + +Exportskripte: + +```text +scripts/Export-SageSpainSalesCsv.ps1 +SageSpainFinalExportPackage/Export-SageSpainSalesCsv.ps1 +``` + +Sage-SQL-Formel im Export: + +```text +SalesPriceValue = LineasAlbaranCliente.ImporteNeto + +wenn c.TipoNuevaFra = 2 + oder c.SerieFactura = 'REC' + oder c.StatusAbono <> 0: + SalesPriceValue = -ABS(LineasAlbaranCliente.ImporteNeto) +sonst: + SalesPriceValue = LineasAlbaranCliente.ImporteNeto + +SalesCurrency = EUR +DocumentCurrency = EUR +CompanyCurrency = EUR +``` + +Formel im Vergleich: + +```text +Ist ES = Sum(SalesPriceValue) +Soll ES = 3'102'333.61 EUR +``` + +Bekannter Stand: + +```text +Ist ca. 3'082'320.18 EUR +Differenz ca. -20'013.43 EUR +``` + +Offen: + +```text +Abweichung ist ca. 0.65%. +Wahrscheinliche Pruefpunkte: Fracht, Portes, Zuschlaege, Rundungen, Versicherung, +Finanzierung, nicht-artikelbezogene Belegpositionen oder abweichende Rhino-Auswertung. +``` + +## FR + +Aktuelle Quelle: + +```text +SourceSystem = BI1 +HANA Schema = fr01_p +SAP B1 Tabellen = OINV/INV1 und ORIN/RIN1 +``` + +B1-HANA-Formel im Import: + +```text +Invoices: + SalesPriceValue = INV1.LineTotal + Quantity = INV1.Quantity + PostingDate = OINV.DocDate + InvoiceDate = OINV.TaxDate + DocumentTotalLC = OINV.DocTotal + VatSumLC = OINV.VatSum + +Credit Notes: + SalesPriceValue = RIN1.LineTotal * -1 + Quantity = RIN1.Quantity * -1 + PostingDate = ORIN.DocDate + InvoiceDate = ORIN.TaxDate + DocumentTotalLC = ORIN.DocTotal * -1 + VatSumLC = ORIN.VatSum * -1 +``` + +Kein landesspezifischer Kontenfilter fuer FR. + +Formel im Vergleich: + +```text +Ist FR = Sum(SalesPriceValue) +Soll FR = CheckValue 1'471'218 EUR +``` + +Bekannter Stand: + +```text +Ist ca. 1'471'218.44 EUR +Differenz ca. +0.44 EUR +``` + +## IN + +Aktuelle Quelle: + +```text +SourceSystem = SAGE +HANA Schema = TRAFAG_LIVE +TSC = TRIN +Hauswaehrung = INR +``` + +Formel im Vergleich: + +```text +Ist IN = bevorzugter Kandidat in Hauswaehrung INR +Soll IN = CheckValue 750'936'591 INR +``` + +Praktischer Effekt: + +```text +Die INR-Hauswaehrung ist fuer den Soll/Ist-Vergleich fuehrend. +CHF-Budgetwert ist nur ein Kandidat, nicht der Hauptvergleich. +``` + +Bekannter Stand: + +```text +Ist ca. 750'936'591.38 INR +Differenz ca. +0.38 INR +``` + +Offen: + +```text +Die genaue Sage/HANA-Quelltabellenformel fuer IN ist in dieser Datei nicht separat aufgeschluesselt. +Gegenpruefung sollte in CentralSalesRecords kontrollieren, welcher Kandidat als preferred gewaehlt wird. +``` + +## IT + +Aktuelle Quelle: + +```text +SourceSystem = BI1 +HANA Schema = it01_p +SAP B1 Tabellen = OINV/INV1 und ORIN/RIN1 +``` + +B1-HANA-Grundformel wie FR: + +```text +Invoices: + SalesPriceValue = INV1.LineTotal + PostingDate = OINV.DocDate + +Credit Notes: + SalesPriceValue = RIN1.LineTotal * -1 + PostingDate = ORIN.DocDate +``` + +Zusaetzlicher provisorischer Filter in `HanaQueryService.BuildRevenueAccountFilter`: + +```sql +AND p."AcctCode" LIKE '47005%' +AND p."AcctCode" NOT LIKE '4700504%' +AND h."CardCode" NOT IN ( + 'C_IT01_0022987', + 'C_IT01_0306928', + 'C_IT01_0306138', + 'C_IT01_0309653', + 'C_IT01_0304885', + 'C_IT01_0306475' +) +``` + +Formel im Vergleich: + +```text +Ist IT = Sum(SalesPriceValue) nach obigem B1-Filter +Soll IT = 7'669'840 EUR +``` + +Bekannter Stand: + +```text +Ist ca. 7'669'641.47 EUR +Differenz ca. -198.53 EUR +``` + +Wichtiger Pruefhinweis: + +```text +Dieser IT-Filter ist noch hart in der HANA-Abfrage codiert. +Er ist ein Arbeitsfilter aus Screenshot/Cache und muss spaeter in eine konfigurierbare Site-/Source-Regel verschoben werden, +wenn Italien die fachliche B1/Rhino-Regel bestaetigt. +``` + +## UK + +Aktuelle Quelle: + +```text +SourceSystem = MANUAL_EXCEL +Fachlich = Sage +TSC = TRUK +SharePoint-Ordner = Import/Finance/UK_B1 +``` + +Wichtig: + +```text +Der Ordnername UK_B1 ist nur technisch. UK ist fachlich Sage, nicht SAP B1. +``` + +Aktuelles Manual-Excel-Mapping: + +```text +SalesPriceValue = SageNetSales([Sales Price/Value], [Quantity], [Document Type], [DocumentType], [Type]) +SalesCurrency = GBP +DocumentCurrency = GBP +CompanyCurrency = GBP +PostingDate = invoice date +InvoiceDate = invoice date +``` + +`SageNetSales(...)` im Importer: + +```text +netLineAmount = amount * quantity + +wenn DocumentType CREDIT, CREDIT NOTE, CREDITNOTE, ABONO, GUTSCHRIFT, CRN oder CN enthaelt: + SalesPriceValue = -ABS(netLineAmount) +sonst: + SalesPriceValue = netLineAmount +``` + +Formel im Vergleich: + +```text +Ist UK = Sum(SalesPriceValue) in GBP +Soll UK = LocalCurrencyValue 3'538'972 GBP +``` + +Bekannter Stand: + +```text +Ist ca. 3'533'710.09 GBP +Differenz ca. -5'261.91 GBP +``` + +Offen: + +```text +UK-Abweichung ueber Sage-Exportvollstaendigkeit, Discounts, Freight/Charges, +Gutschriften und 2nd-party-Abgrenzung pruefen. +``` + +## US + +Aktuelle Quelle: + +```text +SourceSystem = BI1 +HANA Schema = us01_p +SAP B1 Tabellen = OINV/INV1 und ORIN/RIN1 +Hauswaehrung = USD +``` + +B1-HANA-Formel wie FR: + +```text +Invoices: + SalesPriceValue = INV1.LineTotal + PostingDate = OINV.DocDate + +Credit Notes: + SalesPriceValue = RIN1.LineTotal * -1 + PostingDate = ORIN.DocDate +``` + +Formel im Vergleich: + +```text +Ist US = Sum(SalesPriceValue) in USD +Soll US = CheckValue 3'749'865 USD +``` + +Bekannter Stand: + +```text +Ist ca. 3'749'865.33 USD +Differenz ca. +0.33 USD +``` + +## Was nicht verwechselt werden darf + +```text +Soll/Ist-Vergleich: + FinanceReconciliationService, gleiche Logik in Webseite und Testprogramm. + +Import/Transformation: + SiteExportService liest Quelle -> wendet RecordTransformationService.Apply(records, rules) an -> schreibt CentralSalesRecords. + +UK/ES Sage-Korrektur: + in bestehendem Import-/Exportpfad umgesetzt, nicht als separate nachtraegliche Vergleichsklasse. + +IT: + aktuell noch provisorischer Hardcode in HanaQueryService fuer Schema it01_p. +``` + +## Code-Stellen fuer Gegenpruefung + +```text +Services/FinanceReconciliationService.cs + globale Kandidaten, Auswahl, Soll/Ist-Differenz, Jahrabgrenzung + +Services/HanaQueryService.cs + SAP B1/HANA Importformel fuer FR/IT/US und IT-Sonderfilter + +Services/ManualExcelImportService.cs + SageNetSales(...) fuer UK Manual Excel Import + +Services/DatabaseSeedService.cs + FinanceReference-Sollwerte, UK Mapping, ZSCHWEIZ Mapping, Default-Waehrungen + +scripts/Export-SageSpainSalesCsv.ps1 +SageSpainFinalExportPackage/Export-SageSpainSalesCsv.ps1 + Spanien Sage SQL Export und Gutschrift-Logik +```