From 9a74e248e923103501ce7c202ee8d47eaf1ae147 Mon Sep 17 00:00:00 2001 From: metacube Date: Wed, 27 May 2026 09:40:12 +0200 Subject: [PATCH] Organize markdown docs for RAG routing --- TrafagSalesExporter/HANDOFF_2026-04-15.md | 1933 +--- TrafagSalesExporter/LLM_SYSTEM_GUIDE.md | 736 +- TrafagSalesExporter/NEXT_STEPS_2026-04-15.md | 1369 +-- .../docs/FINANCE_DASHBOARD_TODO_2026-05-15.md | 65 +- .../FINANCE_ES_MAIL_ABWEICHUNG_2026-05-15.md | 39 +- .../docs/FINANCE_HANDOFF_2026-05-18.md | 393 +- .../FINANCE_IT_MAIL_ABWEICHUNG_2026-05-15.md | 42 +- .../FINANCE_UK_MAIL_ABWEICHUNG_2026-05-15.md | 48 +- ...INANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md | 77 +- .../docs/MD_DOKUMENTENSTATUS_2026-05-20.md | 2 + TrafagSalesExporter/docs/RAG_ROUTER.md | 52 + TrafagSalesExporter/docs/rag/ADMIN.md | 22 + TrafagSalesExporter/docs/rag/ARCHITECTURE.md | 15 + TrafagSalesExporter/docs/rag/DEPLOYMENT.md | 22 + TrafagSalesExporter/docs/rag/FINANCE.md | 45 + TrafagSalesExporter/docs/rag/HR_KPI.md | 21 + TrafagSalesExporter/docs/rag/MANUAL_IMPORT.md | 32 + TrafagSalesExporter/docs/rag/PROJECT.md | 24 + .../raw_md_archive/HISTORY_CANONICAL.md.raw | 8359 +++++++++++++++++ .../raw_md_archive/original_history_raws.zip | Bin 0 -> 87583 bytes TrafagSalesExporter/lastchange.md | 2349 +---- 21 files changed, 8711 insertions(+), 6934 deletions(-) create mode 100644 TrafagSalesExporter/docs/RAG_ROUTER.md create mode 100644 TrafagSalesExporter/docs/rag/ADMIN.md create mode 100644 TrafagSalesExporter/docs/rag/ARCHITECTURE.md create mode 100644 TrafagSalesExporter/docs/rag/DEPLOYMENT.md create mode 100644 TrafagSalesExporter/docs/rag/FINANCE.md create mode 100644 TrafagSalesExporter/docs/rag/HR_KPI.md create mode 100644 TrafagSalesExporter/docs/rag/MANUAL_IMPORT.md create mode 100644 TrafagSalesExporter/docs/rag/PROJECT.md create mode 100644 TrafagSalesExporter/docs/raw_md_archive/HISTORY_CANONICAL.md.raw create mode 100644 TrafagSalesExporter/docs/raw_md_archive/original_history_raws.zip diff --git a/TrafagSalesExporter/HANDOFF_2026-04-15.md b/TrafagSalesExporter/HANDOFF_2026-04-15.md index c4c826a..e636dcc 100644 --- a/TrafagSalesExporter/HANDOFF_2026-04-15.md +++ b/TrafagSalesExporter/HANDOFF_2026-04-15.md @@ -1,1931 +1,36 @@ # TrafagSalesExporter Handoff -Stand: 2026-05-20 +Stand: 2026-05-27 -## Aktueller Handoff-Zusatz 2026-05-20 +Diese Datei ist fuer tokenarme RAG-Nutzung komprimiert. -Seit den aelteren Handoff-Eintraegen wurden folgende Punkte umgesetzt und dokumentiert: +## Aktueller Kurzstand -- `Management Analyse` hat einen fuehrenden Reiter `Finance Summary`. -- Finance Summary nutzt dieselbe `FinanceRuleEngine` wie das zentrale Excel-Blatt `Finance Summary`. -- Filter fuer Jahr, Land und Waehrung wirken auf das Finance-Endergebnis. -- DE 2026 wirft keinen Fehler mehr, sondern zeigt wegen DE/Alphaplan-2025-Zwang einen leeren Zustand mit Hinweis. -- HR KPI Cockpit wurde erweitert: - - Anleitung-Reiter - - Datenordner anpassbar - - Dateifrische / Datenstatus - - Ampeln - - Periodenvergleich - - Datenqualitaet - - Austritte nach Typ/Organisation - - Absenzen nach Organisation / Top-Absenzen - - Managementsicht - - Drucken/PDF -- Anwenderdokus: - - `docs/HR_KPI_ANLEITUNG_HR_2026-05-20.docx` - - `docs/FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx` -- Markdown-Dokumentenstatus: - - `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` +- Fuehrender Kurzkontext: `docs/rag/PROJECT.md`. +- Architektur-Kurzkontext: `docs/rag/ARCHITECTURE.md`. +- Themenrouter: `docs/RAG_ROUTER.md`. +- Fuer normale Weiterarbeit zuerst Router und passende `docs/rag/*.md` laden. -Validierung: +## Wichtige Bereiche -- `dotnet test TrafagSalesExporter.sln --verbosity minimal` -- Ergebnis am 2026-05-20: `77/77` Tests gruen. +- Finance-Regeln und Finance Summary: `docs/rag/FINANCE.md` +- Manual-Importe und Deltas: `docs/rag/MANUAL_IMPORT.md` +- HR KPI: `docs/rag/HR_KPI.md` +- IIS/Deployment: `docs/rag/DEPLOYMENT.md` +- Admin/Startseite: `docs/rag/ADMIN.md` -Hinweis: +## Volltext Bei Bedarf -- Aeltere Abschnitte in diesem Handoff bleiben als Historie erhalten. Fuer aktuellen Status immer zuerst diesen Zusatz, `NEXT_STEPS_2026-04-15.md`, `lastchange.md` und `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` lesen. - -## Nachtrag 2026-05-11 UK_B1 Mapping / aktueller Arbeitsstand - -Letzter Benutzerwunsch: - -- UK/England soll weiter ueber `UK_B1` laufen. -- Das Mapping soll so angepasst werden, dass die Finance-Zahl plausibel wird. -- Danach soll alles nachvollziehbar dokumentiert sein. - -Wichtiger Befund: - -- FinanceProbe zeigte fuer UK/England: - - `TSC = TRUK` - - `1'881` Zeilen - - Ist `395'605.82 GBP` - - Soll `3'749'865.00 GBP` -- In der lokalen DB waren fuer `TRUK` keine `ManualExcelColumnMappings` vorhanden. -- Der Fallback-Importer hat `Sales Price/Value` direkt als Positionswert importiert. -- Im UK-B1-Export ist `Sales Price/Value` aber ein Stueckpreis. -- Korrekte Positionslogik: +Die kanonische Detailhistorie liegt hier: ```text -SalesPriceValue = [Sales Price/Value] * [Quantity] +docs/raw_md_archive/HISTORY_CANONICAL.md.raw ``` -Probe auf existierenden Zentraldaten: +Die frueheren Original-Volltexte liegen als Wiederherstellungs-Backup hier: ```text -Summe SalesPriceValue bisher: 395'605.82 GBP -Summe SalesPriceValue * Quantity: 3'533'348.89 GBP -check.xlsx Soll: 3'749'865.00 GBP -Restdifferenz: -216'516.11 GBP +docs/raw_md_archive/original_history_raws.zip ``` -Geaenderte Dateien im aktuellen Worktree: - -- `Services/ManualExcelImportService.cs` - - grafische Manual-Excel-Mappings koennen einfache Multiplikationsausdruecke lesen: - -```text -=[Header A]*[Header B] -``` - - - Konstanten wie `=GBP` funktionieren weiterhin. - -- `Services/DatabaseSeedService.cs` - - repariert England/TRUK auf: - -```text -https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1 -``` - - - seedet fuer `TRUK` ein grafisches Mapping, insbesondere: - -```text -SalesPriceValue <- =[Sales Price/Value]*[Quantity] -SalesCurrency <- =GBP -DocumentCurrency<- =GBP -CompanyCurrency <- =GBP -PostingDate <- invoice date -InvoiceDate <- invoice date -``` - -- `TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs` - - neuer Test fuer berechnetes Manual-Excel-Mapping. - -Aktueller Teststand: - -- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false --verbosity minimal` -- Tests erfolgreich: `59/59`. -- Bekannte Warnungen: bestehende MudBlazor-Analyzerwarnungen zu `Dense`. - -Zusatzfix: - -- `DatabaseSeedService` prueft vor `EnsureUkManualExcelMapping(...)`, ob `ManualExcelColumnMappings` sauber auf `Sites` referenziert. -- Falls die Tabelle noch auf `Sites_repair_old` oder eine andere `Sites_*`-Reparaturtabelle zeigt, wird der UK-Mapping-Seed fuer diesen Start uebersprungen. -- Dadurch kann die Schema-Reparatur sauber durchlaufen. - -Naechster praktischer Schritt: - -1. SharePoint-/Graph-Zugriff reparieren. -2. FinanceProbe ist bereits auf `http://127.0.0.1:5099` gestartet. -3. `/run/export/TRUK` erneut ausfuehren. -4. `/finance` erneut pruefen. - -Praktischer Stand: - -- Lokale DB ist aktualisiert: - - `TRUK` Pfad = `UK_B1` - - `18` aktive Manual-Excel-Mapping-Zeilen -- `/finance` antwortet mit HTTP `200`. -- `/run/export/TRUK` scheitert aktuell an Auth/Netzwerk: - -```text -ClientSecretCredential authentication failed -127.0.0.1:9 connection refused -``` - -- Deshalb enthaelt `CentralSalesRecords` fuer UK noch den alten Importstand, bis SharePoint wieder erreichbar ist. - -Wichtig: - -- Das ist keine Sonderlogik, die UK-Zahlen schoenrechnet. -- Der Mapper setzt die allgemeine fachliche Regel "pro Artikel / Belegposition" um. -- Die Formel ist im grafischen Mapping sichtbar und nicht hart als UK-Spezialberechnung im Importcode versteckt. -- Falls nach neuem Export noch eine Restdifferenz bleibt, muss die UK-Datei auf weitere Netto-/Discount-/Frachtspalten geprueft werden. - -## Nachtrag 2026-05-08 Manual Excel/CSV / SharePoint-Ordner - -Aktueller Stand fuer manuelle Quellen: - -- `MANUAL_EXCEL` ist fachlich Manual Excel/CSV. -- Unterstuetzt werden `.xlsx` und `.csv`; altes `.xls` ist nicht der Zielpfad. -- Lokale Datei als Quelle: - - App liest die Datei. - - App erzeugt eine neue Exportdatei im selben lokalen Ordner. -- SharePoint-Datei als Quelle: - - App laedt die Datei temporaer herunter. - - App erzeugt eine neue Exportdatei und laedt sie in denselben SharePoint-Ordner hoch. -- SharePoint-Ordner als Quelle: - - App waehlt automatisch die neueste passende `.xlsx`/`.csv` fuer den Standort. - - Primaeres Muster: `ddMMyy_TSC.xlsx` oder `ddMMyy_TSC.csv`. - - Fallback: SharePoint `LastModifiedDateTime`. - -England / UK: - -- Standort `England`, `TSC = TRUK`, `SourceSystem = MANUAL_EXCEL`. -- Quelle ist ein SharePoint-Ordner: - -```text -https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1 -``` - -- Beispielauswahl: - - `010526_TRUK.xlsx` ist neuer als `010426_TRUK.xlsx`. -- Exportdateien werden wieder in `Import/Finance/UK_B1` geschrieben. -- Befund am 2026-05-08: England zeigte lokal faelschlich auf die Deutschland-Alphaplan-Datei; lokale DB wurde korrigiert. -- `DatabaseSeedService` repariert kuenftig einen leeren England/TRUK-Manual-Pfad auf den UK_B1-Ordner. - -Spanien / Sage: - -- Spanien nutzt `MANUAL_EXCEL` als technischen Importpfad fuer den Sage-Export. -- Die Datei `Spain_Sales_2025.csv` konnte gelesen werden (`4'341` Zeilen). -- Fehler war danach der Exportpfad: die SharePoint-URL wurde als lokaler Dateipfad interpretiert. -- Fix: SharePoint-Manual-Quellen liefern keinen `ReferenceFilePath` mehr, sondern erzeugen eine neue Exportdatei im Quellordner. - -Deutschland / Alphaplan: - -- Deutschland nutzt `MANUAL_EXCEL` als technischen Importpfad fuer Alphaplan-Excel. -- Grafisches Mapping ist vorhanden. -- Offener Punkt: konkreter Alphaplan-Datei-/SharePoint-Pfad muss im Standort hinterlegt sein, sonst kommt `Standort 'Deutschland' hat keine manuelle Excel-Datei.` - -Verifikation: - -- Tests `55/55` erfolgreich. - -## Nachtrag 2026-05-08 FinanceProbe fuer mehr Laender - -FinanceProbe wurde erweitert: - -- `FinanceReferences` werden vollstaendig angezeigt, nicht nur bei aktivem Standort oder vorhandenen Ist-Daten. -- Dadurch sind alle Soll-Laender aus der Finance-Konfiguration im Meeting sichtbar. -- Neue Sektion `Datenabdeckung je Standort` zeigt je Standort: - - Quelle/System - - Manual-/SharePoint-Pfad - - Aktivstatus - - Anzahl 2025-Zeilen in `CentralSalesRecords` - - Summe `SalesPriceValue` - - Waehrungen und Datumsbereich - - letzter Exportstatus/Fehler -- CH/AT-Erkennung im Finance-Service wurde geschaerft, damit `ZSCHWEIZ`-Zeilen mit Land `AT` Oesterreich zugeordnet werden koennen. - -Wichtig: - -- `Keine Daten` bedeutet jetzt nicht zwingend fehlende Referenz, sondern oft: Referenz ist vorhanden, aber Ist-Daten wurden noch nicht exportiert/importiert. -- Fuer neue Laender reicht es, `FinanceReferences` zu pflegen und Daten nach `CentralSalesRecords` zu bringen; die Probe zeigt sie dann automatisch. - -## Nachtrag 2026-05-11 FinanceProbe KI-Steuerung - -FinanceProbe kann jetzt nicht nur vergleichen, sondern im Testkontext auch Exporte ausloesen: - -- `/run/export/{siteKey}`: einzelner Standort nach `Id`, `TSC` oder `Land` -- `/run/export-all`: alle aktiven Standorte plus zentrale Datei -- `/run/consolidated`: zentrale Datei aus `CentralSalesRecords` - -Die Routen liefern eine HTML-Run-Summary mit Exportlogs, Finance-Abgleich und Datenabdeckung. - -Wichtig: - -- Das ist eine temporaere Test-/KI-Steuerung. -- Nicht als produktive API betrachten. -- Echte SAP/HANA/SharePoint-Zugriffe funktionieren nur mit vorhandenen Credentials und Netzverbindung auf dem Rechner. - -## Nachtrag 2026-05-07 Mapper-Konsolidierung / Finance-Konfiguration - -Architekturstand: - -- `MappedSalesRecordComposer` ist die gemeinsame Engine fuer grafisches Mapping. -- SAP OData und generisches HANA-Mapping nutzen denselben Composer fuer Joins und Zielfeldmapping. -- SAP OData laedt weiter ueber `SapGatewayService`. -- HANA-Tabellen/Views laden weiter ueber `HanaQueryService`. -- Der alte B1-HANA-Pfad ohne Mapping bleibt als Legacy-Pfad fuer bestehende BI1/SAGE-Standorte erhalten. -- `ConsolidatedExportService.ExportAsync()` erzeugt die zentrale Datei nur noch aus `CentralSalesRecords`; es gibt keinen zweiten Records-Parameter mehr. -- Manual Excel/CSV akzeptiert im Standort-Editor und Upload `.xlsx` und `.csv`. - -Neue Konfigurationstabellen: - -- `FinanceReferences`: Soll-/check.xlsx-Referenzen je Jahr und Land/Key. -- `FinanceIntercompanyRules`: IC-/2nd-party-Regeln nach Scope, Kundennummer oder Namensbestandteil. -- Budgetkurse 2025 liegen als `CurrencyExchangeRates` mit `Notes = Budget 2025`. -- Config-Export/-Import nimmt `FinanceReferences` und `FinanceIntercompanyRules` mit. - -Offen: - -- Manual-Excel-Import hat noch zwei Modi: Header-Automatik und grafisches Mapping. -- Der alte B1-HANA-Spezialpfad ist bewusst noch vorhanden, sollte aber mittelfristig durch gepflegte HANA-Mappings abgeloest werden. - -Verifikation: - -- Hauptprojekt Build erfolgreich. -- Tests `52/52` erfolgreich. - -## Nachtrag 2026-05-07 SAP OData / ZSCHWEIZ / Schweiz-Oesterreich - -Aktueller Architekturentscheid: - -- `ZSCHWEIZ` wird ueber SAP OData/Gateway gelesen. -- Direkter HANA-Spezialcode fuer `ZSCHWEIZ` wurde vermieden. -- Der grafische Quellen- und Feldmapper wird fuer SAP OData verwendet. -- Fuer direkte HANA-Tabellen/Views gibt es ebenfalls grafisches Mapping; das ist aber nicht der geplante Pfad fuer `ZSCHWEIZ`. - -Quellsysteme: - -- `SAP` = `SAP OData`, Anschlussart `SAP_GATEWAY`. -- `SAP_HANA` = `SAP HANA Tables/Views`, Anschlussart `HANA`. -- `BI1` und `SAGE` bleiben HANA-basierte Quellsysteme. -- `MANUAL_EXCEL` bleibt Excel/CSV. - -ABAP/SAP: - -- Datei `report.abap` enthaelt Report `ZTRAFAG_SCHWEIZ_EXPORT`. -- Ziel-Tabelle in SAP: `ZSCHWEIZ`. -- `BUKRS 1100` wird als Schweiz (`TRCH`, `CH`) geschrieben. -- `BUKRS 1200` wird als Oesterreich (`TRAT`, `AT`) geschrieben. -- `CUSTOMER_LAND` enthaelt das urspruengliche Kundenland. -- Der Report schreibt paketweise per Upsert. - -App-Seed: - -- Standort `ZSCHWEIZ` / `Schweiz/Oesterreich` wird inaktiv angelegt bzw. repariert. -- `SourceSystem = SAP`. -- Quelle `Z`, EntitySet `ZSCHWEIZSet`. -- Quelle und Feldmapping werden beim App-Start per Upsert nachgezogen; eine teilweise vorhandene ZSCHWEIZ-Konfiguration bleibt dadurch nicht leer. -- Initiales Mapping: - - `Tsc <- Z.TSC` - - `Land <- Z.LAND1` - - `InvoiceNumber <- Z.VBELN` - - `PositionOnInvoice <- Z.POSNR` - - `SalesPriceValue <- Z.NETWR_HC` - - `SalesCurrency <- Z.HWAER` - - `CustomerCountry <- Z.CUSTOMER_LAND` - -Wichtig fuer naechsten Einstieg: - -- Wenn die zentrale SAP-Service-URL noch auf `ZPOWERBI_EINKAUF_SRV` zeigt, muss beim Standort `ZSCHWEIZ` ein Service-URL-Override fuer den `ZSCHWEIZ`-OData-Service gesetzt werden. -- Feldinfos kommen ueber `$metadata`; manuelle Feldliste ist nur noetig, wenn Gateway/Metadata nicht funktioniert. -- Nach URL-Setzung: `Entity Sets refreshen`, `Felder aus Quellen laden`, Mapping kontrollieren, Standort aktivieren, Export testen. - -Verifikation: - -- Hauptprojekt Build erfolgreich. -- Tests `52/52` erfolgreich. - -## Nachtrag 2026-05-05 Aktueller Handoff FinanceProbe / Laenderabgleich - -Der aktuelle Arbeitsstand fuer den naechsten Einstieg ist der lokale FinanceProbe: - -```text -http://localhost:55417/finance -``` - -Der FinanceProbe wurde als Meeting-Ansicht erweitert: - -- `Meeting Ampel 2025` -- `Detail alle Laender` -- `Germany Excel sample check` -- `Spain CSV direct check` - -Ampel-Bedeutung: - -- Gruen: Ist/Soll passt rechnerisch gegen Referenz. -- Gelb: technische Daten vorhanden, aber Differenz oder fachliche Abgrenzung offen. -- Grau: keine belastbaren Ist-Daten im aktuellen Import. - -Wichtige Waehrungsregel fuer Management-Aussage: - -- Wenn die Quelle CHF liefert, kann CHF direkt als CHF gezeigt werden. -- Wenn die Quelle EUR/USD/GBP/INR usw. liefert, ist es Mandanten- bzw. Originalwaehrung. -- CHF-Ausweis braucht dann eine separate FX-Regel oder einen offiziell bestaetigten Kurs. - -### Spanien - -Vorhandene finale Kandidatendatei: - -```text -sagespain/v2/Spain_Sales_2025.csv -``` - -FinanceProbe liest diese Datei direkt. - -Aktueller Stand: - -- Zeilen: `4'341` -- Ist `SalesPriceValue`: `3'082'320.18` EUR -- Soll aus `check.xlsx`: `3'102'333.61` -- Differenz: `-20'013.43` -- Status: Gelb / Pruefen - -Technisch: - -- `ManualExcelImportService` kann jetzt semikolongetrennte CSV-Dateien lesen. -- Spanien-v2-CSV kann damit als `MANUAL_EXCEL` importiert werden. -- In der Detailtabelle wird Spanien nicht mehr als `Keine Daten` gezeigt, sondern als `Pruefen` mit dem v2-CSV-Wert. - -Offen fachlich: - -- Periodenlogik: `FechaFactura` vs. andere Datumsfelder -- Serien: `REG`, `LAT`, `PRO`, `REC` -- Behandlung von Gutschriften / `REC` -- offizielle Sage-Auswertung mit identischem Filter zur Sollzahl - -### Deutschland - -Vorhandenes Beispielfile: - -```text -DE_Beispiel_Export_Daten.xlsx -``` - -Wichtig: - -- Das File ist ein Beispielfile, keine finale DE-Jahresdatei. -- Es darf nicht als finale Ist-Zahl gegen die Jahresreferenz verwendet werden. - -Technischer Check: - -- relevante Spalte: `NettoPreisGesamtX` -- Mapping-Ziel: `SalesPriceValue` -- Betragszeilen: `2` -- Summe: `8'290.70` EUR -- Waehrung: `EUR` - -Interpretation: - -- Deutschland-Format ist technisch verstanden. -- Mapping funktioniert. -- Finale DE-Zahl fehlt noch. -- Fuer Abschluss/Meeting wird ein vollstaendiger DE-Jahresfile 2025 oder ein bestaetigter Importlauf benoetigt. - -### Geaenderte wichtige Dateien - -- `Tools/FinanceProbe/Program.cs` - - Management-Ampel - - Spanien-v2-CSV-Direktcheck - - Deutschland-Beispielfile-Check -- `Services/ManualExcelImportService.cs` - - CSV-Support fuer manuelle Quellen -- `Services/DatabaseSeedService.cs` - - deaktivierter Spanien-Standort als Seed/Fallback -- `TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs` - - Tests fuer CSV/Mapping -- `SAGE_SPAIN_EXPORT_2026-05-05.md` - - Spanien-Doku -- `lastchange.md` - - chronologischer Abschlussstand - -### Letzte Verifikation - -```text -dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal --no-restore -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal --no-restore -``` - -Ergebnis: - -- FinanceProbe Build erfolgreich -- Tests erfolgreich -- `50/50` Tests gruen -- FinanceProbe liefert `HTTP 200` - -## Nachtrag 2026-04-29 Dashboard-Referenzcheck Net Sales 2025 - -Das Dashboard zeigt jetzt oberhalb der Exportaktionen einen Referenzcheck fuer `Net Sales Actuals 2025`. - -Zweck: - -- schnelle Gegenpruefung, ob die gezogenen Werte gegen `check.xlsx` / Power-BI-Referenz plausibel sind -- automatische Ermittlung des Summenfelds, das am besten zum Referenzwert passt -- sichtbar machen, ob aktuell `SalesPriceValue`, `DocTotalFC - VatSumFC` oder `DocTotal - VatSum` als Vergleichsbasis genutzt wird -- `DocumentTotal*` wird nur dedupliziert pro Beleg verwendet, weil es ein Belegkopfwert ist und in der positionsbasierten Datei pro Position wiederholt wird - -Logik: - -- Ist-Wert = bester Kandidat aus: - - Summe `CentralSalesRecords.SalesPriceValue` - - Summe `DocumentTotalForeignCurrency - VatSumForeignCurrency` - - Summe `DocumentTotalLocalCurrency - VatSumLocalCurrency` -- Belegkopfwerte werden vor dem Summieren per `TSC` + `DocumentType` + `DocumentEntry` dedupliziert; falls `DocumentEntry` fehlt, per `InvoiceNumber` -- Jahr = `InvoiceDate`, falls vorhanden, sonst `ExtractionDate` -- Vergleichsjahr = `2025` -- Referenzwerte sind aus `check.xlsx` / Power BI Stand 2026-04-29 im Code hinterlegt -- wenn ein Power-BI-Referenzwert vorhanden ist, wird dieser als Vergleich verwendet -- sonst wird der LC-Referenzwert verwendet - -Angezeigt werden: - -- Firma -- Ist 2025 -- Referenz -- Summenfeld -- Referenzquelle (`Power BI` oder `LC`) -- Differenz -- Waehrungen -- Zeilen -- Status `OK`, `Pruefen` oder `Keine Daten` - -Verifikation: - -- `dotnet build .\TrafagSalesExporter.csproj --verbosity minimal` erfolgreich -- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` erfolgreich -- lokaler Dashboard-Start geprueft: `http://localhost:55416` antwortet mit HTTP `200` - -Naechster Bedienablauf, damit die korrekten Summen kommen: - -1. App starten bzw. offen lassen: `http://localhost:55416` -2. Im Dashboard neue Daten ziehen: - - entweder `Alle exportieren` - - oder einzelne Standorte per `Export` -3. Danach `Zentrale Datei neu erzeugen` ausfuehren. -4. Oben im Dashboard den Block `Net Sales Actuals 2025 Referenz` pruefen. -5. Entscheidend ist die Spalte `Summenfeld`: - - `Sales Price/Value` = Positionssumme - - `DocTotalFC - VatSumFC` = Netto-Belegsumme in Belegwaehrung, dedupliziert pro Beleg - - `DocTotal - VatSum` = Netto-Belegsumme in Hauswaehrung, dedupliziert pro Beleg -6. `Status = OK` bedeutet: Abweichung zur Referenz maximal 1. -7. `Status = Pruefen` bedeutet: Feld, Datenquelle, Zeitraum oder Standortkonfiguration fachlich kontrollieren. - -Wichtig: - -- Mit alten zentralen Daten bleiben die neuen B1-Felder leer bzw. `0`. -- Fuer die echte Pruefung von `DocEntry`, `DocTotal*`, `VatSum*`, `DocRate` und `OADM.MainCurncy` muss zuerst neu exportiert werden. -- Fuer neue Jahre ist aktuell noch kein dynamischer Referenzjahres-Schalter eingebaut; der harte Referenzcheck ist Stand jetzt auf `2025`, weil `check.xlsx` die 2025-Referenzen enthaelt. - -## Nachtrag 2026-04-29 Export-all-Abbruch / SQLite-FK-Reparatur - -Beim Klick auf `Export all` kam: - -- `An error occurred while saving the entity changes. See the inner exception for details.` - -Ursache: - -- die bestehende SQLite-DB hatte in `ExportLogs`, `AppEventLogs` und `CentralSalesRecords` noch Foreign Keys auf `"Sites_repair_old"` -- diese Reparatur-Zwischentabelle existiert nicht mehr -- beim Speichern neuer Logs oder zentraler Datensaetze konnte SQLite deshalb nicht mehr korrekt speichern - -Korrektur: - -- `DatabaseSchemaMaintenanceService` erkennt jetzt nicht nur `Sites_old`, sondern auch alte Reparaturtabellen wie `Sites_repair_old` -- betroffene Tabellen werden beim App-Start automatisch neu aufgebaut -- `AppEventLogService` und `ExportLogService` fangen eigene Log-Speicherfehler ab, damit Logging-Probleme nicht den ganzen Export abbrechen -- Dashboard-Fehlerausgaben zeigen jetzt auch die Inner Exception, falls vorhanden - -Verifikation: - -- App neu gestartet -- DB-Schema direkt geprueft: - - `AppEventLogs` -> `FOREIGN KEY (SiteId) REFERENCES Sites (Id)` - - `ExportLogs` -> `FOREIGN KEY (SiteId) REFERENCES Sites (Id)` - - `CentralSalesRecords` -> `FOREIGN KEY (SiteId) REFERENCES Sites (Id)` -- `dotnet build .\TrafagSalesExporter.csproj --verbosity minimal` erfolgreich -- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` erfolgreich - -Direkt danach beobachtete Exportfehler: - -- Frankreich/Italien/USA: `invalid schema name ... line 40` durch HANA-Query-Quoting - - Ursache: Query nutzte `"schema"."Tabelle"` - - Korrektur: wieder `schema."Tabelle"` wie im alten funktionierenden Stand -- Indien: `authentication failed` - - Konfiguration/Credentials pruefen, kein Codefehler aus dieser Aenderung -- England/Spanien/Deutschland: `MANUAL_EXCEL`, aber keine manuelle Excel-Datei hinterlegt - - entweder Datei hinterlegen oder Standort deaktivieren/Quellsystem korrigieren - -## Nachtrag 2026-04-29 B1-Belegwaehrungsfelder aus HANA - -Der HANA/B1-Export wurde um Beleg- und Hauswaehrungsfelder erweitert. - -Grund: - -- `p.StockPrice` muss fachlich in der B1-Hauswaehrung bewertet werden -- die Hauswaehrung kommt aus `OADM.MainCurncy` -- bisher wurde `StandardCostCurrency` aus `p.Currency` bzw. `h.DocCur` abgeleitet -- fuer Power-BI-/Cockpit-Gegenpruefung muessen Belegwaehrung, Hauswaehrung, Netto-/Steuerbetraege und Kurs sichtbar sein - -Neue Felder in `SalesRecord` und `CentralSalesRecord`: - -- `DocumentEntry` -- `DocumentCurrency` -- `DocumentTotalForeignCurrency` -- `DocumentTotalLocalCurrency` -- `VatSumForeignCurrency` -- `VatSumLocalCurrency` -- `DocumentRate` -- `CompanyCurrency` - -B1-Feldmapping: - -- `DocumentEntry` = `OINV/ORIN.DocEntry` -- `DocumentCurrency` = `OINV/ORIN.DocCur` -- `DocumentTotalForeignCurrency` = `OINV/ORIN.DocTotalFC` -- `DocumentTotalLocalCurrency` = `OINV/ORIN.DocTotal` -- `VatSumForeignCurrency` = `OINV/ORIN.VatSumFC` -- `VatSumLocalCurrency` = `OINV/ORIN.VatSum` -- `DocumentRate` = `OINV/ORIN.DocRate` -- `CompanyCurrency` = `OADM.MainCurncy` -- `StandardCostCurrency` = `OADM.MainCurncy` - -Technische Umsetzung: - -- `HanaQueryService` liest `OADM` jetzt per `CROSS JOIN` -- Invoice- und Credit-Note-Query liefern die neuen Felder -- bei Gutschriften werden Dokument- und Steuerbetraege mit negativem Vorzeichen uebernommen -- `CentralSalesRecords`-Schema wurde erweitert -- bestehende SQLite-DBs erhalten die neuen Spalten per `DatabaseSchemaMaintenanceService` -- `CentralSalesRecordService` persistiert und liest die neuen Felder -- `ExcelExportService` schreibt die neuen Spalten in Standort- und `Sales_All_*.xlsx`-Dateien -- `ManualExcelImportService` kann die neuen Spalten wieder einlesen -- `ConfigTransferService` erhaelt die neuen Felder beim Remapping zentraler Laufzeitdaten - -Wichtig fuer Power BI: - -- die neuen `DocumentTotal*`- und `VatSum*`-Felder sind Belegkopfwerte -- sie werden in der positionsbasierten Excel pro Positionszeile wiederholt -- diese Felder duerfen daher nicht blind positionsweise summiert werden -- fuer Belegkopfsummen in Power BI zuerst nach `DocumentType`, `Invoice Number`, `TSC` und ggf. `Land` deduplizieren -- besser: nach `TSC` + `DocumentType` + `DocumentEntry` deduplizieren, weil `DocEntry` aus B1 jetzt mitgezogen wird -- positionsbasierte Auswertungen sollen weiterhin mit positionsbezogenen Feldern wie `Sales Price/Value`, `Quantity` oder `Standard cost` arbeiten - -Wichtig zum aktuellen Datenbestand: - -- alte zentrale Daten wurden vor der Erweiterung exportiert und haben fuer die neuen B1-Felder noch `0` -- nach einem neuen Export/Rebuild der zentralen Daten koennen `DocEntry`, `DocTotal*`, `VatSum*`, `DocRate` und `OADM.MainCurncy` fachlich verglichen werden - -Verifikation: - -- `dotnet build .\TrafagSalesExporter.csproj --verbosity minimal` erfolgreich -- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` erfolgreich -- `48/48` Tests gruen -- `ManualExcelImportServiceTests` pruefen die neuen Excel-Spalten -- `CentralSalesRecordServiceTests` pruefen Persistenz und Ruecklesen der neuen B1-Felder - -## Nachtrag 2026-04-29 Clean-Code-/DI-Befund - -Der aktuelle Code ist DI-orientiert und deutlich besser strukturiert als zu Beginn des Refactorings, aber noch nicht durchgehend ein Clean-Code-Ideal. - -Positiv: - -- Services werden weitgehend ueber Interfaces und DI verdrahtet -- `DataSourceAdapter` trennt die Quellsysteme -- Page-Services reduzieren direkte DB-Logik in mehreren Razor-Seiten -- `Scoped` fuer UI-nahe Services und `Singleton` fuer gemeinsame Infrastruktur/Orchestrierung ist bewusst gewaehlt -- Testabdeckung fuer zentrale Fachlogik ist vorhanden und waechst - -Weiterhin offene Clean-Code-Risiken: - -- `DatabaseInitializationService` ist weiterhin produktiver Reparatur-/Migrationspfad -- `Settings.razor` und `Standorte.razor` enthalten noch viel Workflow-/UI-Logik -- `ManagementCockpitService` und `ConfigTransferService` sind breit und sollten spaeter weiter aufgeteilt werden -- Retry-/Robustheitslayer fuer externe Systeme fehlt -- Secret-Store fehlt -- Auth-Rollenmodell ist aktuell pragmatisch, aber noch grob - -Bewertung: - -- Architektur: brauchbar bis gut -- DI: grundsaetzlich sauber -- Clean Code: mittel bis gut, mit klaren Altlasten - -Dieser Befund wurde bewusst nur dokumentiert. Die strukturelle Bereinigung wird spaeter priorisiert. - -## Nachtrag 2026-04-29 Authentifizierung / AD-Zugriffsschutz - -Nach Rueckmeldung der IT wurde ein Zugriffsschutz fuer die Blazor-App eingebaut. - -Vorher konnte jeder Benutzer mit Netzwerkzugriff auf die App-URL die Anwendung oeffnen. Das war kritisch, weil die App Verkaufsdaten, Standort-/Quellsystemkonfiguration, SharePoint-Konfiguration, Config Import/Export und Secrets bzw. Zugangsdatenfelder beruehrt. - -Neuer Stand: - -- die App ist grundsaetzlich authentifizierungspflichtig -- produktives Ziel ist Windows Authentication / Active Directory -- Berechtigungen laufen ueber AD-Gruppen -- es gibt keine eigene Benutzer-/Passwortverwaltung in der App -- es gibt keinen versteckten produktiven Backdoor - -Neue Security-Dateien: - -- `Security/SecurityOptions.cs` -- `Security/SecurityPolicies.cs` -- `Security/DevelopmentAuthenticationHandler.cs` - -Geaenderte zentrale Dateien: - -- `Program.cs` -- `Components/Routes.razor` -- `Components/_Imports.razor` -- `Components/Layout/NavMenu.razor` -- `Components/Layout/MainLayout.razor` -- `appsettings.json` -- `appsettings.Development.json` - -Aktuelles Rollenmodell: - -- `Security:AccessGroups` steuert Zugriff auf die App -- `Security:AdminGroups` steuert Admin-Berechtigung -- Default-Gruppen sind `TRAFAG\\TrafagSalesExporter-Users` und `TRAFAG\\TrafagSalesExporter-Admins` -- echte Gruppennamen muessen von der IT bestaetigt oder angepasst werden - -Admin-geschuetzte Seiten: - -- `Settings` -- `Standorte` -- `Transformations` - -Dashboard, Management Cockpit und Logs bleiben fuer berechtigte angemeldete Benutzer sichtbar. - -Development: - -- `appsettings.Development.json` aktiviert bei `ASPNETCORE_ENVIRONMENT=Development` einen lokalen Development-Auth-Handler -- Default-User: `DEV\\TrafagDeveloper` -- `DevelopmentUserIsAdmin=true`, damit lokal weiter programmiert werden kann -- produktiv darf die App nicht mit `Development` laufen - -IIS-/IT-Hinweise: - -1. Windows Authentication aktivieren -2. Anonymous Authentication deaktivieren -3. `ASPNETCORE_ENVIRONMENT` produktiv nicht auf `Development` setzen -4. AD-Gruppen fuer Benutzer und Admins anlegen oder bestehende Gruppen eintragen -5. `Security:AccessGroups` und `Security:AdminGroups` in produktiver Konfiguration korrekt setzen - -Aktueller IIS-Deployment-Nachtrag 2026-05-20: - -- Vollstaendige Detaildoku: `docs/DEPLOYMENT_IIS_HANDOFF_2026-05-19.md` -- Fuehrendes Projekt bleibt `TrafagSalesExporter`. -- Publish-Ausgabe heisst fuer IIS weiterhin `BiDashboard.dll`, ohne EXE/AppHost. -- Publish-Ziel: `\\trch-webapp-bidashboard.trafagch.local\BiDashboard$\` -- Browser-URL: `https://trch-webapp-bidashboard.trafagch.local/BiDashboard/` -- `diag.txt` unter `/BiDashboard/diag.txt` ist erreichbar und beweist, dass IIS auf den richtigen Publish-Ordner zeigt. -- Der verbleibende `500` entsteht beim ASP.NET-Core-Start oder im ASP.NET-Core-IIS-Modul. -- `web.config` steht aktuell auf `hostingModel="outofprocess"`, `stdoutLogEnabled="true"` und `ASPNETCORE_DETAILEDERRORS=true`. -- Wenn `logs` leer bleibt, muss der Serveradmin im Event Viewer pruefen: `IIS AspNetCore Module V2`, `.NET Runtime`, `Application Error`. -- Server muss kein Microsoft Excel installiert haben; XLSX wird ueber ClosedXML/OpenXML gelesen. - -Verifikation: - -```text -dotnet build .\TrafagSalesExporter.csproj --verbosity minimal -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal -``` - -Ergebnis: - -- Build erfolgreich -- Tests erfolgreich -- `48/48` Tests gruen -- Auth-Policy-Tests fuer AccessGroup, AdminGroup und Development-Admin vorhanden -- lokaler Development-Auth-Start geprueft: `http://localhost:55416` antwortet mit HTTP `200` -- bekannte MudBlazor-Analyzer-Warnungen zu `Dense` bleiben - -## Nachtrag 2026-04-29 Management-Cockpit-Auswertung - -Seit dem letzten dokumentierten Stand vom 2026-04-17 wurde das `Management Cockpit` weiter ausgebaut. Dieser Abschnitt rekonstruiert den aktuellen Stand aus dem Code, weil die Aenderungen nach einem PC-Absturz nicht direkt nachdokumentiert wurden. - -### Neue Auswertlogik - -Das Cockpit ist nicht mehr nur auf Umsatz als feste Kennzahl beschraenkt. - -Neu gibt es auswählbare Summenfelder: - -- `Sales Price/Value` -- `Quantity` -- `Standard cost` -- `Quantity * Standard cost` - -Diese Auswahl gilt fuer: - -- dateibasierte Analyse vorhandener Excel-Exporte -- zentrale Roh-Auswertung aus `CentralSalesRecords` - -### Anzeige-Waehrung und Wechselkurse - -Fuer betragliche Summenfelder kann jetzt eine Anzeige-Waehrung gewaehlt werden: - -- `EUR` -- `USD` -- `Original` - -Die Umrechnung nutzt `CurrencyExchangeRateService`. - -Wichtig: - -- nicht-betragliche Werte wie `Quantity` werden nicht umgerechnet -- bei `Original` bleiben Werte in der jeweiligen Quellwaehrung -- bei fehlendem Wechselkurs wird der betroffene Wert mit `0` in die Zielwaehrung eingerechnet -- fehlende Kurse werden als Anzahl `Nicht umgerechnet` bzw. in Hinweisen/Finding sichtbar gemacht -- Wechselkurse werden pro Quellwaehrung, Zielwaehrung und Datum gecacht, damit grosse Auswertungen nicht unnoetig oft die gleiche Rate aufloesen - -### Zusätzliche Summenfelder in der zentralen Sicht - -Die zentrale Roh-Auswertung kann neben dem Haupt-Summenfeld weitere Summenfelder anzeigen. - -Diese Zusatzwerte werden aktuell in den Zeitreihen ausgegeben: - -- Jahreswerte -- Monatswerte -- Tageswerte im gewaehlten Monat - -Beispiel: - -- Hauptwert: `Sales Price/Value` -- Zusatzwerte: `Quantity`, `Quantity * Standard cost` - -Damit kann die zentrale Sicht Umsatz, Mengen und Kostennaeherung nebeneinander darstellen. - -### UI-Stand - -`Components/Pages/ManagementCockpit.razor` hat neue Controls: - -- Summenfeld fuer Excel-Dateianalyse -- Anzeige-Waehrung fuer Excel-Dateianalyse -- Summenfeld fuer zentrale Roh-Auswertung -- weitere Summenfelder fuer zentrale Roh-Auswertung per Mehrfachauswahl -- Anzeige-Waehrung fuer zentrale Roh-Auswertung - -Die Tabellen wurden von festem Text `Umsatz` auf generische `Werte` / `Jahreswerte` / `Monatswerte` umgestellt. - -Die vorher dokumentierte Manometer-/Gauge-Sicht ist im aktuellen Arbeitsstand nicht mehr aktiv sichtbar. Stattdessen liegt der Fokus wieder auf Kennzahlen, Hinweisen und tabellarischen Auswertungen. - -### Technische Umsetzung - -Betroffene Dateien: - -- `Components/Pages/ManagementCockpit.razor` -- `Models/ManagementCockpitModels.cs` -- `Services/IManagementCockpitService.cs` -- `Services/ManagementCockpitPageService.cs` -- `Services/ManagementCockpitService.cs` -- `TrafagSalesExporter.Tests/ManagementCockpitServiceTests.cs` - -Neue bzw. erweiterte Modelle: - -- `ManagementCockpitValueFieldKeys` -- `ManagementCockpitCurrencyOptions` -- `ManagementCockpitValueFieldOption` -- `ManagementCockpitAnalysisOptions` -- `ManagementCockpitAggregatedFieldValue` - -Neue Felder in Ergebnissen: - -- gewaehltes Summenfeld -- Anzeige-Waehrung -- Anzahl fehlender Wechselkurse -- Zusatzwerte pro Zeitreihe - -### Testabdeckung - -Die `ManagementCockpitServiceTests` wurden erweitert um Tests fuer: - -- Umrechnung zentraler Werte in EUR -- Caching von Wechselkursauflösungen -- Mengen-Summe ohne Waehrungsumrechnung -- Zusatz-Summenfelder in Jahres- und Monatswerten - -Noch offen: - -- UI manuell pruefen -- genaue fachliche Zielwaehrung fuer Standardberichte bestaetigen -- entscheiden, ob `CHF` ebenfalls als direkte Anzeige-Waehrung angeboten werden soll -- klaeren, ob fehlende Wechselkurse langfristig mit `0`, Originalwert oder separater Fehlergruppe dargestellt werden sollen - -## Nachtrag 2026-04-17 Refactoring- und HANA-Stand - -Der Stand aus den frueheren Nachtraegen ist fuer Architektur und HANA-Zugriff nicht mehr vollstaendig. - -Inzwischen gilt zusaetzlich: - -### 1. DataSourceAdapter-Pattern ist eingefuehrt - -Die Quellsysteme `HANA`, `SAP_GATEWAY` und `MANUAL_EXCEL` laufen nicht mehr ueber einen grossen `if/else`-Block im `SiteExportService`. - -Neu: - -- `Services/DataSources/IDataSourceAdapter.cs` -- `Services/DataSources/IDataSourceAdapterResolver.cs` -- `Services/DataSources/DataSourceAdapterResolver.cs` -- `Services/DataSources/DataSourceFetchContext.cs` -- `Services/DataSources/DataSourceFetchResult.cs` -- `Services/DataSources/DataSourceCredentials.cs` -- `Services/DataSources/HanaDataSourceAdapter.cs` -- `Services/DataSources/SapGatewayDataSourceAdapter.cs` -- `Services/DataSources/ManualExcelDataSourceAdapter.cs` - -Neuer Zuschnitt: - -- `SiteExportService` ist jetzt deutlich schlanker und nur noch Export-Pipeline -- Adapter loesen Quellsystem-spezifisches Laden auf -- fuer ein weiteres Quellsystem ist kein Umbau im `SiteExportService` mehr noetig - -### 2. Page-Services sind nicht mehr Singleton - -UI-nahe Services laufen jetzt pro Blazor-Circuit als `Scoped`. - -Betroffen: - -- `ISettingsPageService` -- `IStandortePageService` -- `IStandorteSapEditorService` -- `IManagementCockpitPageService` -- `IDashboardPageService` -- `ILogsPageService` -- `ITransformationsPageService` - -Wichtig: - -- `ExportOrchestrationService` bleibt bewusst `Singleton`, weil Exportstatus ueber Circuits geteilt werden muss -- stateless Infrastruktur-Services bleiben weiter `Singleton` - -### 3. Datenbank-Initialisierung ist aufgeteilt - -Der fruehere monolithische `DatabaseInitializationService` ist inzwischen in grobe Verantwortungsbloecke getrennt: - -- `DatabaseInitializationService` als Orchestrator -- `DatabaseSchemaMaintenanceService` fuer Schema-/Repair-Logik -- `DatabaseSeedService` fuer Defaultdaten und Stammdaten-Seeding -- `DatabaseInitializationService.SchemaSql.cs` als SQL-Definitionsblock - -Das reduziert das groesste Architektur-Risiko deutlich, auch wenn die Startmigrationen weiterhin ein sensibler Teil des Systems bleiben. - -### 4. Weitere Razor-Seiten sind entlastet - -Neben den frueher bereits entlasteten Seiten laufen jetzt auch diese Seiten ueber Page-Services statt direkten `DbContext`-Zugriffen: - -- `Dashboard.razor` ueber `DashboardPageService` -- `Logs.razor` ueber `LogsPageService` -- `Transformations.razor` ueber `TransformationsPageService` - -Der Rest an direkter Persistenzlogik in Razor ist damit deutlich kleiner geworden. - -### 5. Kritische HANA-Risiken wurden entschärft - -#### SQL-Injection-Schutz - -Im `HanaQueryService` wurden die kritischen interpolierten SQL-Stellen bereinigt: - -- `tsc` und `dateFilter` laufen jetzt parametriert in `HanaCommand` -- `schema` wird als Identifier streng validiert und gequotet - -Damit ist der akute Injection-Pfad in den HANA-Verkaufsabfragen geschlossen. - -#### Async statt `.GetAwaiter().GetResult()` - -Die blockierenden HANA-Aufrufe wurden auf echte Async-Methoden umgestellt: - -- `IHanaQueryService` ist jetzt async-basiert -- `HanaQueryService` nutzt `OpenAsync`, `ExecuteReaderAsync`, `ReadAsync`, `ExecuteScalarAsync` -- Aufrufer wie `HanaDataSourceAdapter`, `StandortePageService` und `SettingsPageService` verwenden keine `Task.Run`-Workarounds mehr fuer HANA - -Damit ist das fruehere Deadlock-/Blocking-Risiko in diesem Pfad deutlich reduziert. - -### 6. Test- und Build-Stand - -Verifiziert wurde zuletzt mit: - -```text -dotnet build .\TrafagSalesExporter.csproj --verbosity minimal -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal -``` - -Ergebnis: - -- Projekt-Build erfolgreich -- `36/36` Tests gruen - -Bekannt: - -- `dotnet build .\TrafagSalesExporter.sln` endet in dieser Umgebung weiterhin mit Exitcode `1` ohne konkrete Compilerfehler -- das Hauptprojekt und das Testprojekt bauen aber erfolgreich -- bekannte Warnungen bleiben: - - `MSB3270` wegen HANA-Assembly-Architektur - - MudBlazor-Analyzer zu `Dense` - -### 7. Aktuelles Architektururteil - -Der Zustand ist jetzt deutlich professioneller als zu Beginn des Refactorings: - -- Datenquellen sauberer getrennt -- UI konsistenter ueber Page-Services geschnitten -- groesster Start-/Schema-Block zerlegt -- HANA-Pfad sicherer und sauberer asynchron - -Aber noch nicht vollendet: - -- keine gezielten Adapter-/Resolver-Unit-Tests -- keine Retry-Strategie fuer SharePoint / SAP / HANA-Netzpfade -- kein Secret-Store -- `DatabaseInitializationService` bleibt trotz Zerlegung ein sensibler produktiver Migrationspfad - -## Nachtrag 2026-04-17 - -Der dokumentierte Stand in diesem Handoff war bei der Waehrungslogik nicht mehr aktuell. - -Inzwischen gilt: - -- Kurstabellen fuer `CurrencyExchangeRates` sind im System vorhanden -- `Settings` enthaelt bereits eine Pflegeoberflaeche fuer Wechselkurse -- `ExchangeRateImportService` importiert ECB-Tageskurse nach `CurrencyExchangeRates` -- `NormalizeCurrencyCode` ist als Value-Transformation vorhanden -- `ConvertCurrency` ist als Record-Transformation vorhanden -- `Program.cs` registriert beide Strategien sowie `CurrencyExchangeRateService` und `ExchangeRateImportService` - -Wichtig: - -- die Roh-Auswertung im `Management Cockpit` rechnet Stand heute weiterhin bewusst **nicht** in CHF um -- dort bleibt der Umsatz weiterhin in `Sales Currency` -- die Waehrungsumrechnung ist aktuell Teil des allgemeinen Transformations-/Mapping-Systems, nicht der Cockpit-Rohsicht - -Zusatzlich wurden am 2026-04-17 fehlende Unit-Tests fuer die Waehrungslogik nachgezogen: - -- `CurrencyExchangeRateServiceTests` -- `ExchangeRateImportServiceTests` -- Erweiterungen in - - `TransformationStrategiesTests` - - `RecordTransformationServiceTests` - - `TransformationCatalogTests` - -Aktueller Teststatus nach diesem Nachtrag: - -```text -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal -``` - -Ergebnis: - -- erfolgreich -- `31/31` Tests gruen -- bekannte Warnung bleibt: - - SAP HANA Architekturwarnung `MSB3270` - -## Architekturpruefung 2026-04-17 - -Es wurde eine erneute Gesamtpruefung der Architektur gemacht, ausdruecklich ohne neue Implementierung. - -### Gesamturteil - -Die Grundrichtung ist weiterhin sinnvoll: - -- klare Trennung der Quellsysteme `SAP`, `BI1`, `SAGE`, `MANUAL_EXCEL` -- zentrales fachliches Zielschema ueber `SalesRecord` -- zentrale technische Ablage ueber `CentralSalesRecords` -- separater Orchestrator fuer Standort- und Konsolidierungsexport -- Transformationssystem als eigener Layer - -Aber: - -- die Architektur ist **noch nicht stabil genug**, um sie als "fertig sauber" zu betrachten -- die groessten Risiken liegen aktuell nicht in SAP oder Waehrungen, sondern in - - Start-/Schema-Initialisierung - - Config-Import - - Verteilung von Logik zwischen Razor-Seiten und Services - -### Wichtigste Architektur-Risiken - -#### 1. Start-/Schema-Initialisierung ist fragil - -`DatabaseInitializationService` mischt derzeit: - -- `EnsureCreated` -- manuelle `ALTER TABLE`-Pflege -- FK-Reparaturlogik -- Seeding -- empfohlenes Regel-Seeding - -Das ist funktional hilfreich, aber architektonisch gefaehrlich, weil: - -- die App-Initialisierung dadurch viel implizite Datenmigration enthaelt -- Verhalten schwer vorhersehbar wird -- Fehler im Migrationspfad sofort produktive Daten treffen - -Wichtiger konkreter Befund aus der Pruefung: - -- beim Kopieren von `Sites_old` nach `Sites` ist die Spaltenreihenfolge im SQL inkonsistent -- dadurch koennen Werte wie `ManualImportFilePath`, `SapServiceUrl`, `SapEntitySet` verschoben gespeichert werden -- das ist eine reale Datenkorruptionsgefahr und kein reines Architekturthema - -### 2. Config-Import ist destruktiv und nicht atomar - -`ConfigTransferService.ImportJsonAsync` loescht aktuell zuerst grosse Teile der Konfiguration und Daten: - -- Sites -- HanaServers -- Transformation Rules -- SAP-Konfiguration -- Wechselkurse -- sogar `CentralSalesRecords` - -und baut danach mit mehreren `SaveChangesAsync()`-Zwischenschritten neu auf. - -Risiko: - -- wenn der Import in der Mitte scheitert, bleibt das System teilweise geloescht zurueck -- `CentralSalesRecords` gehoeren fachlich ohnehin nicht sauber in einen normalen Config-Import - -### 3. Zu viel Fach- und Persistenzlogik in Razor-Seiten - -`Settings.razor` und `Standorte.razor` machen aktuell sehr viel direkt: - -- `DbContext` oeffnen -- Daten laden und speichern -- Konfigurationsimport/-export anstossen -- SAP-Refresh -- Upload-Handling -- Teile der Validierung / Persistenzlogik - -Das funktioniert momentan, fuehrt aber langfristig zu: - -- schwer testbarer UI-Logik -- verstreuten Regeln -- hoeherem Seiteneffekt-Risiko bei Erweiterungen - -### 4. Vertrag zwischen Orchestrator und konsolidiertem Export ist unscharf - -`ExportOrchestrationService` sammelt bei `ExportAllAsync` bereits `consolidatedRecords`, uebergibt sie weiter, aber `ConsolidatedExportService` ignoriert diesen Parameter und liest erneut aus `CentralSalesRecords`. - -Das zeigt ein offenes Architekturthema: - -- Soll die zentrale Datei aus dem Live-Exportlauf gebaut werden? -- oder immer nur aus dem persistenten Read Model `CentralSalesRecords`? - -Aktuell ist beides halb vorhanden. - -### 5. Reporting-/Cockpit-Logik ist noch nicht voll verallgemeinert - -Bei der Pruefung wurde gesehen: - -- `ManagementCockpitService` enthaelt noch hartcodierte Jahreslogik fuer `2025` und `2026` -- die Rohsicht bleibt bewusst ohne CHF-Umrechnung - -Das ist fuer den aktuellen Stand akzeptabel, zeigt aber: - -- Reporting ist noch kein voll abstrahierter fachlicher Layer - -## Empfohlenes Sollbild - -Die naechste Architektur-Stufe sollte in diese Richtung gehen: - -### 1. Klare Schichten - -- UI: - - Razor nur fuer Interaktion, Anzeige, Formularzustand -- Application: - - Use Cases / Commands / Queries fuer Export, Config, SAP-Refresh, Wechselkurse, Standortpflege -- Domain / Fachlogik: - - Transformationen, Mappingregeln, Waehrungsumrechnung, Cockpit-Berechnungen -- Infrastructure: - - HANA, SAP Gateway, SQLite, SharePoint, Dateisystem - -### 2. Versionierte Migrationen statt manueller Start-Reparaturen - -Statt immer mehr Reparaturlogik beim App-Start: - -- Schema-Aenderungen versionieren -- Migrationspfade testbar machen -- Startlogik nur noch fuer minimale Bootstrap-Aufgaben behalten - -### 3. Config-Import als atomarer Vorgang - -Ziel: - -- alles in einer Transaktion oder bewusst in klar getrennten Phasen -- kein halb geloeschter Zustand bei Fehlern -- `CentralSalesRecords` aus normalem Config-Import eher herausnehmen - -### 4. Zentrale Export-Semantik entscheiden - -Explizit festlegen: - -- zentrale Datei immer aus `CentralSalesRecords` - oder -- zentrale Datei aus dem aktuellen Export-Snapshot - -Danach die doppelte Semantik entfernen. - -## Priorisierung aus Architektursicht - -Wenn nach Stabilitaet priorisiert wird, dann in dieser Reihenfolge: - -1. `DatabaseInitializationService` / Migrationspfad absichern -2. `ConfigTransferService.ImportJsonAsync` atomar und weniger destruktiv machen -3. Logik aus `Settings.razor` und `Standorte.razor` in Anwendungsservices verschieben -4. Export-Semantik fuer Konsolidierung vereinheitlichen -5. erst danach weitere Fachfeatures wie Cockpit-CHF, Budget, Gruppenlogik - -## Kurzfazit - -Die Architektur ist nicht schlecht. Das Grundmodell traegt. - -Aber: - -- sie ist noch nicht robust genug fuer ruhigen weiteren Ausbau ohne technische Konsolidierung -- die aktuelle Hauptgefahr liegt in Infrastruktur- und Persistenzlogik, nicht in den Fachfeatures - -Fuer den naechsten Einstieg nach Absturz gilt daher: - -1. zuerst diesen Architektur-Nachtrag lesen -2. dann `DatabaseInitializationService` und `ConfigTransferService` als Risikobloecke ansehen -3. neue Fachfeatures erst nach dieser technischen Konsolidierung beginnen - -## Nachtrag HANA-/Standort-Workflow 2026-04-17 - -Nach der Architekturpruefung wurde der doppelte HANA-Workflow bereinigt. - -### Altes Problem - -Vorher gab es zwei konkurrierende Stellen fuer HANA-Konfiguration: - -- oben eine eigene `HANA Server`-Verwaltung -- unten im Standortdialog noch einmal eine fast vollstaendige HANA-Verbindung - -Dadurch war unklar: - -- was die zentrale Wahrheit ist -- wann ein zentraler Server geaendert wird -- wann still ein separater Server pro Standort entsteht - -### Neue Logik - -Oben gilt jetzt: - -- `HANA Server` ist zentrale HANA-Konfiguration pro Quellsystem -- aktuell relevant fuer: - - `BI1` - - `SAGE` - -Unten im Standort gilt jetzt: - -- Standort pflegt nur noch standortspezifische Daten - - `Schema` - - `TSC` - - `Land` - - `SourceSystem` - - optionale Username-/Password-Overrides -- die technische HANA-Verbindung kommt aus der zentralen Konfiguration des Quellsystems - -### Technische Umsetzung - -- `HanaServer` hat jetzt zusaetzlich `SourceSystem` -- `DatabaseInitializationService` stellt zentrale Eintraege fuer `BI1` und `SAGE` sicher -- bestehende verknuepfte HANA-Server werden dabei moeglichst auf `BI1` / `SAGE` gemappt -- `SiteExportService` baut HANA-Verbindungen jetzt aus der zentralen HANA-Konfiguration des Quellsystems -- `Settings.razor` testet BI1/SAGE nicht mehr ueber einen Beispiel-Standort, sondern ueber die zentrale HANA-Konfiguration -- `Standorte.razor` speichert im Standort fuer HANA-basierte Systeme keine eigene Vollverbindung mehr - -### Wichtige Konsequenz - -Fachlich gilt jetzt: - -- oben = Standardkonfiguration pro Quellsystem -- unten = Standort + optionale Credential-Overrides - -Das entspricht der gewuenschten Logik: - -- gleiche BI1-/SAGE-Standorte koennen zentrale Verbindungswerte teilen -- Ausnahmen koennen weiter ueber Username-/Password-Overrides reagieren - -### UI-Nachtrag - -Die frueher doppelte und dadurch verwirrende UI wurde danach auch sichtbar bereinigt. - -Aktueller UI-Stand: - -- oben heisst der Bereich jetzt klar `Zentrale HANA-Konfiguration` -- im Standortdialog gibt es fuer HANA keine zweite technische Eingabestrecke mehr -- dort wird nur noch die aktive Zentralverbindung angezeigt -- Host, Port, SSL und technische Parameter werden explizit nach oben verwiesen -- der zentrale Verbindungstest in `Settings.razor` meldet jetzt sauber die zentrale HANA-Verbindung - -## Nachtrag Quellsystem-Verwaltung 2026-04-17 - -Die bisher noch hart codierten Quellsystem-Listen wurden entfernt und durch echte Stammdaten ersetzt. - -### Neuer Stand - -- neues Modell `SourceSystemDefinition` -- Quellsysteme werden jetzt zentral in der DB gehalten statt in Razor-Arrays -- pro Quellsystem werden gepflegt: - - `Code` - - `DisplayName` - - `ConnectionKind` - - `IsActive` - - `CentralUsername` - - `CentralPassword` - -### Neue GUI-Logik - -- `Settings.razor` enthaelt jetzt eine pflegbare Quellsystem-Tabelle -- dort koennen Quellsysteme per GUI angelegt, bearbeitet und gespeichert werden -- Anschlussart ist nicht mehr implizit im Code, sondern pro Quellsystem konfigurierbar -- zentrale Zugangsdaten haengen jetzt am Quellsystem selbst - -### Anschlussarten - -Aktuell technisch vorgesehen: - -- `HANA` -- `SAP_GATEWAY` -- `MANUAL_EXCEL` - -Damit gilt: - -- HANA-Konfiguration oben in `Standorte.razor` nur noch fuer Quellsysteme mit Anschlussart `HANA` -- Standort-Dropdown zieht seine Quellsysteme jetzt aus `SourceSystemDefinitions` -- Transformationsregeln ziehen ihre Quellsystem-Auswahl ebenfalls aus `SourceSystemDefinitions` - -### Technische Umsetzung - -- `AppDbContext` hat jetzt `DbSet` -- `DatabaseInitializationService` erzeugt und seedet `SourceSystemDefinitions` -- `SiteExportService` loest zentrale Credentials jetzt ueber `SourceSystemDefinition` -- `ConfigTransferService` exportiert/importiert jetzt auch `SourceSystemDefinitions` - -### Verifikation - -Nach dieser Umstellung geprueft: - -```text -dotnet build .\TrafagSalesExporter.csproj -v minimal -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal -``` - -Ergebnis: - -- Build erfolgreich -- Tests erfolgreich -- `31/31` Tests gruen - -### Bereinigung der Legacy-Credentials - -Danach wurden auch die alten zentralen Credential-Felder technisch bereinigt. - -Aktueller Stand: - -- `ExportSettings` enthaelt keine alten Felder mehr fuer `SapUsername`, `Bi1Username`, `SageUsername` usw. -- der Config-Export schreibt zentrale Zugangsdaten nur noch ueber `SourceSystemDefinitions` -- `ConfigTransferService` hat keinen aktiven Legacy-Credential-Pfad mehr -- die fruehere Temp-Datei `standorte_numbered.tmp` wurde entfernt - -Wichtig: - -- bestehende DB-Spalten koennen physisch noch vorhanden sein, sind aber kein aktiver Codepfad mehr -- fuehrende Wahrheit fuer zentrale Zugangsdaten ist jetzt ausschliesslich `SourceSystemDefinition` - -### Schema-Bereinigung - -Danach wurde auch die SQLite-Schemabereinigung nachgezogen. - -Aktueller Stand: - -- `DatabaseInitializationService` erkennt alte Credential-Spalten in `ExportSettings` -- wenn diese Legacy-Spalten noch existieren, wird `ExportSettings` beim Start auf das neue Schema rekonstruiert -- erhalten bleiben nur die noch gueltigen Felder: - - `DateFilter` - - `TimerHour` - - `TimerMinute` - - `TimerEnabled` - - `DebugLoggingEnabled` - - `LocalSiteExportFolder` - - `LocalConsolidatedExportFolder` - -Damit gilt jetzt: - -- alte zentrale SAP/BI1/SAGE-Credentials sind nicht nur logisch entfernt -- sie werden bei bestehender DB auch aktiv aus dem `ExportSettings`-Schema entfernt - -### Letzte Bereinigung HANA-Credentials - -Danach wurde auch die letzte doppelte Credential-Stelle in der HANA-Verwaltung entfernt. - -Aktueller Stand: - -- zentrale HANA-Konfiguration speichert nur noch technische Verbindungsdaten - - `Host` - - `Port` - - `DatabaseName` - - `UseSsl` - - `ValidateCertificate` - - `AdditionalParams` -- Username/Password werden nicht mehr in der zentralen HANA-UI gepflegt -- HANA-Verbindungstests in `Standorte.razor` verwenden jetzt die zentralen Credentials aus `SourceSystemDefinition` -- `SiteExportService` faellt bei HANA nicht mehr auf in `HanaServer` gespeicherte Credentials zurueck -- `ConfigTransferService` exportiert/importiert fuer `HanaServer` keine Username-/Password-Werte mehr -- `DatabaseInitializationService` bereinigt bei bestehender DB auch das `HanaServers`-Schema und entfernt die Altspalten `Username` / `Password` - -Die fachliche Reihenfolge ist jetzt eindeutig: - -1. zentrale Credentials aus `SourceSystemDefinition` -2. optionale Override-Credentials am `Site` -3. technische HANA-Verbindung aus der zentralen HANA-Konfiguration - -### EF-/SQLite-Fix - -Beim ersten Lauf nach der Schema-Bereinigung trat noch ein Mapping-Fehler auf: - -- `SQLite Error 1: 'no such column: h.Password'` - -Ursache: - -- `HanaServers`-Schema war bereits ohne `Username` / `Password` -- das EF-Modell `HanaServer` hat diese Properties aber noch als normale Spalten behandelt - -Fix: - -- `HanaServer.Username` und `HanaServer.Password` sind jetzt `[NotMapped]` -- damit bleiben sie fuer Laufzeit-Verbindungsaufbau und Tests nutzbar -- EF erwartet sie aber nicht mehr als Datenbankspalten - -## Nachtrag Zentrale SAP-Steuerung 2026-04-17 - -Der verbleibende Architekturbruch bei SAP wurde ebenfalls bereinigt. - -### Neuer Stand - -- `SourceSystemDefinition` enthaelt jetzt auch `CentralServiceUrl` -- zentrale SAP-Service-URL wird damit am Quellsystem gepflegt, nicht mehr primaer am Standort -- `Standorte.razor` behandelt `SapServiceUrl` jetzt als Override -- wenn kein Override gesetzt ist, zieht SAP die URL zentral aus dem Quellsystem - -### UI - -- `Settings.razor` hat fuer Quellsysteme jetzt eine Dialogbearbeitung statt nur Inline-Tabellenfelder -- dadurch ist das Quellsystem sauber editierbar -- fuer `SAP_GATEWAY` wird dort die zentrale SAP-Service-URL gepflegt -- `Standorte.razor` zeigt bei SAP jetzt: - - zentrale SAP Service URL - - optionales `SAP Service URL Override` - -### Laufzeitlogik - -- `SiteExportService` verwendet bei SAP die effektive URL aus - - Standort-Override - - sonst `SourceSystemDefinition.CentralServiceUrl` -- SAP-Verbindungstest in `Settings.razor` testet die zentrale URL direkt aus dem Quellsystem -- Dashboard zeigt fuer SAP jetzt ebenfalls die effektive zentrale bzw. ueberschriebene URL - -### Verifikation - -Nach der Umstellung geprueft: - -```text -dotnet build .\TrafagSalesExporter.csproj -v minimal -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal -``` - -Ergebnis: - -- Build erfolgreich -- Tests erfolgreich -- `31/31` Tests gruen - -## Nachtrag 2026-04-16 - -Seit dem letzten Handoff wurden weitere Funktionen umgesetzt, die unten im alten Stand noch nicht voll enthalten sind. - -## Zielbild - -Die App wurde von einem reinen BI1/HANA-Exporter zu einer kombinierten Plattform erweitert: - -- `BI1` und `SAGE` bleiben auf direktem HANA-Zugriff -- `SAP` laeuft separat ueber SAP Gateway / OData -- SAP-Quellen koennen gelesen, gejoint und auf das zentrale `SalesRecord`-Schema gemappt werden -- Standort-Exporte werden lokal als Excel geschrieben -- zusaetzlich werden Datensaetze in eine zentrale SQLite-Tabelle geschrieben -- ein konsolidierter Export liest aus dieser zentralen Tabelle - -## Wichtigste umgesetzte Funktionen - -### 1. Zentrale Credentials pro Quellsystem - -Es gibt zentrale Zugangsdaten in `ExportSettings` fuer: - -- `SAP` -- `BI1` -- `SAGE` - -Zusaetzlich gibt es pro Standort optionale Overrides: - -- `UsernameOverride` -- `PasswordOverride` - -Aufloesungsreihenfolge: - -1. Standort-Override -2. zentrale Credentials des Quellsystems -3. bei HANA zusaetzlich Fallback auf alten `HanaServer.Username/Password` - -### 2. SAP von BI1/HANA getrennt - -`SAP` nutzt nicht mehr den HANA-Pfad, sondern eine eigene Gateway/OData-Strecke. - -Pro SAP-Standort gibt es: - -- `SapServiceUrl` -- `SapEntitySet` -- `SapEntitySetsCache` -- `SapEntitySetsRefreshedAtUtc` - -Refresh der SAP-Quellen erfolgt nur auf Knopfdruck. - -Beispiel Service URL: - -```text -http://travt762.sap.trafag.com:8000/sap/opu/odata/sap/ZPOWERBI_EINKAUF_SRV/ -``` - -Wichtig: - -- Service URL immer nur bis zum Service -- Entity Set separat auswaehlen - -### 3. SAP-Quellen, Joins und Feldmappings - -Fuer SAP gibt es mehrere neue Modelle: - -- `SapSourceDefinition` -- `SapJoinDefinition` -- `SapFieldMapping` - -Unterstuetzt wird: - -- mehrere SAP-Quellen pro Standort -- Alias pro Quelle -- Primaerquelle -- Join-Definitionen -- Mapping von `Alias.Feldname` auf zentrales Schema - -UI-Erweiterungen: - -- `Quellen refreshen` -- `Felder aus Quellen laden` -- Join-Key-Auswahl aus Metadaten -- `Auto-Match` fuer gleiche Feldnamen zwischen Primaerquelle und anderen Quellen - -### 4. Zentrale Datenspeicherung - -Neue Tabelle: - -- `CentralSalesRecords` - -Verwendung: - -- pro Standort werden alte zentrale Saetze dieses Standorts ersetzt -- konsolidierte Excel liest aus `CentralSalesRecords` - -Wichtig: - -- zentrale Excel wird nicht appendet -- sie wird aus dem aktuellen Zustand der zentralen Tabelle neu erstellt - -### 5. Exportpfade - -Neue Konfigurationsmoeglichkeiten: - -Zentral in `Settings`: - -- `LocalSiteExportFolder` -- `LocalConsolidatedExportFolder` - -Pro Standort: - -- `LocalExportFolderOverride` - -Fallback wenn leer: - -```text -./output -``` - -relativ zum App-Verzeichnis. - -### 6. SharePoint - -SharePoint-Upload ist optional. - -Wenn keine vollstaendige SharePoint-Konfiguration vorhanden ist: - -- Excel wird trotzdem lokal erzeugt -- kein Upload nach SharePoint - -Benoetigte SharePoint-Werte: - -- `Tenant ID` -- `Client ID` -- `Client Secret` - -Das sind Entra App Registration Werte, nicht normale Benutzer-Credentials. - -### 7. Config Import/Export - -Es gibt JSON-Import/Export der Konfiguration mit Checkbox: - -- mit Secrets -- ohne Secrets - -Enthalten sind u. a.: - -- SharePoint Config -- ExportSettings -- HanaServers -- Sites -- Transformation Rules -- SAP-Quellen -- SAP-Joins -- SAP-Mappings - -### 8. Logging und Live-Status - -Neue technische Logs ueber `AppEventLogs`. - -Sichtbar: - -- auf `/logs` -- im Dashboard als `Live-Status` - -Geloggt werden u. a.: - -- HANA-Query Start -- SAP Refresh -- SAP Reads -- Transformationen -- Excel-Erstellung -- zentrale Tabellenspeicherung -- Export erfolgreich / fehlgeschlagen - -### 9. Excel oeffnen - -Im Dashboard gibt es neben `Export` den Button: - -- `Excel oeffnen` - -Dieser nutzt `ExportLogs.FilePath`. - -Voraussetzungen: - -- letzter Export erfolgreich -- `FilePath` gespeichert -- Datei existiert lokal - -### 10. Management Cockpit - -Es gibt einen neuen Menuepunkt: - -- `Management Cockpit` - -Funktion: - -- Auswahl vorhandener Excel-Dateien -- Analyse einer exportierten Standort-Datei -- Kennzahlen fuer Geschaeftsinhaber / Management - -Aktuell enthalten: - -- Umsatz -- geschaetzte Kosten -- geschaetzte Marge -- Rechnungsanzahl -- Kundenanzahl -- Top Kunden -- Top Produktgruppen -- Top Sales Owner -- Datenqualitaetshinweise -- automatische Management-Aussagen - -### 11. Manueller Excel-Import pro Standort - -Es gibt jetzt einen vierten `SourceSystem`-Typ: - -- `MANUAL_EXCEL` - -Gedanke: - -- Standort ohne Netz-/Systemanbindung liefert nur Excel -- Datei wird im Standort hochgeladen -- Export liest diese Datei statt SAP/HANA -- Daten werden in `CentralSalesRecords` fuer diesen Standort ersetzt -- der zentrale Export liest weiter nur aus `CentralSalesRecords` - -Neue Site-Felder: - -- `ManualImportFilePath` -- `ManualImportLastUploadedAtUtc` - -Wichtig: - -- das ist kein Excel-zu-Excel-Merge -- die App importiert ins zentrale Schema und erzeugt danach die zentrale Datei neu - -### 12. Dashboard erweitert - -Im Dashboard gibt es jetzt zusaetzlich: - -- separaten Bereich `Zentrale Datei` -- `Excel oeffnen` fuer die neueste zentrale Datei `Sales_All_*.xlsx` -- Button `Alle exportieren` -- Button `Zentrale Datei neu erzeugen` - -Bedeutung: - -- `Alle exportieren` liest alle Quellen neu und erzeugt danach die zentrale Datei -- `Zentrale Datei neu erzeugen` schreibt nur aus `CentralSalesRecords` eine neue zentrale Excel - -### 13. Management Cockpit Roh-Auswertung aus Zentraldaten - -Zusaetzlich zur dateibasierten Cockpit-Analyse gibt es jetzt eine Roh-Auswertung direkt aus `CentralSalesRecords`. - -Aktuell umgesetzt: - -- Auswahl Jahr -- optional Auswahl Monat -- Jahresumsatz -- Monatsumsatz -- Tagesumsatz im gewaehlten Monat -- Umsatz nach Quelle -- Umsatz nach Land -- Periodenabdeckung / Zeilen / Rechnungen / Standorte / Laender / Waehrungen - -Bewusst noch nicht enthalten: - -- kein Intercompany-Filter -- keine CHF-Umrechnung -- kein Budgetvergleich -- keine Spartenlogik -- keine Gruppenlogik -- keine Margenlogik - -### 14. Transformationssystem erweitert - -Das Transformationssystem kann jetzt zwei Ebenen: - -- `Value` fuer einfache feldweise Regeln aus der GUI -- `Record` fuer komplexere C#-Strategien per Strategy Pattern - -Umgesetzt: - -- neues Feld `RuleScope` auf `FieldTransformationRule` -- dynamischer Strategiekatalog -- GUI liest verfuegbare Typen aus dem Katalog -- erste `Record`-Strategie: `FirstNonEmpty` - -Beispiel: - -- `TargetField = CustomerName` -- `TransformationType = FirstNonEmpty` -- `Argument = CustomerName|SupplierName|Name` - -### 15. Schema-Lookup fuer HANA-Standorte - -Im Standortdialog fuer HANA-basierte Standorte gibt es jetzt: - -- Button `Schemas laden` -- Lookup mit gueltigen Schemas aus HANA - -Die Liste wird nicht blind aus allen Schemas gelesen, sondern auf typische B1-Schemas eingeschraenkt, in denen z. B. Tabellen wie - -- `OINV` -- `INV1` -- `ORIN` -- `RIN1` -- `OCRD` -- `OITM` - -vorhanden sind. - -Wichtig: - -- manuelle Eingabe bleibt moeglich -- fuer `BI1` und `SAGE` werden beim Lookup die effektiven Credentials inkl. zentraler Zugangsdaten / Overrides verwendet -- das reduziert Fehler wie `invalid schema name` - -### 16. Testabdeckung ausgebaut - -Es gibt jetzt ein separates Testprojekt: - -- `TrafagSalesExporter.Tests` - -Automatisiert getestet werden aktuell: - -- Transformationsstrategien -- `RecordTransformationService` -- `TransformationCatalog` -- `ManualExcelImportService` -- `ManagementCockpitService` -- `ConfigTransferService` - -Wichtiger bereits gefundener Bug: - -- deutsches Dezimalformat wie `1,50` wurde im manuellen Excel-Import falsch interpretiert -- Parsing wurde korrigiert - -## Wichtige Dateien - -### Modelle - -- `Models/Site.cs` -- `Models/ExportSettings.cs` -- `Models/ExportLog.cs` -- `Models/CentralSalesRecord.cs` -- `Models/SapSourceDefinition.cs` -- `Models/SapJoinDefinition.cs` -- `Models/SapFieldMapping.cs` -- `Models/ManagementCockpitModels.cs` -- `Models/ConfigTransferPackage.cs` -- `Models/FieldTransformationRule.cs` - -### Services - -- `Services/SiteExportService.cs` -- `Services/ConsolidatedExportService.cs` -- `Services/CentralSalesRecordService.cs` -- `Services/SapGatewayService.cs` -- `Services/SapCompositionService.cs` -- `Services/ConfigTransferService.cs` -- `Services/AppEventLogService.cs` -- `Services/ManagementCockpitService.cs` -- `Services/DatabaseInitializationService.cs` -- `Services/ExportOrchestrationService.cs` -- `Services/ManualExcelImportService.cs` -- `Services/TransformationCatalog.cs` -- `Services/RecordTransformationService.cs` -- `Services/TransformationStrategies.cs` - -### UI - -- `Components/Pages/Standorte.razor` -- `Components/Pages/Settings.razor` -- `Components/Pages/Dashboard.razor` -- `Components/Pages/Logs.razor` -- `Components/Pages/ManagementCockpit.razor` -- `Components/Pages/Transformations.razor` -- `Components/Layout/NavMenu.razor` - -### Tests - -- `TrafagSalesExporter.Tests/TransformationStrategiesTests.cs` -- `TrafagSalesExporter.Tests/RecordTransformationServiceTests.cs` -- `TrafagSalesExporter.Tests/TransformationCatalogTests.cs` -- `TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs` -- `TrafagSalesExporter.Tests/ManagementCockpitServiceTests.cs` -- `TrafagSalesExporter.Tests/ConfigTransferServiceTests.cs` - -## Datenbank / Migrationen - -Viele Aenderungen laufen ueber `DatabaseInitializationService`. - -Wichtige neue oder erweiterte Tabellen/Felder: - -- `Sites` - - `UsernameOverride` - - `PasswordOverride` - - `SapServiceUrl` - - `SapEntitySet` - - `SapEntitySetsCache` - - `SapEntitySetsRefreshedAtUtc` - - `LocalExportFolderOverride` - - `ManualImportFilePath` - - `ManualImportLastUploadedAtUtc` -- `ExportSettings` - - zentrale SAP/BI1/SAGE Credentials - - `LocalSiteExportFolder` - - `LocalConsolidatedExportFolder` - - `DebugLoggingEnabled` -- `FieldTransformationRules` - - `RuleScope` -- `ExportLogs` - - `FilePath` -- neue Tabellen: - - `AppEventLogs` - - `CentralSalesRecords` - - SAP-Konfigtabellen - -## Letztes Hauptproblem und Loesung - -### Export hing nach zentraler Speicherung - -Der Export blieb zuletzt nach - -- `Zentrale Tabelle: 20106 Datensaetze gespeichert.` - -haengen. - -Die eigentliche Ursache war am Ende nicht mehr der Batch-Insert selbst, sondern ein kaputter SQLite-Schemazustand: - -- mindestens eine Tabelle referenzierte per FK noch `main.Sites_old` -- dadurch scheiterte `SaveChangesAsync()` spaeter beim Schreiben in `AppEventLogs` oder `ExportLogs` -- die alte Tabelle `Sites_old` existierte nicht mehr - -Beobachteter Fehler: - -- `SQLite Error 1: 'no such table: main.Sites_old'` - -## Umgesetzte Korrekturen - -- `Components/Pages/Dashboard.razor` - - Live-Status pollt waehrend laufendem Export nicht mehr permanent `AppEventLogs` - - stattdessen Anzeige ueber den In-Memory-Status aus `ExportOrchestrationService` -- `Program.cs` - - SQLite `Default Timeout` von `10` auf `60` erhoeht -- `Services/CentralSalesRecordService.cs` - - nach abgeschlossenem Batch-Insert wird explizit `Zentrale Tabelle aktualisiert` gesetzt -- `Services/DatabaseInitializationService.cs` - - automatische Reparaturlogik fuer Tabellen, deren `CREATE TABLE`-SQL noch `Sites_old` referenziert - - betroffene Tabellen werden beim Start neu aufgebaut und Daten rueberkopiert - -Danach wurde der Export erfolgreich getestet und geht jetzt wieder durch. - -## Was bei einer naechsten Stoerung zuerst zu pruefen ist - -1. Tritt beim App-Start die Schema-Reparatur sauber durch? -2. Gibt es noch weitere Tabellen mit FK-Referenz auf `Sites_old`? -3. Erst danach wieder Insert-/Commit-Batches der zentralen Speicherung untersuchen - -## Build-Status - -Letzter Build: - -```text -dotnet build TrafagSalesExporter.sln -``` - -Ergebnis: - -- erfolgreich -- bekannte Warnungen bleiben: - - SAP HANA Architekturwarnung `MSB3270` - - MudBlazor Analyzer `Dense` - -## Nachtrag 2026-04-17 UI-Klarstellung HANA vs. SAP - -- `Components/Pages/Standorte.razor` - - Bereich oben heisst jetzt bewusst `Zentrale HANA-Technik` - - Hinweistext stellt klar: dort erscheinen nur Quellsysteme mit Anschlussart `HANA` - - `SAP` wird zentral unter `Settings -> Quellsysteme` gepflegt und gehoert nicht in diese Box - - der irrefuehrende Button `Server hinzufuegen` wurde entfernt - - neue HANA-Zeilen entstehen aus den Quellsystem-Stammdaten, nicht mehr aus einer zweiten UI-Erfassung - - Dialogtitel fuer HANA wurde auf reine Bearbeitung der zentralen Technik reduziert - -Fachliche Regel jetzt: - -- `Quellsysteme` verwalten die zentralen Systeme und deren Anschlussart -- `Standorte` zeigen fuer HANA nur noch die technische Zentralverbindung -- `SAP` wird nicht mehr implizit in der HANA-Box erwartet - -## Nachtrag 2026-04-17 Pruefung Config-Import/Export - -Der aktuelle Config-Transfer wurde nach den Umbauten nochmals geprueft. - -Status: - -- Das aktuelle Import-/Exportformat passt zum neuen Modell. -- `SourceSystemDefinitions` werden mit `ConnectionKind`, `CentralServiceUrl`, `CentralUsername`, `CentralPassword` importiert/exportiert. -- `HanaServers` enthalten nur noch technische HANA-Verbindungsdaten und keine Credentials mehr. -- Standort-Overrides fuer Username/Password sowie SAP Service URL gehen weiterhin mit. -- Die vorhandenen `ConfigTransferServiceTests` laufen grün. - -Weiterhin offene Architekturpunkte: - -- `ConfigTransferService.ImportJsonAsync` ist weiterhin destruktiv und nicht atomar. - - Erst werden bestehende Daten geloescht, danach wird in mehreren Schritten neu aufgebaut. - - Wenn der Import in der Mitte scheitert, bleibt ein teilweiser Zustand zurueck. -- Altformat-Risiko bei `ConnectionKind`: - - Wenn ein aelteres JSON bereits `SourceSystemDefinitions` enthaelt, aber noch ohne `ConnectionKind`, faellt der DTO-Default auf `HANA`. - - Dadurch koennte ein altes `SAP` beim Import falsch als `HANA` landen. - -Fazit: - -- Fuer Exporte aus dem aktuellen Stand ist der Config-Transfer konsistent. -- Fuer aeltere JSON-Staende braucht der Import noch eine explizite Migrations-/Fallback-Logik. +Nur laden, wenn tiefer technischer Handoff, alte Codepfade, Architekturhistorie oder Fehleranalyse aus frueheren Zwischenstaenden benoetigt werden. diff --git a/TrafagSalesExporter/LLM_SYSTEM_GUIDE.md b/TrafagSalesExporter/LLM_SYSTEM_GUIDE.md index f3c5967..3038b18 100644 --- a/TrafagSalesExporter/LLM_SYSTEM_GUIDE.md +++ b/TrafagSalesExporter/LLM_SYSTEM_GUIDE.md @@ -1,733 +1,19 @@ -# TrafagSalesExporter LLM System Guide +# LLM System Guide -Stand: 2026-05-05 +Stand: 2026-05-27 -## Aktueller Projektstand 2026-05-05 +Diese Datei ist fuer tokenarme RAG-Nutzung komprimiert. -Fuer den aktuellen Finance-/Laenderabgleich zuerst diese Dateien lesen: +## Kontext-Regel -- [HANDOFF_2026-04-15.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/HANDOFF_2026-04-15.md) -- [NEXT_STEPS_2026-04-15.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/NEXT_STEPS_2026-04-15.md) -- [lastchange.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/lastchange.md) -- [SAGE_SPAIN_EXPORT_2026-05-05.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/SAGE_SPAIN_EXPORT_2026-05-05.md) +1. Zuerst `docs/RAG_ROUTER.md` laden. +2. Danach genau eine passende Kurzdatei aus `docs/rag/` laden. +3. Original-/Rohdokus nur bei Detail-, Audit- oder Fehleranalysebedarf laden. -Lokaler FinanceProbe: +## Volltext Bei Bedarf + +Die Detailhistorie liegt hier: ```text -http://localhost:55417/finance +docs/raw_md_archive/HISTORY_CANONICAL.md.raw ``` - -## Aktueller Zusatzstand 2026-05-07 SAP OData / ZSCHWEIZ - -Schweiz/Oesterreich werden ueber eine neue SAP-Tabelle `ZSCHWEIZ` bereitgestellt. - -Wichtige Punkte: - -- ABAP-Report: `report.abap` -- SAP-Tabelle: `ZSCHWEIZ` -- OData EntitySet: `ZSCHWEIZSet` -- App-Standort: `ZSCHWEIZ` / `Schweiz/Oesterreich` -- Geplanter App-Pfad: `SAP` = `SAP OData`, nicht direkter HANA-Spezialcode - -Quellsystem-Codes: - -- `SAP`: SAP OData/Gateway, DisplayName `SAP OData` -- `SAP_HANA`: direkte HANA-Tabellen/Views, DisplayName `SAP HANA Tables/Views` -- `BI1`: HANA -- `SAGE`: HANA -- `MANUAL_EXCEL`: Excel/CSV - -Mapper: - -- SAP OData nutzt `SapSourceDefinition`, `SapJoinDefinition`, `SapFieldMapping`. -- Direkte HANA-Tabellen/Views koennen dieselben Mapping-Tabellen ebenfalls nutzen. -- Gemeinsame Mapping-Engine ist `MappedSalesRecordComposer`. -- `SapCompositionService` und `HanaQueryService.GetMappedSalesRecordsAsync` unterscheiden sich nur noch in der Quellenbeschaffung; Join und `SalesRecord`-Mapping sind zentral. -- Bei HANA mit gepflegten Quellen/Mappings nutzt `HanaDataSourceAdapter` den generischen Mapping-Pfad. -- Ohne HANA-Mapping bleibt der alte B1-HANA-Standardpfad fuer `OINV/INV1/ORIN/RIN1` aktiv. - -Finance-Konfiguration: - -- `FinanceReferences` enthaelt Soll-/check.xlsx-Referenzen. -- `FinanceIntercompanyRules` enthaelt 2nd-party/IC-Regeln. -- Budgetkurse werden als `CurrencyExchangeRates` mit `Notes = Budget 2025` gepflegt. -- Config-Export/-Import umfasst Finance-Referenzen und IC-Regeln. - -ZSCHWEIZ-Seed: - -- Quelle Alias `Z` -- EntitySet `ZSCHWEIZSet` -- Mapping auf `SalesRecord` ist vorbefuellt und grafisch editierbar. -- Beim App-Start wird die ZSCHWEIZ-Quelle samt Feldmapping per Upsert angelegt oder repariert. -- Wenn Gateway `$metadata` liefert, koennen Felder in der UI per `Felder aus Quellen laden` gelesen werden. - -ABAP-Fachlogik: - -- `BUKRS 1100` = Schweiz, `TSC TRCH`, `LAND1 CH` -- `BUKRS 1200` = Oesterreich, `TSC TRAT`, `LAND1 AT` -- `CUSTOMER_LAND` = Kundenland aus `KNA1-LAND1` -- Netto-/Steuerwerte werden in Belegwaehrung und Hauswaehrung geschrieben. - -Aktuelle FinanceProbe-Funktionen: - -- `Meeting Ampel 2025` fuer alle Laender aus `check.xlsx` -- `Detail alle Laender` -- `Spain CSV direct check` -- `Germany Excel sample check` - -Spanien: - -- Datei: `sagespain/v2/Spain_Sales_2025.csv` -- Ist: `3'082'320.18` EUR -- Soll: `3'102'333.61` -- Differenz: `-20'013.43` -- Status: Gelb / Pruefen -- Technisch lesbar, fachliche Differenz noch offen - -Deutschland: - -- Datei: `DE_Beispiel_Export_Daten.xlsx` -- Sample-Summe `NettoPreisGesamtX`: `8'290.70` EUR -- Nur Beispielfile, keine finale Jahreszahl -- Mapping technisch verstanden, finaler DE-Jahresfile fehlt - -Letzte Verifikation: - -- `dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal --no-restore` -- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal --no-restore` -- Ergebnis: Build OK, Tests `50/50`, FinanceProbe `HTTP 200` - -Diese Datei ist fuer andere LLMs gedacht, die das Projekt schnell verstehen und daraus Architekturtexte, Visualisierungen, Ablaufdiagramme oder UI-/Datenflussgrafiken erzeugen sollen. - -## Zweck des Systems - -`TrafagSalesExporter` ist eine Blazor Server App auf `.NET 8`, die Verkaufsdaten aus mehreren Quellsystemen in ein gemeinsames Zielschema ueberfuehrt. - -Quellsysteme: - -- `HANA`-basierte Systeme wie `BI1` und `SAGE` -- `SAP_GATEWAY` ueber OData -- `MANUAL_EXCEL` aus hochgeladenen oder referenzierten Excel-Dateien - -Zielbild: - -- jede Quelle wird in `SalesRecord` normalisiert -- Standortdaten koennen lokal als Excel exportiert werden -- alle Datensaetze werden in `CentralSalesRecords` gespeichert -- eine zentrale konsolidierte Datei wird aus dem zentralen Datenbestand erzeugt -- ein `Management Cockpit` analysiert sowohl exportierte Dateien als auch zentrale Rohdaten - -## Technologie-Stack - -- UI: Blazor Server + MudBlazor -- Authentifizierung: ASP.NET Core Authentication/Authorization, produktiv Windows Authentication / Active Directory -- Datenbank: SQLite (`trafag_exporter.db`) -- Excel lesen/schreiben: ClosedXML -- SAP HANA Zugriff: `Sap.Data.Hana.Core.v2.1.dll` -- SAP Gateway / OData: eigener Service ueber HTTP -- SharePoint Upload/Download: Microsoft Graph + Azure Identity -- Tests: xUnit - -## Einstiegspunkte - -Wichtige Dateien: - -- [Program.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Program.cs) -- [Data/AppDbContext.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Data/AppDbContext.cs) -- [Components/Layout/NavMenu.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Layout/NavMenu.razor) - -`Program.cs` registriert fast die komplette Architektur ueber DI und fuehrt beim Start `DatabaseInitializationService.InitializeAsync()` aus. - -Zusaetzlich registriert `Program.cs` den Zugriffsschutz: - -- `AddCascadingAuthenticationState` -- Windows Authentication fuer produktive Umgebungen -- Development-Authentication-Handler nur bei `ASPNETCORE_ENVIRONMENT=Development` und `Security:DevelopmentBypass=true` -- globale Fallback-Policy fuer authentifizierte/berechtigte User -- Policy `AdminOnly` fuer administrative Seiten - -## Hauptseiten - -Navigation: - -- `/` Dashboard -- `/standorte` -- `/transformations` -- `/management-cockpit` -- `/settings` -- `/logs` - -Dateien: - -- [Components/Pages/Dashboard.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/Dashboard.razor) -- [Components/Pages/Standorte.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/Standorte.razor) -- [Components/Pages/Transformations.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/Transformations.razor) -- [Components/Pages/ManagementCockpit.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/ManagementCockpit.razor) -- [Components/Pages/Settings.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/Settings.razor) -- [Components/Pages/Logs.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/Logs.razor) - -Kurzrollen: - -- `Dashboard`: Einzel-Export, Alle exportieren, zentrale Datei neu erzeugen, Live-Status -- `Standorte`: Standortpflege, zentrale HANA-Technik, SAP-Konfiguration pro Standort, manueller Excel-Import -- `Transformations`: feldweise und record-basierte Regeln -- `Management Cockpit`: Dateianalyse und Rohanalyse aus `CentralSalesRecords` -- `Settings`: SharePoint, Exportpfade, Quellsysteme, Wechselkurse, Config Import/Export -- `Logs`: technische Ereignisprotokolle - -Security: - -- alle Routen erfordern Authentifizierung -- `Settings`, `Standorte` und `Transformations` sind `AdminOnly` -- Admin-Navigation wird nur fuer Admins angezeigt -- eingeloggter Benutzer wird im App-Bar angezeigt - -## Kernmodelle - -Wichtige Entity-Klassen: - -- [Models/Site.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/Site.cs) -- [Models/SourceSystemDefinition.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SourceSystemDefinition.cs) -- [Models/HanaServer.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/HanaServer.cs) -- [Models/SalesRecord.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SalesRecord.cs) -- [Models/CentralSalesRecord.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/CentralSalesRecord.cs) -- [Models/FieldTransformationRule.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/FieldTransformationRule.cs) -- [Models/SapSourceDefinition.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SapSourceDefinition.cs) -- [Models/SapJoinDefinition.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SapJoinDefinition.cs) -- [Models/SapFieldMapping.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SapFieldMapping.cs) -- [Models/SharePointConfig.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SharePointConfig.cs) -- [Models/ExportSettings.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/ExportSettings.cs) -- [Models/ExportLog.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/ExportLog.cs) -- [Models/AppEventLog.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/AppEventLog.cs) -- [Models/CurrencyExchangeRate.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/CurrencyExchangeRate.cs) - -`SalesRecord` / `CentralSalesRecord` enthalten neben den positionsnahen Feldern auch B1-Belegwaehrungsfelder: - -- `DocumentCurrency` aus `DocCur` -- `DocumentTotalForeignCurrency` aus `DocTotalFC` -- `DocumentTotalLocalCurrency` aus `DocTotal` -- `VatSumForeignCurrency` aus `VatSumFC` -- `VatSumLocalCurrency` aus `VatSum` -- `DocumentRate` aus `DocRate` -- `CompanyCurrency` aus `OADM.MainCurncy` - -Wichtig: diese Dokumentwerte sind Belegkopfwerte und werden in der positionsbasierten Excel pro Position wiederholt. Fuer Belegkopfsummen muessen Auswertungen nach Beleg deduplizieren. - -Wichtige Relationen: - -- `Site -> HanaServer` optional -- `Site -> SapSourceDefinitions` -- `Site -> SapJoinDefinitions` -- `Site -> SapFieldMappings` -- `Site -> CentralSalesRecords` -- `SourceSystemDefinition` ist zentrale Stammdatenquelle fuer Quellsysteme - -## Datenbanktabellen - -`AppDbContext` enthaelt: - -- `HanaServers` -- `SourceSystemDefinitions` -- `Sites` -- `SharePointConfigs` -- `ExportSettings` -- `ExportLogs` -- `AppEventLogs` -- `FieldTransformationRules` -- `CurrencyExchangeRates` -- `SapSourceDefinitions` -- `SapJoinDefinitions` -- `SapFieldMappings` -- `CentralSalesRecords` - -## Architekturrollen der Services - -### Export / Orchestrierung - -- [Services/ExportOrchestrationService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ExportOrchestrationService.cs) -- [Services/SiteExportService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/SiteExportService.cs) -- [Services/ConsolidatedExportService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ConsolidatedExportService.cs) -- [Services/CentralSalesRecordService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/CentralSalesRecordService.cs) -- [Services/ExportLogService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ExportLogService.cs) - -Rollen: - -- `ExportOrchestrationService` steuert UI-nahe Exportlaeufe und Live-Status -- `SiteExportService` entscheidet anhand des Quellsystems, wie ein Standort gelesen wird -- `CentralSalesRecordService` ersetzt zentrale Saetze pro Standort -- `ConsolidatedExportService` erzeugt die zentrale Datei - -### Datenquellen - -- [Services/HanaQueryService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/HanaQueryService.cs) -- [Services/SapGatewayService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/SapGatewayService.cs) -- [Services/SapCompositionService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/SapCompositionService.cs) -- [Services/ManualExcelImportService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ManualExcelImportService.cs) -- [Services/SharePointUploadService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/SharePointUploadService.cs) - -Rollen: - -- `HanaQueryService`: SQL gegen SAP B1/HANA-nahe Schemata -- `SapGatewayService`: OData-Metadaten und Reads -- `SapCompositionService`: Mehrquellen-/Join-/Mapping-Aufbau fuer SAP -- `ManualExcelImportService`: Import im Exportformat aus `.xlsx` -- `SharePointUploadService`: Upload fuer Exportdateien und Download fuer manuelle Excel-Dateien - -### Transformation / Mapping - -- [Services/TransformationCatalog.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/TransformationCatalog.cs) -- [Services/TransformationStrategies.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/TransformationStrategies.cs) -- [Services/RecordTransformationService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/RecordTransformationService.cs) -- [Services/CurrencyExchangeRateService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/CurrencyExchangeRateService.cs) -- [Services/ExchangeRateImportService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ExchangeRateImportService.cs) - -Rollen: - -- `Value`-Transformationen fuer einzelne Felder -- `Record`-Transformationen fuer zeilenweite Regeln -- Wechselkursimport und -umrechnung - -### Reporting / Monitoring / Infrastruktur - -- [Services/ManagementCockpitService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ManagementCockpitService.cs) -- [Services/AppEventLogService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/AppEventLogService.cs) -- [Services/ConfigTransferService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ConfigTransferService.cs) -- [Services/DatabaseInitializationService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/DatabaseInitializationService.cs) -- [Services/TimerBackgroundService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/TimerBackgroundService.cs) - -## Der wichtigste technische Ablauf - -### 1. Standort-Export - -Pfad: - -`Dashboard/Standorte -> ExportOrchestrationService -> SiteExportService` - -`SiteExportService` unterscheidet drei Modi: - -1. `SAP_GATEWAY` - - SAP-Quellen lesen - - SAP-Joins anwenden - - SAP-Feldmappings auf `SalesRecord` - - Transformationen anwenden - - Standort-Excel erzeugen - - `CentralSalesRecords` ersetzen - - optional SharePoint-Upload - -2. `HANA` - - effektive zentrale HANA-Konfiguration laden - - optionale Standort-Credential-Overrides anwenden - - SQL in HANA ausfuehren - - `SalesRecord` erzeugen - - Transformationen anwenden - - Standort-Excel erzeugen - - `CentralSalesRecords` ersetzen - - optional SharePoint-Upload - -3. `MANUAL_EXCEL` - - `ManualImportFilePath` auswerten - - wenn lokal/UNC vorhanden: lokal lesen - - wenn SharePoint-Referenz: via Graph temp herunterladen - - Excel in `SalesRecord` lesen - - Transformationen anwenden - - keine neue Standortdatei erzeugen, bestehende Excel dient als Eingabe - - `CentralSalesRecords` ersetzen - -### 2. Konsolidierter Export - -Pfad: - -`Dashboard -> ExportOrchestrationService -> ConsolidatedExportService` - -Semantik aktuell: - -- die zentrale Datei basiert fachlich auf `CentralSalesRecords` -- `ExportAllAsync()` sammelt zwar auch `consolidatedRecords`, aber die zentrale Exportsemantik ist historisch noch nicht vollkommen bereinigt - -### 3. Management Cockpit - -Zwei Betriebsarten: - -1. Dateibasiert - - vorhandene `.xlsx` waehlen - - Datei mit ClosedXML lesen - - Summenfeld waehlen - - Anzeige-Waehrung waehlen - - Kennzahlen, Top-Listen, Datenqualitaet, Findings erzeugen - -2. Zentraldatenbasiert - - direkt aus `CentralSalesRecords` - - Jahr/Monat Filter - - Summenfeld waehlen - - optionale weitere Summenfelder fuer Zeitreihen waehlen - - Anzeige-Waehrung waehlen - - Rohsicht ohne Intercompany-, Budget- oder Spartelogik - -Aktuelle Summenfelder: - -- `Sales Price/Value` -- `Quantity` -- `Standard cost` -- `Quantity * Standard cost` - -Aktuelle Anzeige-Waehrungen: - -- `EUR` -- `USD` -- `Original` - -Die Waehrungsumrechnung nutzt `CurrencyExchangeRateService`. Bei `Original` bleiben Werte in Quellwaehrungen gruppiert. Nicht-betragliche Summenfelder wie `Quantity` haben keine Waehrung. Fehlende Wechselkurse werden gezaehlt und in Hinweisen bzw. Findings sichtbar; betroffene Werte werden in der Zielwaehrung mit `0` einbezogen. - -## Quellsystemlogik - -### SourceSystemDefinition - -`SourceSystemDefinition` ist die fuehrende Wahrheit fuer: - -- `Code` -- `DisplayName` -- `ConnectionKind` -- `IsActive` -- `CentralUsername` -- `CentralPassword` -- `CentralServiceUrl` fuer SAP - -Anschlussarten: - -- `HANA` -- `SAP_GATEWAY` -- `MANUAL_EXCEL` - -### HANA - -Fachliche Logik: - -- zentrale technische HANA-Konfiguration pro Quellsystem -- keine separaten Vollverbindungen pro Standort -- Standort speichert nur Fachdaten plus optionale Username-/Password-Overrides - -Schema-Lookup: - -- in `Standorte` gibt es jetzt `Schemas laden` -- Lookup fragt `sys.tables` in HANA ab -- eingeschraenkt auf typische B1-Schemas mit Tabellen wie `OINV`, `INV1`, `ORIN`, `RIN1`, `OCRD`, `OITM` - -### SAP - -Fachliche Logik: - -- zentrale SAP Service URL in `SourceSystemDefinition.CentralServiceUrl` -- Standort kann `SapServiceUrl` als Override pflegen -- pro Standort gibt es SAP-Quellen, Joins und Feldmappings - -### Manual Excel - -Fachliche Logik: - -- `Site.ManualImportFilePath` kann sein: - - lokaler Windows-Pfad - - UNC-Pfad - - SharePoint-URL - - SharePoint-Pfad unterhalb der konfigurierten Site -- Standortdaten werden aus der Excel eingelesen und in `CentralSalesRecords` uebernommen -- SharePoint dient hier als Eingangsquelle, nicht nur als Exportziel - -## Transformationen - -Das System unterscheidet: - -- `Value`-Transformationen -- `Record`-Transformationen - -Beispiele: - -- `Copy` -- `Uppercase` -- `Lowercase` -- `Prefix` -- `Suffix` -- `Replace` -- `Constant` -- `NormalizeCurrencyCode` -- `FirstNonEmpty` -- `ConvertCurrency` - -Technischer Ablauf: - -- Regeln liegen in `FieldTransformationRules` -- `TransformationCatalog` meldet verfuegbare Strategien an die UI -- `RecordTransformationService` wendet record-basierte Strategien an - -## Wechselkurse - -Vorhanden: - -- `CurrencyExchangeRates` -- `ExchangeRateImportService` fuer ECB-Tageskurse -- `NormalizeCurrencyCode` -- `ConvertCurrency` -- `ManagementCockpitService` kann betragliche Cockpit-Kennzahlen in `EUR` oder `USD` umrechnen - -Wichtig: - -- die Rohsicht im `Management Cockpit` kann jetzt Anzeige-Waehrungen nutzen -- `CHF` ist im Cockpit aktuell nicht als direkte Anzeige-Waehrung in der UI angeboten -- CHF bleibt weiterhin Teil des allgemeinen Transformationssystems -- fachlich ist noch zu klaeren, ob CHF als Standard- oder zusaetzliche Cockpit-Anzeige-Waehrung gebraucht wird - -## SharePoint-Rolle im Gesamtsystem - -`SharePointConfig` enthaelt: - -- `SiteUrl` -- `ExportFolder` -- `CentralExportFolder` -- `TenantId` -- `ClientId` -- `ClientSecret` - -Verwendung: - -- Upload von Standort-Exporten -- Upload der zentralen Datei -- Download von manuellen Excel-Dateien fuer `MANUAL_EXCEL` - -Wichtig: - -- die App arbeitet gegen dieselbe SharePoint-Site, die in `Settings` konfiguriert ist -- fuer `MANUAL_EXCEL` muessen Referenzen auf derselben Site aufloesbar sein - -## Startinitialisierung / Migrationen - -Kritische Datei: - -- [Services/DatabaseInitializationService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/DatabaseInitializationService.cs) - -Aktuelle Rolle: - -- `EnsureCreated` -- Schema-Ergaenzungen per `ALTER TABLE` -- Tabellen-Rebuilds bei Legacy-Schemas -- FK-Reparaturen -- Stammdaten-Seeding -- empfohlene Transformationsregeln - -Bekannte Architekturrealitaet: - -- das ist funktional hilfreich, aber kein sauberes Migrationssystem -- die Startlogik traegt produktive Schema-Reparaturverantwortung -- das ist einer der wichtigsten technischen Risikobloecke - -Bereits gehaertete Fehlerbilder: - -- kaputte FK-Referenzen auf `Sites_old` -- kaputte FK-Referenzen auf `HanaServers_repair_old` -- Legacy-Credential-Spalten in `ExportSettings` -- Legacy-Credential-Spalten in `HanaServers` -- verschobene Spalten im `Sites_old -> Sites`-Kopierpfad - -## Authentifizierung / Autorisierung - -Dateien: - -- [Security/SecurityOptions.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Security/SecurityOptions.cs) -- [Security/SecurityPolicies.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Security/SecurityPolicies.cs) -- [Security/DevelopmentAuthenticationHandler.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Security/DevelopmentAuthenticationHandler.cs) -- [Components/Routes.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Routes.razor) -- [Components/Layout/NavMenu.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Layout/NavMenu.razor) -- [Components/Layout/MainLayout.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Layout/MainLayout.razor) - -Produktives Ziel: - -- Windows Authentication / Active Directory -- keine eigene Benutzerverwaltung -- Zugriff ueber AD-Gruppen -- Adminrechte ueber separate AD-Gruppe - -Konfiguration in `appsettings.json`: - -- `Security:AccessGroups` -- `Security:AdminGroups` -- `Security:DevelopmentBypass` -- `Security:DevelopmentUserIsAdmin` -- `Security:DevelopmentUserName` - -Default-Gruppen: - -- `TRAFAG\\TrafagSalesExporter-Users` -- `TRAFAG\\TrafagSalesExporter-Admins` - -Development: - -- `appsettings.Development.json` aktiviert einen lokalen Development-Auth-Handler -- dieser ist nur fuer lokale Entwicklung gedacht -- produktiv darf `ASPNETCORE_ENVIRONMENT` nicht `Development` sein - -IIS-Betrieb: - -- Windows Authentication aktivieren -- Anonymous Authentication deaktivieren -- AD-Gruppennamen in produktiver Konfiguration setzen - -## Config Import / Export - -Dateien: - -- [Services/ConfigTransferService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ConfigTransferService.cs) -- [Models/ConfigTransferPackage.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/ConfigTransferPackage.cs) - -Aktueller Stand: - -- JSON Export/Import fuer Konfiguration -- Secrets optional -- `SourceSystemDefinitions` im aktuellen Modell enthalten -- HANA-Technik ohne HANA-Credentials -- Standort-Overrides bleiben erhalten - -Wichtige Punkte: - -- Import laeuft jetzt transaktional -- alte `ConnectionKind`-lose Formate bekommen Fallbacks -- `CentralSalesRecords` werden nicht mehr blind geloescht -- bestehende zentrale Laufzeitdaten werden fuer weiterhin vorhandene Standorte remappt - -## Logging - -Es gibt zwei Log-Ebenen: - -- `ExportLogs` fuer fachliche Exporthistorie -- `AppEventLogs` fuer technische und UI-nahe Ereignisse - -Die `Logs`-Seite liest vor allem `AppEventLogs`. - -## Tests - -Testprojekt: - -- [TrafagSalesExporter.Tests](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/TrafagSalesExporter.Tests) - -Aktuell vorhandene Schwerpunkte: - -- Transformationen -- Record-Transformationen -- TransformationCatalog -- CurrencyExchangeRateService -- ExchangeRateImportService -- ManualExcelImportService -- ManagementCockpitService -- ConfigTransferService -- DatabaseInitializationService - -`ManagementCockpitServiceTests` decken inzwischen auch ab: - -- zentrale Analyse nach Jahr/Monat -- Tages-, Monats-, Jahres-, Quellen- und Laenderwerte -- waehlbare Summenfelder -- Waehrungsumrechnung in EUR -- Wechselkurs-Caching -- Mengen-Auswertung ohne Waehrungsumrechnung -- Zusatz-Summenfelder in Zeitreihen - -`SecurityPolicyFactoryTests` decken inzwischen ab: - -- App-Zugriff fuer User in `AccessGroups` -- Ablehnung fuer User ausserhalb der Access-Gruppen -- Development-Auth-Zugriff im lokalen Modus -- Admin-Zugriff fuer User in `AdminGroups` -- Ablehnung normaler User fuer `AdminOnly` -- Development-Admin-Claim - -`CentralSalesRecordServiceTests` decken inzwischen ab: - -- Persistenz und Ruecklesen der B1-Belegwaehrungsfelder in `CentralSalesRecords` - -Wichtig: - -- es gibt aktuell keine echten UI-Komponententests mit `bUnit` -- es gibt keine Browser-E2E-Tests mit `Playwright` -- viele Button-Aktionen sind nur indirekt ueber Services und Persistenz getestet - -## Bekannte offene Architekturfragen - -Fuer andere LLMs wichtig, damit Visualisierungen nicht zu glatt oder zu idealisiert werden: - -1. `DatabaseInitializationService` ist ein produktiver Reparatur-/Migrationslayer, nicht nur Bootstrap. -2. `Settings.razor` und `Standorte.razor` enthalten weiterhin relativ viel Anwendungslogik. -3. Die Semantik der konsolidierten Datei ist historisch teilweise doppelt angelegt. -4. Das `Management Cockpit` ist noch kein voll generalisierter Reporting-Layer. -5. SharePoint ist sowohl Exportziel als auch bei `MANUAL_EXCEL` mittlerweile moegliche Eingangsquelle. - -## Empfohlene Diagramme fuer andere LLMs - -### 1. Kontextdiagramm - -Zeige: - -- Benutzer -- Blazor App -- SQLite -- SAP HANA -- SAP Gateway -- lokale Dateisystempfade -- SharePoint - -### 2. Komponenten-/Service-Diagramm - -Gruppiere: - -- UI -- Orchestrierung -- Quelladapter -- Transformation -- Persistenz -- Reporting - -### 3. Datenflussdiagramm pro Quelltyp - -Je ein separater Flow fuer: - -- HANA -- SAP Gateway -- Manual Excel lokal -- Manual Excel SharePoint - -### 4. ER-Diagramm - -Fokussiere auf: - -- `SourceSystemDefinition` -- `HanaServer` -- `Site` -- `SapSourceDefinition` -- `SapJoinDefinition` -- `SapFieldMapping` -- `CentralSalesRecord` -- `FieldTransformationRule` - -### 5. Sequenzdiagramm fuer Export - -Wichtige Stationen: - -- Dashboard -- ExportOrchestrationService -- SiteExportService -- spezifischer Quellservice -- Transformation -- CentralSalesRecordService -- Excel/SharePoint -- ExportLog/AppEventLog - -## Prompt-Vorlage fuer ein anderes LLM - -Wenn ein anderes LLM daraus Visualisierungen erzeugen soll, funktioniert diese Anweisung gut: - -> Lies `LLM_SYSTEM_GUIDE.md` als primaeren Systemkontext. Erzeuge daraus ein Architekturdiagramm, ein Datenflussdiagramm fuer HANA/SAP/MANUAL_EXCEL, ein ER-Diagramm der wichtigsten Tabellen und ein Sequenzdiagramm fuer `ExportAsync`. Achte darauf, dass `DatabaseInitializationService` produktive Reparaturlogik enthaelt und dass `MANUAL_EXCEL` sowohl lokal als auch ueber SharePoint gelesen werden kann. - -## Weitere Kontextdateien - -Zusatzkontext fuer Verlauf und Risiken: - -- [HANDOFF_2026-04-15.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/HANDOFF_2026-04-15.md) -- [NEXT_STEPS_2026-04-15.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/NEXT_STEPS_2026-04-15.md) - -Diese beiden Dateien sind wichtig, wenn ein anderes LLM nicht nur Struktur, sondern auch historische Umbauten, Risiken und Prioritaeten verstehen soll. diff --git a/TrafagSalesExporter/NEXT_STEPS_2026-04-15.md b/TrafagSalesExporter/NEXT_STEPS_2026-04-15.md index c55b4a3..8cd7d29 100644 --- a/TrafagSalesExporter/NEXT_STEPS_2026-04-15.md +++ b/TrafagSalesExporter/NEXT_STEPS_2026-04-15.md @@ -1,1365 +1,38 @@ # Next Steps -Stand: 2026-05-20 +Stand: 2026-05-27 -## Nachtrag 2026-05-20 Dokumentation bereinigt +Diese Datei ist fuer tokenarme RAG-Nutzung komprimiert. -Erledigt: +## Aktueller Kurzstand -- Markdown-Bestand eingeordnet in `docs/MD_DOKUMENTENSTATUS_2026-05-20.md`. -- HR-Anwenderdoku als Word-Datei optisch ueberarbeitet: - - `docs/HR_KPI_ANLEITUNG_HR_2026-05-20.docx` - - inklusive 10 neuer HR-Cockpit-Punkte, Tabellen, Hinweisboxen und Vorschaugrafik. -- Finance-Anwenderdoku als Word-Datei optisch ueberarbeitet: - - `docs/FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx` - - inklusive Finance Summary Workflow, Filterregeln und Pruefpunkten. -- Neue neutrale Vorschaubilder fuer die Word-Dokus: - - `docs/hr_kpi_cockpit_preview.png` - - `docs/finance_cockpit_preview.png` +- Fuehrender Kurzkontext: `docs/rag/PROJECT.md`. +- Themenrouter: `docs/RAG_ROUTER.md`. +- Offene aktive Fachpunkte stehen in den jeweiligen Kurzdateien: + - Finance: `docs/rag/FINANCE.md` + - Manual Import: `docs/rag/MANUAL_IMPORT.md` + - HR KPI: `docs/rag/HR_KPI.md` + - Deployment: `docs/rag/DEPLOYMENT.md` + - Admin: `docs/rag/ADMIN.md` -Bewusst nicht geloescht: +## Offene Hauptpunkte -- Alte Markdown-Dateien und alte Eintraege bleiben erhalten, wenn sie Pruefwerte, Zwischenentscheide, Mailkontext oder Audit-Spuren enthalten. -- Nicht mehr fuehrende Dateien sind in `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` als historisch markiert. +- DE Alphaplan-Fachabgrenzung muss durch Finance/Munir bestaetigt werden. +- IIS/TLS Serverkonfiguration muss durch IT/Serveradmin korrigiert werden. +- IT/ES/UK Finance-Spezialfaelle nur bei konkreter Nachfrage im Detail laden. -## Nachtrag 2026-05-20 Workflow-Fixes nach Review +## Volltext Bei Bedarf -Umgesetzt: - -- Dashboard warnt vor aktiven manuellen Standorten ohne Datei. -- Nach Einzelstandortexport wird sichtbar, dass die zentrale Excel neu erzeugt werden muss. -- Dashboard erkennt eine veraltete zentrale Excel nach neuem Standortexport. -- Neuer Menuepunkt `Manuelle Importe` fuer Keyuser. -- `Manuelle Importe` hat jetzt die Reiter `Importdateien` und `Anleitung`. -- Der Reiter `Anleitung` zeigt den Upload-/Export-/Zentraldatei-/Finance-Pruefprozess grafisch. -- Zentrale Excel hat ein Blatt `Finance Summary`. -- `Management Analyse` ist als Rohdaten-/Plausibilitaetssicht markiert. -- `Soll/Ist Vergleich` ist als verbindliche Finance-Sicht markiert. -- Export-Live-Status ist nicht mehr pauschal `HANA Abfrage...`. - -Weiterhin offen: - -- DE Alphaplan-Fachabgrenzung: Kundenlaender/Filter muessen von Munir/Finance bestaetigt werden. - -## Nachtrag 2026-05-20 Keyuser Prozess-SVG - -Erstellt: +Die kanonische Detailhistorie liegt hier: ```text -docs/KEYUSER_PROZESSDOKU_2026-05-20.svg +docs/raw_md_archive/HISTORY_CANONICAL.md.raw ``` -Zielgruppe: - -- Finance Keyuser / Poweruser. - -Inhalt: - -- Vorbereitung in Settings und Standorte. -- Manual-Excel-Dateien fuer UK/ES/DE. -- Einzelstandortexport, Export aller Standorte und zentrale Excel. -- Finance-Filter im Endexcel. -- Soll/Ist Vergleich, Management Analyse, Logs. -- Fehlerbehandlung und fachliche Freigabe. - -## Nachtrag 2026-05-20 Technische Architektur-SVG - -Erstellt: +Die frueheren Original-Volltexte liegen als Wiederherstellungs-Backup hier: ```text -docs/SYSTEMARCHITEKTUR_TECHNISCH_2026-05-20.svg +docs/raw_md_archive/original_history_raws.zip ``` -Zielgruppe: - -- Systemarchitekt / Serveradmin / technischer Projektkontext. - -Abgrenzung: - -- Nur produktive Applikation. -- Keine Testapp, Probe-Tools oder temporaeren Analyseprogramme. - -Status: - -- Keyuser-Prozessdoku wurde als separate SVG erstellt. - -## Nachtrag 2026-05-20 DE Alphaplan-Excel provisorisch eingebaut - -Erledigt: - -- Deutschland wird als manueller Excel-Standort vorbereitet: - - `TSC = TRDE` - - `Land = Deutschland` - - `SourceSystem = MANUAL_EXCEL` - - neuer Standort ist standardmaessig inaktiv, damit Export-All nicht ohne Datei scheitert -- Alphaplan-Mapping wird automatisch geseedet: - - `NettoPreisGesamtX` -> `SalesPriceValue` - - `Belegnummer` -> `InvoiceNumber` - - `Position` -> `PositionOnInvoice` - - `ArtikelNummer` -> `Material` - - `ArtikelBezeichnung` -> `Name` - - `Warengruppen-Bezeichnung` -> `ProductGroup` - - `Anz. VE` -> `Quantity` - - `Name/Land Lieferant`, `Name/Land Kunde`, `Branche`, `Versandbedingung` - - `Belegdatum-Rechnung` -> `PostingDate` und `InvoiceDate` - - `DocumentType = Alphaplan Excel` -- Datei erhalten: - -```text -docs/2025_DataExport_DE.xlsx -``` - -Bedienung: - -1. App starten. -2. `Standorte` oeffnen. -3. Deutschland / `TRDE` oeffnen. -4. Alphaplan-Excel hochladen oder Pfad setzen. -5. Standort aktivieren. -6. Standortexport fuer DE ausfuehren. -7. Danach zentrale Excel erzeugen; DE ist dann in `CentralSalesRecords` und im Endexcel enthalten. - -Offen fachlich: - -- Komplette Summe `NettoPreisGesamtX`: `4'154'690.05 EUR`. -- Nur `Land Kunde = Deutschland`: `3'455'276.64 EUR`. -- Sollwert DE: `3'635'923.00 EUR`. -- Finance/Munir muss bestaetigen, welche Kundenlaender oder Filter zum offiziellen DE-Ist gehoeren. - -## Nachtrag 2026-05-20 IIS 500 aktueller Stand - -Vollstaendige Doku: - -```text -docs/DEPLOYMENT_IIS_HANDOFF_2026-05-19.md -``` - -Was sicher bewiesen ist: - -- `https://trch-webapp-bidashboard.trafagch.local/BiDashboard/diag.txt` ist erreichbar. -- Browser zeigt dort: - -```text -BiDashboard publish folder reached 2026-05-20T08:19:14.2667783+02:00 -``` - -- Damit stimmt IIS-URL `/BiDashboard` und der Physical Path zum Publish-Ordner. -- Der verbleibende `500` ist kein falscher Pfad und kein HTTP/HTTPS-Verwechslungsproblem. - -Was umgesetzt wurde: - -- Publish weiterhin aus `TrafagSalesExporter`. -- Ausgabe weiterhin `BiDashboard.dll`, keine EXE. -- `web.config` auf `hostingModel="outofprocess"` umgestellt. -- `stdoutLogEnabled="true"` bleibt aktiv. -- `ASPNETCORE_DETAILEDERRORS=true` fuer Diagnose gesetzt. -- Neu publiziert auf `\\trch-webapp-bidashboard.trafagch.local\BiDashboard$\`. - -Offen fuer Server-Spezialist: - -- .NET 8 Hosting Bundle / AspNetCoreModuleV2 pruefen. -- App Pool pruefen: - - `.NET CLR Version = No Managed Code` - - `Managed Pipeline Mode = Integrated` - - `Enable 32-bit Applications = False` -- Event Viewer lesen: - - `IIS AspNetCore Module V2` - - `.NET Runtime` - - `Application Error` -- App-Pool-Identity mit `Modify` auf Publish-Ordner, `logs` und `trafag_exporter.db*` bestaetigen. - -Wichtig: - -- Der Server braucht kein installiertes Microsoft Excel. -- XLSX wird ueber ClosedXML/OpenXML gelesen. -- CSV-Umstellung ist fuer diesen 500-Fehler nicht noetig. - -## Nachtrag 2026-05-20 IT Finance-Methode - -Erledigt: - -- IT-Methode gemaess Finance-Leiter umgesetzt. -- `CustomerName` enthaelt `Trafag Italia` wird fuer IT ausgeschlossen. -- Doppelte IT-Zeilen mit leerem `Supplier country` werden nur einmal gezaehlt. -- Regel greift im Finance-Vergleich/Testprogramm und in den Finance-Spalten der zentralen Excel. - -Bewusster Entscheid: - -- Die alte 2025-Kombination ist naeher am Soll, aber fachlich nicht zukunftssicher. -- Fuer 2026+ gilt die neue Methode, auch wenn sie 2025 in der aktuellen DB weiter vom Sollwert abweicht. - -Naechster Check: - -- Nach neuem IT-Export pruefen, ob die vollstaendige `Trafag Italia`-Summe aus den neuen Rohdaten sichtbar wird. -- Zentrale Excel fuer `Finance | Country Key = IT`, `Finance | Include = TRUE` filtern und gegen Finance-Vergleich kontrollieren. - -## Nachtrag 2026-05-19 IIS Deployment / 500 Fehler - -Vollstaendige Doku: - -```text -docs/DEPLOYMENT_IIS_HANDOFF_2026-05-19.md -``` - -Aktueller Stand: - -- Publish erfolgt direkt aus `TrafagSalesExporter`. -- Publish-Ausgabe ist an das alte `BiDashboard` angepasst: - - `BiDashboard.dll` - - keine EXE - - `web.config` startet `.\BiDashboard.dll` - - Diagnose aktiv mit `stdoutLogEnabled=true` -- URL mit App-Pfad liefert laut Browser `500`: - -```text -https://trch-webapp-bidashboard.trafagch.local/BiDashboard/ -``` - -Wahrscheinlichstes offenes Thema: - -- App-Pool/IIS hat auf dem Publish-Ordner nur Lesen/Ausfuehren. -- Die App schreibt beim Start in SQLite (`trafag_exporter.db`, `db-shm`, `db-wal`) und in `logs`. -- `icacls`-Versuch von lokal wurde vom Server mit `Zugriff verweigert` abgelehnt. - -Naechster Schritt fuer Server-Spezialist: - -- App-Pool-Identity ermitteln. -- `Modify` auf Publish-Ordner, `logs` und `trafag_exporter.db*` setzen. -- App-Pool neu starten. -- Danach URL neu testen und bei weiterem `500` stdout-Log/Event Viewer lesen. - -## Nachtrag 2026-05-19 Finance-Cockpit-Login finalisieren - -Aktueller Stand: - -- Finance Cockpit hat einen separaten Login. -- HR-KPI-Login und Finance-Cockpit-Login sind technisch getrennte Services/Konfigurationen. -- Finance-Konfiguration liegt in `appsettings.json` unter `FinanceCockpitAccess`. -- Aktueller Benutzer: `finance`. -- Finance nutzt ein eigenes Passwort: `Trafag-Finance-Cockpit-2026!`. -- Globale AD-/Rollenpruefung ist fuer den Moment mit `Security.Enabled = false` deaktiviert. -- Die AD-Gruppen sind nicht geloescht und bleiben in `AccessGroups`/`AdminGroups` dokumentiert. - -Wichtig: - -- Finance- und HR-KPI-Sperren laufen weiter ueber eigene Passwortabfragen. -- AD/Rollen koennen spaeter durch `Security.Enabled = true` wieder aktiviert werden. - -Noch offen: - -1. Entscheiden, wann AD-/Rollenpruefung wieder aktiviert wird. -2. Bei Reaktivierung `Security.Enabled` auf `true` setzen und Gruppen pruefen. -3. Pruefen, ob direkte Run-/Export-/FinanceProbe-Endpunkte ebenfalls geschuetzt werden muessen. -4. In Browser testen: - -```text -http://127.0.0.1:5099/finance-cockpit/vergleich -``` - -5. Nach Entsperren pruefen, dass Navigation und `Finance sperren` korrekt funktionieren. - -## Nachtrag 2026-05-19 Finance-Vergleich / Formeldoku - -Erledigt: - -- `/finance-cockpit/vergleich` nutzt dieselbe `FinanceReconciliationService`-Logik wie die FinanceProbe. -- Leere Ist-Zeilen werden in der Haupt-App ausgefiltert. -- Berechnungslogik pro Land wurde dokumentiert: - -```text -docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md -``` - -Naechster Check: - -- Bei neuer Datenladung `/finance-cockpit/vergleich` und `/finance` gegeneinander vergleichen. -- Besonders ES, AT, UK und IT weiter fachlich klaeren. - -## Nachtrag 2026-05-19 Zentrale Excel fuer Finance-Filter - -Erledigt: - -- Die zentrale Excel `Sales_All_yyyy-MM-dd.xlsx` enthaelt im Blatt `Sales` einen Finance-Spaltenblock: - -```text -Finance | Year -Finance | Country Key -Finance | Date -Finance | Net Sales Actual -Finance | Currency -Finance | Include -Finance | Source Value Field -``` - -- Die zentrale Excel enthaelt ein Hilfsblatt `Finance Filter Hilfe`. -- Das Hilfsblatt erklaert, wie Finance dieselben Ist-Summen wie im Testprogramm erhaelt: - -```text -Finance | Year = 2025 -Finance | Country Key = Land -Finance | Include = TRUE -Summe Finance | Net Sales Actual -``` - -Geprueft: - -- Excel-Finance-Spalten wurden gegen `FinanceReconciliationService` fuer 2025 verglichen. -- AT, CH, ES, FR, IN, IT, UK und US ergaben jeweils `MATCH` mit Differenz `0.00`. - -Naechster praktischer Check: - -- Nach dem naechsten echten Export die SharePoint-Datei `Sales_All_yyyy-MM-dd.xlsx` oeffnen und mit Finance die Filter-/Summenlogik einmal gemeinsam durchgehen. -- Dabei darauf achten, dass nicht versehentlich alte Spalten wie `Land`, `TSC`, `Document Total LC` oder `Sales Price/Value` direkt fuer CFO-Summen verwendet werden. - -## Nachtrag 2026-05-11 UK_B1 Mapping fertigstellen - -Aktueller Stand: - -- UK/England bleibt auf Quelle `UK_B1`. -- Korrekte Quelle: - -```text -https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1 -``` - -- Ursache der grossen UK-Abweichung: - - kein grafisches Mapping fuer `TRUK` - - `Sales Price/Value` wurde als Positionswert gelesen - - in UK_B1 ist es nach aktuellem Befund ein Stueckpreis - - korrekte Formel ist `=[Sales Price/Value]*[Quantity]` - -Bereits im Worktree umgesetzt: - -- `ManualExcelImportService` kann berechnete Mapping-Quellen `=[Header A]*[Header B]`. -- `DatabaseSeedService` seedet/repariert UK_B1-Pfad und `TRUK`-Mapping. -- `DatabaseSeedService` ueberspringt den UK-Mapping-Seed, solange `ManualExcelColumnMappings` noch auf eine alte SQLite-Reparaturtabelle wie `Sites_repair_old` zeigt. -- Unit-Test fuer berechnetes Manual-Excel-Mapping ist vorhanden. -- Doku wurde in `docs/FINANCE_ENTSCHEIDE.md`, `lastchange.md` und `HANDOFF_2026-04-15.md` ergaenzt. -- Tests sind gruen: `59/59`. - -Verifizierter Testlauf: - -```text -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false --verbosity minimal -``` - -Noch offen fuer den praktischen UK-Check: - -1. SharePoint-/Graph-Zugriff reparieren. - - letzter Fehler bei `/run/export/TRUK`: - -```text -ClientSecretCredential authentication failed -127.0.0.1:9 connection refused -``` - -2. UK neu exportieren: - -```text -http://127.0.0.1:5099/run/export/TRUK -``` - -3. Finance pruefen: - -```text -http://127.0.0.1:5099/finance -``` - -4. Ergebnis bewerten: - - wenn UK nahe `3'749'865 GBP` liegt: Mapping war Hauptursache. - - wenn UK bei ca. `3'533'349 GBP` bleibt: Restdifferenz gegen weitere UK-Netto-/Discount-/Frachtspalten pruefen. - -Nicht vergessen: - -- Keine harte Spezialkorrektur fuer genau 2025 einbauen. -- Die Loesung muss ueber Mapping und allgemeine Positionslogik laufen, damit andere Jahre ebenfalls korrekt funktionieren. - -## Nachtrag 2026-05-08 Manual Excel/CSV SharePoint-Automatik - -Erledigt: - -- SharePoint-Ordner koennen bei Manual Excel/CSV als Quelle hinterlegt werden. -- Bei Ordnern wird automatisch die neueste passende `.xlsx`/`.csv` ausgewaehlt. -- Dateinamenmuster fuer bevorzugte Auswahl: `ddMMyy_TSC.xlsx` bzw. `ddMMyy_TSC.csv`. -- Manual-Export schreibt die erzeugte Exportdatei in den Quellordner zurueck: - - lokal: gleicher lokaler Ordner - - SharePoint: gleicher SharePoint-Ordner -- England/TRUK ist lokal auf den SharePoint-Ordner `Import/Finance/UK_B1` korrigiert. -- Spanien-Fehler nach erfolgreichem Einlesen der SharePoint-CSV ist behoben. - -Naechste konkrete Schritte: - -1. App neu starten, damit die Seed-/Repair-Logik aktiv ist. -2. England/TRUK exportieren und pruefen, ob die App `010526_TRUK.xlsx` statt `010426_TRUK.xlsx` auswaehlt. -3. Im SharePoint-Ordner `Import/Finance/UK_B1` pruefen, ob die neue Exportdatei dort wieder abgelegt wird. -4. Deutschland/Alphaplan: im Standort den korrekten Alphaplan-Excel- oder SharePoint-Pfad hinterlegen. -5. Deutschland exportieren und Mapping gegen die Alphaplan-Datei validieren. -6. Falls UK-Dateinamen spaeter ein anderes Muster bekommen, Auswahlregel erweitern. - -## Nachtrag 2026-05-08 FinanceProbe - -Erledigt: - -- FinanceProbe zeigt alle Finance-Referenzen 2025. -- Datenabdeckung je Standort wurde ergaenzt. -- CH/AT-Zuordnung wurde fuer `ZSCHWEIZ` geschaerft. - -Naechste fachliche Schritte: - -1. Nach Export von England, Schweiz/Oesterreich, Spanien und Deutschland die FinanceProbe neu laden. -2. In der Sektion `Datenabdeckung je Standort` pruefen, ob Zeilen 2025 und Periode plausibel sind. -3. Fuer Laender mit `Keine Daten` entscheiden: - - Datenquelle fehlt - - Standort deaktiviert - - Mapping/Export noch nicht gelaufen - - Referenz ist nur zukuenftig relevant -4. Fuer AT/CH nach `ZSCHWEIZ`-Export pruefen, ob `LAND1` korrekt `AT` bzw. `CH` liefert. - -## Nachtrag 2026-05-11 FinanceProbe KI-Steuerung - -Neue Test-Routen: - -- `/run/export/{siteKey}` fuer Einzelstandortexporte -- `/run/export-all` fuer alle aktiven Standorte plus zentrale Datei -- `/run/consolidated` fuer nur zentrale Datei - -Naechster sinnvoller Prueflauf: - -1. FinanceProbe starten. -2. `/run/export/TRUK` fuer England testen. -3. `/run/export/Spanien` testen. -4. `/run/export/Deutschland` testen, sobald Alphaplan-Pfad korrekt ist. -5. `/run/export/ZSCHWEIZ` testen. -6. Danach `/finance` und `docs/finance_status_2025.svg` aktualisieren. - -## Nachtrag 2026-05-07 nach Mapper-/Finance-Aufraeumung - -Erledigt: - -- SAP-OData- und HANA-Mapping laufen ueber `MappedSalesRecordComposer`. -- Doppelte SAP-Mapping-Normalisierung wurde entfernt. -- Konsolidierter Export liest eindeutig aus `CentralSalesRecords`. -- Manuelle Standortdateien duerfen `.xlsx` oder `.csv` sein. -- Finance-Sollwerte, Budgetkurse und Intercompany-Regeln sind DB-Konfiguration mit Seed. - -Naechste technische Schritte: - -1. App neu starten, damit Schema/Seed fuer `FinanceReferences`, `FinanceIntercompanyRules` und Budgetkurse laeuft. -2. In Settings Konfiguration exportieren und pruefen, ob Finance-Referenzen und IC-Regeln enthalten sind. -3. Fuer produktive Pflege spaeter eine kleine UI fuer `FinanceReferences` und `FinanceIntercompanyRules` bauen. -4. Manual Excel als naechsten Aufraeumpunkt vereinheitlichen: Header-Automatik und grafisches Mapping in eine gemeinsame Mapping-Engine ziehen. -5. Bestehende BI1/SAGE-Standorte mittelfristig auf grafisches HANA-Mapping migrieren; erst danach den alten B1-Spezialpfad entfernen. - -## Nachtrag 2026-05-07 ZSCHWEIZ ueber SAP OData - -Finaler Stand fuer Schweiz/Oesterreich: - -- ABAP-Report `report.abap` fuellt SAP-Tabelle `ZSCHWEIZ`. -- Buchungskreis `1100` = Schweiz, `1200` = Oesterreich. -- `LAND1` in `ZSCHWEIZ` ist Reporting-Land aus Buchungskreis. -- `CUSTOMER_LAND` ist Kundenland aus `KNA1-LAND1`. -- Die App liest `ZSCHWEIZ` ueber SAP OData, nicht ueber direkten HANA-Spezialcode. - -In der App: - -- Quellsystem-Code `SAP` bleibt bestehen, DisplayName jetzt `SAP OData`. -- `SAP_HANA` ist nur fuer direkte HANA-Tabellen/Views und heisst `SAP HANA Tables/Views`. -- Der grafische Mapper funktioniert fuer SAP OData und fuer HANA-Tabellen/Views. -- Vorkonfigurierter Standort: - - `TSC = ZSCHWEIZ` - - `Land = Schweiz/Oesterreich` - - `SourceSystem = SAP` - - Quelle `Z` - - EntitySet `ZSCHWEIZSet` -- Quelle und Feldmapping werden beim App-Start per Seed-/Repair-Logik nachgezogen, auch wenn der Standort bereits existiert. - -Naechste Schritte: - -1. App neu starten, damit die Seed-/Repair-Logik laeuft. -2. In `Settings -> Quellsysteme` pruefen, ob `SAP` als `SAP OData` angezeigt wird. -3. In `Standorte` den Standort `ZSCHWEIZ` oeffnen. -4. Falls die zentrale SAP-Service-URL noch auf `ZPOWERBI_EINKAUF_SRV` zeigt, beim Standort `SAP Service URL Override` auf den finalen OData-Service fuer `ZSCHWEIZ` setzen. -5. `Entity Sets refreshen`. -6. Quelle `Z` auf `ZSCHWEIZSet` kontrollieren. -7. `Felder aus Quellen laden`. -8. Grafisches Mapping kontrollieren; manuell mappen musst du nur, wenn Gateway-Feldnamen vom erwarteten `ZSCHWEIZ`-Layout abweichen. -9. Standort aktivieren und Export testen. - -Keine manuelle Feldliste ist noetig, wenn der Gateway-Service `$metadata` korrekt liefert. - -## Nachtrag 2026-05-05 Abschlussstand FinanceProbe / Spanien / Deutschland - -Aktueller lokaler Testpunkt: - -```text -http://localhost:55417/finance -``` - -FinanceProbe enthaelt jetzt: - -- `Meeting Ampel 2025` fuer alle Laender aus `check.xlsx` -- Ampel: - - Gruen: rechnerisch passend - - Gelb: Differenz oder fachliche Abgrenzung offen - - Grau: keine belastbaren Ist-Daten -- `Detail alle Laender` -- `Spain CSV direct check` -- `Germany Excel sample check` - -Spanien: - -- finale v2-Datei liegt unter `sagespain/v2/Spain_Sales_2025.csv` -- Zeilen: `4'341` -- Ist `SalesPriceValue`: `3'082'320.18` EUR -- Soll aus `check.xlsx`: `3'102'333.61` -- Differenz: `-20'013.43` -- Status: Gelb / Pruefen -- Export technisch lesbar, Differenz fachlich mit Spanien/Finance klaeren - -Deutschland: - -- Beispielfile liegt im Projektordner: - -```text -DE_Beispiel_Export_Daten.xlsx -``` - -- relevante Spalte: `NettoPreisGesamtX` -- Mapping-Ziel: `SalesPriceValue` -- Betragszeilen: `2` -- Summe: `8'290.70` EUR -- das ist nur ein Sample, keine finale DE-Jahreszahl -- Deutschland bleibt fuer die finale Ampel offen/grau, bis ein vollstaendiger DE-Jahresfile 2025 oder ein bestaetigter Importlauf vorliegt - -Offen fuer das Finance-Meeting / danach: - -1. Spanien Differenz `-20'013.43` klaeren: - - Periodendatum - - Serien `REG`, `LAT`, `PRO`, `REC` - - Gutschriften / `REC` - - offizielle Sage-Auswertung mit identischem Filter -2. Deutschland finalen Jahresfile 2025 anfordern oder Importlauf mit finaler Datei ausfuehren. -3. Fuer Laender mit Grau pruefen, ob Exportdaten fehlen oder Standort deaktiviert/ohne Datei ist. -4. Fuer CHF-Aussage beachten: - - CHF nur direkt, wenn Quelle CHF liefert - - sonst Mandanten-/Originalwaehrung und separate FX-Regel noetig - -Letzte Verifikation: - -```text -dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal --no-restore -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal --no-restore -``` - -Ergebnis: - -- FinanceProbe Build erfolgreich -- Tests erfolgreich -- `50/50` Tests gruen -- Web UI `HTTP 200` - -## Nachtrag 2026-04-29 Dashboard-Referenzcheck - -Das Dashboard enthaelt jetzt oben einen `Net Sales Actuals 2025`-Referenzcheck gegen die Zahlen aus `check.xlsx` / Power BI Stand 2026-04-29. - -Technischer Stand: - -- Ist-Wert wird automatisch aus dem besten Kandidaten gegen die Referenz gewaehlt: - - `SalesPriceValue` - - `DocumentTotalForeignCurrency - VatSumForeignCurrency` - - `DocumentTotalLocalCurrency - VatSumLocalCurrency` -- Belegkopfwerte werden per `TSC` + `DocumentType` + `DocumentEntry` dedupliziert; Fallback ist `InvoiceNumber` -- Jahr 2025 ueber `InvoiceDate`, fallback `ExtractionDate` -- Vergleich gegen Power-BI-Wert, falls vorhanden, sonst LC-Referenz -- Dashboard zeigt das verwendete `Summenfeld` - -Noch fachlich zu pruefen: - -- IT bleibt als bekannter `not ok`-Fall offen -- UK/US bleiben offen, bis die richtige Quelle bzw. Config geklaert ist -- bei weiteren Standorten erst Referenzwert und Datenquelle bestaetigen -- bestehende zentrale Altdaten enthalten fuer die neuen B1-Felder noch `0`; fuer den echten Feldvergleich ist ein neuer Export/Rebuild noetig - -Konkreter Ablauf nach Neustart/PC-Absturz: - -1. App starten und Dashboard oeffnen: `http://localhost:55416` -2. `Alle exportieren` ausfuehren oder betroffene Standorte einzeln exportieren. -3. Danach `Zentrale Datei neu erzeugen` ausfuehren. -4. Im oberen Dashboard-Block `Net Sales Actuals 2025 Referenz` die Spalte `Summenfeld` kontrollieren. -5. Wenn `Status = OK`, passt die Summe zur hinterlegten Referenz. -6. Wenn `Status = Pruefen`, zuerst kontrollieren: - - richtige Standortquelle/Config - - richtiges Jahr - - ob nach der Codeaenderung wirklich neu exportiert wurde - - ob das gewaehlte Summenfeld fachlich Sinn macht - -Naechster technischer Schritt fuer neue Jahre: - -- Jahresauswahl im Dashboard einbauen. -- Fuer Jahre ohne Referenz trotzdem Ist-Summen und verwendetes Summenfeld anzeigen. -- Sobald eine neue Referenzdatei fuer 2026/2027 vorliegt, Referenzwerte ergaenzen. - -Export-all-Abbruch am 2026-04-29: - -- Fehler war SQLite-Schema: `ExportLogs`, `AppEventLogs`, `CentralSalesRecords` zeigten noch auf `"Sites_repair_old"` -- Schema-Reparatur wurde erweitert und beim App-Start erfolgreich angewendet -- gepruefter Zustand danach: alle drei Tabellen referenzieren wieder `Sites` -- Export kann jetzt erneut getestet werden -- falls erneut Fehler kommt, sollte die Snackbar die Inner Exception anzeigen und die Logs sollten nicht mehr selbst den Export abbrechen - -Nachtest Export all: - -- HANA-Schema-Fehler fuer Frankreich/Italien/USA wurde auf HANA-Quoting zurueckgefuehrt und korrigiert -- Indien bleibt Auth-/Credential-Thema -- England, Spanien und Deutschland sind aktuell `MANUAL_EXCEL` ohne hinterlegte Datei -- Fuer einen sauberen Export-all-Lauf: - - HANA-Standorte mit korrigierter Query nochmals testen - - Indien Credentials pruefen - - manuelle Standorte entweder Datei hinterlegen oder deaktivieren, falls sie nicht im Export-all laufen sollen - -## Nachtrag 2026-04-29 B1-Belegwaehrungsfelder - -Der HANA/B1-Export zieht jetzt zusaetzliche Belegwaehrungsfelder: - -- `DocEntry` -- `DocCur` -- `DocTotalFC` -- `DocTotal` -- `VatSumFC` -- `VatSum` -- `DocRate` -- `OADM.MainCurncy` - -Neue Zielfelder: - -- `DocumentEntry` -- `DocumentCurrency` -- `DocumentTotalForeignCurrency` -- `DocumentTotalLocalCurrency` -- `VatSumForeignCurrency` -- `VatSumLocalCurrency` -- `DocumentRate` -- `CompanyCurrency` - -Zusaetzlich gilt jetzt: - -- `StandardCostCurrency` kommt im HANA-Pfad aus `OADM.MainCurncy` -- `Sales_All_*.xlsx` enthaelt die neuen Spalten -- `CentralSalesRecords` enthaelt die neuen Spalten -- bestehende SQLite-DBs werden beim Start um die Spalten erweitert -- Manual-Excel-Import kann die neuen Spalten lesen - -### Wichtig fuer Auswertungen - -Die neuen `DocumentTotal*`- und `VatSum*`-Werte sind Belegkopfwerte und werden in der positionsbasierten Datei pro Position wiederholt. - -Power BI: - -- nicht positionsweise summieren -- zuerst nach Beleg deduplizieren, bevorzugt `TSC` + `DocumentType` + `DocumentEntry` -- danach Belegkopfwerte summieren - -Positionswerte wie `Sales Price/Value`, `Quantity` und `Standard cost` bleiben fuer positionsbasierte Summen geeignet. - -### Verifikation - -Geprueft: - -```text -dotnet build .\TrafagSalesExporter.csproj --verbosity minimal -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal -``` - -Ergebnis: - -- Build erfolgreich -- Tests erfolgreich -- `48/48` Tests gruen - -## Nachtrag 2026-04-29 Clean-Code-/DI-Befund - -Aktueller Architektur- und DI-Zustand nach den letzten Umbauten: - -Gesamturteil: - -- die App ist deutlich besser strukturiert als zu Beginn -- die Grundarchitektur ist brauchbar bis gut und fuer pragmatischen produktiven Einsatz geeignet -- Dependency Injection wird grundsaetzlich sinnvoll genutzt -- Clean Code ist mittel bis gut, aber noch nicht durchgehend konsequent - -Was positiv ist: - -- Kernservices laufen weitgehend ueber Interfaces und DI -- `DataSourceAdapter`-Pattern trennt `HANA`, `SAP_GATEWAY` und `MANUAL_EXCEL` -- `SiteExportService` ist dadurch deutlich schlanker als frueher -- UI-nahe Page-Services wurden eingefuehrt -- viele Razor-Seiten sind nicht mehr direkt `DbContext`-lastig -- `Scoped` fuer Page-Services und `Singleton` fuer gemeinsame Infrastruktur/Orchestrierung ist bewusst gewaehlt -- Tests decken wichtige Fachlogik ab, u. a. Transformationen, ConfigTransfer, DatabaseInitialization und ManagementCockpit - -Was noch nicht ideal ist: - -- `DatabaseInitializationService` bleibt ein produktiver Reparatur-/Migrationsblock und ist kein sauberes versioniertes Migrationssystem -- `Settings.razor` und `Standorte.razor` enthalten weiterhin relativ viel UI-/Workflow-Logik -- `ManagementCockpitService`, `ConfigTransferService` und Teile der Initialisierung sind noch sehr breit -- konsolidierter Export hat historisch noch Semantikreste zwischen Live-Snapshot und `CentralSalesRecords` -- Secrets/Zugangsdaten sind noch nicht ideal geloest -- zentraler Retry-/Resilience-Layer fuer SAP/HANA/SharePoint fehlt -- Auth ist jetzt pragmatisch mit User/Admin geschnitten, aber noch nicht fein nach `Viewer`, `Exporter`, `Admin`, `Finance` - -Sinnvolle spaetere Clean-Code-Schritte: - -1. `ManagementCockpitService` in kleinere Query-, Aggregation- und Currency-Komponenten teilen -2. `Settings.razor` und `Standorte.razor` weiter Richtung Page-/Application-Services entlasten -3. `DatabaseInitializationService` langfristig durch versionierte Migrationen ersetzen -4. Auth-Policies fachlich feiner schneiden, z. B. `Viewer`, `Exporter`, `Admin`, `Finance` -5. Retry/Timeout/Failure-Handling fuer externe Systeme zentralisieren -6. Secret-Store-Konzept umsetzen - -## Nachtrag 2026-04-29 Authentifizierung / AD - -Die App wurde nach IT-Rueckmeldung gegen anonymen Zugriff abgesichert. - -Neuer Stand: - -- globale Authentifizierungspflicht -- produktiv vorgesehen: Windows Authentication / Active Directory -- Zugriff und Adminrechte ueber AD-Gruppen -- kein eigener App-Login -- kein versteckter produktiver Backdoor -- lokaler Development-Bypass nur bei `ASPNETCORE_ENVIRONMENT=Development` - -Neue/angepasste Dateien: - -- `Program.cs` -- `Security/SecurityOptions.cs` -- `Security/SecurityPolicies.cs` -- `Security/DevelopmentAuthenticationHandler.cs` -- `Components/Routes.razor` -- `Components/_Imports.razor` -- `Components/Layout/NavMenu.razor` -- `Components/Layout/MainLayout.razor` -- `Components/Pages/Settings.razor` -- `Components/Pages/Standorte.razor` -- `Components/Pages/Transformations.razor` -- `appsettings.json` -- `appsettings.Development.json` - -Aktuelle Default-Gruppen: - -- `TRAFAG\TrafagSalesExporter-Users` -- `TRAFAG\TrafagSalesExporter-Admins` - -### Noch mit IT zu klaeren - -1. Exakte AD-Domain-/Gruppennamen bestaetigen -2. AD-Gruppen anlegen oder bestehende Gruppen verwenden -3. IIS-Zielumgebung festlegen -4. Auf IIS Windows Authentication aktivieren -5. Auf IIS Anonymous Authentication deaktivieren -6. Sicherstellen, dass produktiv nicht `ASPNETCORE_ENVIRONMENT=Development` gesetzt ist -7. Test mit einem normalen User und einem Admin-User durchfuehren - -### Fachliche Rollenentscheidung - -Aktuell: - -- Admin: - - `Settings` - - `Standorte` - - `Transformations` -- berechtigter User: - - Dashboard - - Management Cockpit - - Logs - -Noch zu entscheiden: - -- ob `Logs` ebenfalls Admin-only sein soll -- ob Export-Buttons im Dashboard nur fuer eine eigene Rolle `Exporter` sichtbar sein sollen -- ob Management Cockpit fuer alle berechtigten User oder nur fuer Management/Finance-Gruppen sichtbar sein soll - -### Verifikation - -Geprueft: - -```text -dotnet build .\TrafagSalesExporter.csproj --verbosity minimal -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal -``` - -Ergebnis: - -- Build erfolgreich -- Tests erfolgreich -- `48/48` Tests gruen -- Auth-Policy-Tests fuer AccessGroup, AdminGroup und Development-Admin vorhanden -- lokaler Development-Auth-Start geprueft: `http://localhost:55416` antwortet mit HTTP `200` - -## Nachtrag 2026-04-29 Management Cockpit - -Seit dem 2026-04-17 wurden im `Management Cockpit` weitere Auswertmoeglichkeiten umgesetzt und nachtraeglich aus dem aktuellen Code rekonstruiert. - -Aktueller neuer Stand: - -- Summenfeld ist waehbar statt fest auf Umsatz: - - `Sales Price/Value` - - `Quantity` - - `Standard cost` - - `Quantity * Standard cost` -- Anzeige-Waehrung ist waehbar: - - `EUR` - - `USD` - - `Original` -- betragliche Werte werden ueber `CurrencyExchangeRateService` umgerechnet -- nicht-betragliche Werte wie `Quantity` bleiben ohne Waehrung -- fehlende Wechselkurse werden gezaehlt und in der UI/Hinweisen sichtbar -- zentrale Roh-Auswertung kann weitere Summenfelder als Zusatzspalten in Jahres-, Monats- und Tageswerten anzeigen -- dateibasierte Excel-Analyse nutzt ebenfalls Summenfeld und Anzeige-Waehrung - -Betroffene Dateien: - -- `Components/Pages/ManagementCockpit.razor` -- `Models/ManagementCockpitModels.cs` -- `Services/IManagementCockpitService.cs` -- `Services/ManagementCockpitPageService.cs` -- `Services/ManagementCockpitService.cs` -- `TrafagSalesExporter.Tests/ManagementCockpitServiceTests.cs` - -Neue Tests: - -- Umrechnung zentraler Werte in EUR -- Wechselkurs-Cache pro Waehrung/Ziel/Datum -- Mengen-Auswertung ohne Waehrungsumrechnung -- Zusatzwerte in Zeitreihen - -### Jetzt sinnvoll zu pruefen - -1. `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` -2. Management Cockpit in der App oeffnen -3. zentrale Auswertung mit `Sales Price/Value` in `EUR` pruefen -4. zentrale Auswertung mit `Quantity` pruefen und bestaetigen, dass keine Waehrung angezeigt wird -5. Zusatzfelder `Quantity` und `Quantity * Standard cost` in Jahres-/Monatswerten pruefen -6. Dateianalyse einer exportierten Excel mit unterschiedlichen Summenfeldern pruefen -7. fachlich klaeren, ob `CHF` neben `EUR` und `USD` als Anzeige-Waehrung angeboten werden soll -8. fachlich klaeren, ob fehlende Wechselkurse als `0` in Zielwaehrung korrekt sind oder separat ausgewiesen werden sollen - -## Nachtrag 2026-04-17 Refactoring-Fortschritt - -Mehrere frueher als hoch priorisiert markierte Architekturpunkte sind inzwischen bereits umgesetzt. - -Erledigt: - -- DataSourceAdapter-Pattern fuer `HANA`, `SAP_GATEWAY`, `MANUAL_EXCEL` -- `SiteExportService` deutlich verschlankt -- Page-Services auf `Scoped` -- `DatabaseInitializationService` in Schema-/Seed-/Orchestrator-Bloecke getrennt -- `Dashboard`, `Logs` und `Transformations` von direktem `DbContext`-Zugriff befreit -- HANA-SQL-Injection-Pfad geschlossen -- blockierende `.GetAwaiter().GetResult()`-Aufrufe im HANA-Pfad entfernt - -Neuer verifizierter Stand: - -- `dotnet build .\TrafagSalesExporter.csproj --verbosity minimal` erfolgreich -- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` -- `36/36` Tests gruen - -### Neue Top-Prioritaeten ab jetzt - -#### 1. Adapter- und Resolver-Tests nachziehen - -Prio hoch. - -Warum: - -- das neue `DataSourceAdapter`-Pattern ist architektonisch wichtig -- genau dieser neue Schnitt hat aktuell noch keine gezielten Unit-Tests - -Sinnvoll waeren: - -- `DataSourceAdapterResolver`-Tests -- `HanaDataSourceAdapter`-Tests -- `SapGatewayDataSourceAdapter`-Tests -- `ManualExcelDataSourceAdapter`-Tests - -#### 2. Retry-/Robustheitslayer - -Prio hoch. - -Vor allem fuer: - -- SharePoint -- SAP Gateway -- HANA-nahe Netzpfade - -Aktuell brechen diese Integrationen bei transienten Problemen zu direkt ab. - -#### 3. Secret-Store-Konzept - -Prio hoch bis mittel. - -Aktuell liegen Zugangsdaten weiterhin in der App-/DB-Konfiguration. -Langfristig sollte entschieden werden: - -- Windows Credential Manager -- DPAPI / verschluesselte Ablage -- externer Secret Store - -#### 4. `DatabaseInitializationService` weiter haerten, aber nicht mehr blind gross refactoren - -Prio mittel. - -Der schlimmste Architekturteil ist deutlich besser als vorher. -Weitere Arbeit dort sollte jetzt nur noch zielgerichtet passieren: - -- Regressionstests fuer konkrete Legacy-/Repair-Zustaende -- spaeter moeglichst versionierte Migrationen - -#### 5. MudBlazor-Analyzer-Warnungen bereinigen - -Prio mittel. - -Nicht kritisch fuer Produktion, aber sinnvoll fuer sauberen Build: - -- `Logs.razor` -- `Transformations.razor` -- `Standorte.razor` - -### Was im Vergleich zu frueher nicht mehr Top-Prioritaet ist - -Nicht mehr ganz oben: - -- generisches weiteres Page-Service-Refactoring um des Refactorings willen -- noch mehr strukturelles Verschieben ohne Risikoreduktion - -Der wirtschaftlich sinnvolle Fokus liegt jetzt eher auf: - -- Absicherung -- Robustheit -- Integrationsstabilitaet - -## Nachtrag 2026-04-17 - -Der Punkt `CHF-Umrechnung / Wechselkurse` ist nicht mehr komplett offen. - -Der aktuelle Ist-Stand ist: - -- `CurrencyExchangeRateService` ist implementiert -- `ExchangeRateImportService` importiert ECB-Kurse -- `NormalizeCurrencyCode` und `ConvertCurrency` sind im Transformationssystem registriert -- fehlende Unit-Tests dafuer wurden am 2026-04-17 ergaenzt - -Neuer Teststand: - -- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` -- erfolgreich -- `31/31` Tests gruen - -Was fuer Waehrungen trotzdem noch offen bleibt: - -- fachlicher Einsatz der `ConvertCurrency`-Regeln in echten Standortkonfigurationen pruefen -- UI-Flow fuer Wechselkurspflege in `Settings.razor` manuell gegenpruefen -- ECB-Import einmal real ueber die UI bzw. App-Funktion pruefen -- bestaetigen, fuer welche Sichten CHF die Zielwaehrung sein soll -- Management-Cockpit-Rohsicht nur dann auf CHF umstellen, wenn fachlich gewuenscht - -## Architektur-Nachtrag 2026-04-17 - -Nach einer separaten Architekturpruefung wurden die naechsten Schritte neu priorisiert. - -Wichtig: - -- neue Fachfeatures sind aktuell **nicht** der erste Engpass -- zuerst muessen die Architektur-Risiken in Initialisierung, Config-Import und UI-Service-Schnitt bereinigt werden - -### Neue Top-Prioritaeten - -#### 1. `DatabaseInitializationService` absichern - -Prio sehr hoch. - -Gruende: - -- Startlogik enthaelt manuelle Schema-Migrationen -- FK-Reparaturen laufen produktiv beim App-Start -- dort wurde ein konkretes Risiko fuer verschobene Spaltenwerte beim `Sites_old`-Kopierpfad erkannt - -Vor weiterer Fachentwicklung: - -- Initialisierungspfad genau pruefen -- SQL-Kopierlogik validieren -- moeglichst Richtung versionierte Migrationen bewegen - -#### 2. `ConfigTransferService.ImportJsonAsync` neu denken - -Prio sehr hoch. - -Aktuelles Problem: - -- Import loescht sehr viel und baut danach stueckweise neu auf -- nicht atomar -- potenziell teilzerstoerter Zustand bei Fehlern -- `CentralSalesRecords` werden mitimportiert/mitgeloescht, obwohl sie eher Laufzeitdaten als Konfiguration sind - -Ziel: - -- atomarer Import -- saubere Trennung zwischen Konfiguration und Betriebsdaten - -#### 3. Razor-Seiten entlasten - -Prio hoch. - -Betroffen vor allem: - -- `Components/Pages/Settings.razor` -- `Components/Pages/Standorte.razor` - -Ziel: - -- DB- und Fachlogik aus UI-Code in Services / Application-Layer verschieben -- Seiten nur noch fuer Interaktion und Formularzustand - -#### 4. Konsolidierten Export semantisch klaeren - -Prio mittel. - -Offene Frage: - -- zentrale Datei aus laufendem Snapshot - oder -- zentrale Datei immer aus `CentralSalesRecords` - -Aktuell ist die Verantwortung unscharf. - -#### 5. Reporting verallgemeinern - -Prio mittel. - -Erst nach den Infrastrukturthemen: - -- hartcodierte Jahreslogik im Cockpit entfernen -- fachlich entscheiden, ob und wo CHF-Rohsicht gebraucht wird - -### Praktische Reihenfolge fuer den naechsten Wiedereinstieg - -Wenn nach erneutem Absturz oder Kontextverlust weitergemacht wird: - -1. `HANDOFF_2026-04-15.md` lesen, speziell die Architekturpruefung vom 2026-04-17 -2. `DatabaseInitializationService` als ersten Risikoblock ansehen -3. `ConfigTransferService.ImportJsonAsync` als zweiten Risikoblock ansehen -4. erst danach wieder an Cockpit / CHF / weitere Fachfeatures gehen - -## Nachtrag HANA-/Standort-Workflow 2026-04-17 - -Der doppelte HANA-Workflow wurde inzwischen bereits bereinigt. - -Neuer Stand: - -- oben zentrale HANA-Konfiguration pro Quellsystem `BI1` / `SAGE` -- unten im Standort keine eigene wirksame Voll-HANA-Konfiguration mehr -- HANA-basierte Standorte ziehen ihre technische Verbindung aus der zentralen Quellsystem-Konfiguration -- Standort bleibt fuer fachliche Daten und optionale Credential-Overrides zustaendig -- die frueher doppelte HANA-UI im Standortdialog ist inzwischen auch sichtbar entfernt -- der Verbindungstest in `Settings.razor` prueft und meldet jetzt die zentrale HANA-Verbindung klar - -### Was dazu noch praktisch geprueft werden sollte - -- `Standorte`-Seite im UI manuell durchklicken -- pruefen, ob `BI1`- und `SAGE`-Standort beim Speichern sauber auf die zentrale HANA-Konfiguration zeigen -- pruefen, ob Aenderung oben bei zentraler HANA-Konfiguration in nachfolgenden Exporten wirklich greift - -### Anschlussarbeiten - -- `ConfigTransferService` spaeter auf das neue zentrale HANA-Modell fachlich nachziehen und kritisch pruefen -- `DatabaseInitializationService` weiter konsolidieren, damit die Zuordnung alter HANA-Daten langfristig robuster wird - -## Nachtrag Quellsystem-Verwaltung 2026-04-17 - -Die bisher hart codierten Quellsystem-Listen wurden ersetzt. - -Neuer Stand: - -- `SourceSystemDefinition` ist jetzt die zentrale Stammdatenquelle fuer Quellsysteme -- `Settings.razor` hat jetzt eine GUI zur Pflege von Quellsystemen -- `Standorte.razor` zieht seine Quellsystem-Auswahl aus diesen Stammdaten -- `Transformations.razor` zieht die Systemauswahl ebenfalls aus diesen Stammdaten -- zentrale Credentials haengen jetzt am Quellsystem selbst -- HANA-Zentralverbindungen werden nur noch fuer Quellsysteme mit Anschlussart `HANA` gezeigt -- alte zentrale Credential-Felder in `ExportSettings` sind aus dem aktiven Codepfad entfernt -- `ExportSettings` wird beim Start auch schematisch auf das neue Feldset bereinigt -- HANA speichert zentral keine eigenen Credentials mehr; dort bleiben nur technische Verbindungsdaten -- `HanaServer.Username` / `Password` sind nur noch Laufzeitfelder und nicht mehr im EF-Schema gemappt -- SAP Service URL wird jetzt zentral im Quellsystem gepflegt; der Standort haelt nur noch ein optionales Override -- Quellsysteme werden jetzt per Dialog bearbeitet statt nur ueber Inline-Tabellenfelder - -### Was dazu noch praktisch geprueft werden sollte - -- in `Settings` ein neues Quellsystem per GUI anlegen -- pruefen, ob es danach in `Standorte` und `Transformations` sofort auswählbar ist -- pruefen, ob deaktivierte Quellsysteme in neuen Standort-/Regelanlagen nicht mehr normal angeboten werden -- pruefen, ob Aenderung der Anschlussart von `HANA` auf `SAP_GATEWAY` oder `MANUAL_EXCEL` fachlich sauber wirkt -- pruefen, ob bestehende BI1/SAGE/SAP-Daten nach Startmigration korrekt in `SourceSystemDefinitions` stehen -- pruefen, ob Konfiguration-Export/Import ohne die alten Credential-Felder sauber mit `SourceSystemDefinitions` arbeitet -- pruefen, ob zentrale SAP Service URL ohne Override sauber fuer Refresh, Export und Dashboard greift -- pruefen, ob SAP Service URL Override am Standort die zentrale URL erwartungsgemaess uebersteuert - -## Nachtrag 2026-04-16 - -Seit dem letzten Stand kamen mehrere groessere Erweiterungen dazu. Die offenen Punkte unten muessen deshalb im neuen Kontext gelesen werden. - -## 0. Neuer Ist-Stand - -Zusaetzlich zum alten Stand ist jetzt vorhanden: - -- manueller Standort-Import ueber `MANUAL_EXCEL` -- Dashboard mit `Alle exportieren`, `Zentrale Datei neu erzeugen` und zentralem `Excel oeffnen` -- Roh-Auswertung im `Management Cockpit` direkt aus `CentralSalesRecords` -- erweitertes Transformationssystem mit `Value`- und `Record`-Regeln -- HANA-Schema-Lookup im Standortdialog -- Testprojekt mit aktuell 18 gruenden Tests - -## 1. Status - -Der Export geht jetzt wieder durch. - -Die zuletzt gefundene Hauptursache war nicht mehr ein reiner SQLite-Lock beim Batch-Insert, sondern ein kaputter FK-Schemazustand in der bestehenden DB: - -- SQLite referenzierte in mindestens einer Tabelle noch `main.Sites_old` -- dadurch scheiterte `SaveChangesAsync()` beim Schreiben z. B. in `AppEventLogs` oder `ExportLogs` -- sichtbarer Effekt: Export blieb nach `Zentrale Tabelle: ... Datensaetze gespeichert.` haengen - -## 2. Umgesetzter Fix - -Umgesetzt wurde: - -- Dashboard-Live-Status liest waehrend laufendem Export nicht mehr staendig aus `AppEventLogs`, sondern nutzt den In-Memory-Status des `ExportOrchestrationService` -- SQLite `Default Timeout` in `Program.cs` auf `60` erhoeht -- `CentralSalesRecordService` setzt nach den Batches explizit `Zentrale Tabelle aktualisiert` -- `DatabaseInitializationService` repariert beim App-Start automatisch Tabellen, deren FK-SQL noch `Sites_old` referenziert - -Betroffene Dateien: - -- `Program.cs` -- `Components/Pages/Dashboard.razor` -- `Services/CentralSalesRecordService.cs` -- `Services/DatabaseInitializationService.cs` - -## 3. Was noch getestet werden sollte - -Kurz gegenpruefen: - -- Export eines Standorts erneut -- `Excel oeffnen` nach erfolgreichem Export -- `Export erfolgreich` inkl. `Pfad=...` -- Dashboard-Live-Status setzt sich nach Abschluss sauber zurueck -- `Alle exportieren` -- `Zentrale Datei neu erzeugen` -- zentrale Datei im Dashboard oeffnen - -## 3a. Manuellen Excel-Import pruefen - -Zu testen: - -- Standort auf `MANUAL_EXCEL` stellen -- Excel im Standort hochladen -- Standort exportieren -- pruefen, ob `CentralSalesRecords` fuer diesen Standort ersetzt wurden -- pruefen, ob der zentrale Export den Standort korrekt enthaelt - -Dateien: - -- `Components/Pages/Standorte.razor` -- `Services/ManualExcelImportService.cs` -- `Services/SiteExportService.cs` - -## 3b. HANA-Schema-Lookup pruefen - -Zu testen: - -- bei `BI1`-Standort `Schemas laden` -- bei `SAGE`-Standort `Schemas laden` -- wird ein plausibles B1-Schema angeboten? -- funktioniert danach Export ohne manuelle Schema-Eingabe? -- zeigt England / Spezialstandort jetzt schneller, wenn Schema oder Rechte nicht passen? - -Dateien: - -- `Components/Pages/Standorte.razor` -- `Services/HanaQueryService.cs` - -## 4. Falls wieder ein Fehler auftritt - -In dieser Reihenfolge pruefen: - -1. Exakte Fehlermeldung aus `AppEventLogs` bzw. Console notieren -2. Pruefen, ob die Reparaturlogik beim Start gelaufen ist -3. Pruefen, ob noch weitere Tabellen mit veralteter FK-Referenz existieren -4. Erst danach wieder am Batch-/Commit-Pfad der zentralen Speicherung arbeiten - -## 5. SAP-Funktionalitaet kurz gegenpruefen - -Zu testen: - -- `Quellen refreshen` -- `Felder aus Quellen laden` -- `Auto-Match` -- SAP-Export eines Standorts - -Dateien: - -- `Components/Pages/Standorte.razor` -- `Services/SapGatewayService.cs` -- `Services/SapCompositionService.cs` - -## 6. Management Cockpit pruefen - -Zu testen: - -- vorhandene Excel-Datei auswaehlbar -- Analyse laeuft -- Kennzahlen plausibel -- Roh-Auswertung aus `CentralSalesRecords` laeuft -- Jahr/Monat-Filter funktionieren -- Summen nach Quelle / Land plausibel - -Dateien: - -- `Components/Pages/ManagementCockpit.razor` -- `Services/ManagementCockpitService.cs` - -## 6a. Fachlich bewusst noch offen - -Noch nicht final umsetzen ohne Rueckmeldung Fachseite: - -- Intercompany-Filter -- fachliche Nutzung der CHF-Umrechnung in Cockpit / Reports -- Budgetvergleich -- Gruppenlogik -- Spartenlogik -- Margenlogik - -Diese Punkte sollen spaeter moeglichst dynamisch auf dem neuen Transformations-/Mapping-Ansatz aufsetzen, aber aktuell nicht hart geraten werden. - -## 6b. Naechste sinnvolle Testkandidaten - -Wenn weiter in Tests investiert wird, sind die naechsten Kandidaten: - -- `ExportOrchestrationService` -- spaeter End-to-End-Tests fuer den Wechselkurs-/Transformationspfad -- spaeter evtl. SQLite-nahe Integrationstests fuer `DatabaseInitializationService` - -Aktueller Teststatus: - -- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` -- erfolgreich -- `31/31` Tests gruen - -## 7. Referenzdatei - -Fuer den vollstaendigen Kontext zuerst lesen: - -- `HANDOFF_2026-04-15.md` - -## 8. Letzte bereinigte UI-Irritation - -Stand 2026-04-17: - -- In `Standorte` wurde die obere Box auf `Zentrale HANA-Technik` geklaert. -- Dort gibt es keinen `Server hinzufuegen`-Pfad mehr. -- Grund: zentrale HANA-Eintraege werden aus `Quellsystemen` mit Anschlussart `HANA` abgeleitet. -- `SAP` gehoert fachlich nicht in diese Box, sondern in `Settings -> Quellsysteme`. - -Wichtig fuer den naechsten Wiedereinstieg: - -- Wenn ein Benutzer fragt `wo ist SAP?`, ist die richtige Antwort: nicht in der HANA-Box, sondern in der zentralen Quellsystem-Verwaltung. -- Wenn ein HANA-System oben fehlt, zuerst `Settings -> Quellsysteme` pruefen und dort Anschlussart `HANA` setzen. - -## 9. Config-Transfer erneut geprueft - -Stand 2026-04-17: - -- Der aktuelle Config-Import/-Export passt zum neuen Datenmodell. -- Zentral verwaltete Quellsysteme, SAP-Zentral-URL, HANA-Technik ohne HANA-Credentials und Standort-Overrides werden korrekt im Transferformat abgebildet. -- Die vorhandenen `ConfigTransferServiceTests` bestaetigen den aktuellen Rundlauf. - -Fuer den naechsten Wiedereinstieg wichtig: - -- Das aktuelle Format ist fuer heutige Exporte konsistent. -- `ImportJsonAsync` ist aber weiterhin nicht atomar und loescht zuerst produktive Konfiguration. -- Zusaetzlich gibt es ein Altformat-Risiko: - - aeltere JSONs mit `SourceSystemDefinitions`, aber ohne `ConnectionKind`, koennen wegen DTO-Default falsch als `HANA` interpretiert werden. - -Naechste saubere Haertung fuer dieses Thema: - -- Config-Import transaktional machen -- Legacy-Fallback fuer fehlendes `ConnectionKind` einbauen - -## 10. Nachtrag 2026-05-20: Finance-Regeln statt harte Laenderlogik - -Aktueller Stand: - -- Es gibt jetzt `Admin -> Finance Regeln`. -- Die fachliche Abgrenzung fuer Finance wird dort als Regel gepflegt: - - Land/Scope - - Jahr - - Regeltyp - - Feld - - Vergleich - - Wert - - Notiz - - Sortierung/Aktiv -- Diese Regeln wirken auf: - - zentrales Excel (`Finance | ...` und `Finance Summary`) - - Soll/Ist Vergleich -- Sie veraendern nicht: - - Rohdatenimport - - Mapping in `Admin -> Standorte` - - technische Transformationen in `Admin -> Transformationen` - -UI-Logik fuer Keyuser: - -```text -Admin -> Standorte = Quelle und Spaltenmapping -Admin -> Transformationen = technische Feldnormalisierung/-berechnung -Admin -> Finance Regeln = CFO-/Finance-Abgrenzung -``` - -Wichtige Default-Regeln: - -- DE: - - Alphaplan-Jahresfile -> Finance-Jahr 2025 - - Trafag AG ausschliessen - - Magnetic Sense ausschliessen - - GS2510095 ausschliessen - - GS-Gutschriften negativ -- IT: - - Trafag Italia ausschliessen - - doppelte Blank-Supplier-Country-Zeilen deduplizieren - -Nach jedem Regelwechsel testen: - -1. passenden Standort exportieren -2. zentrale Datei neu erzeugen -3. im Endexcel `Finance Summary` kontrollieren -4. `Soll/Ist Vergleich` kontrollieren - -Letzter DE-Pruefstand: - -```text -DE 2025 im zentralen Excel: 3'652'394.46 -``` - -## 11. Nachtrag 2026-05-20: Export Dashboard Datenbasis - -Im Export Dashboard steht direkt nach `Land` die Spalte `Basis`. - -Angezeigt wird: - -- `Excel-Datei` mit Tabellen-Icon -- `CSV-Datei` mit Datei-Icon -- `SAP Service` mit Cloud-Sync-Icon -- `Server` mit Storage-Icon -- `Manuelle Datei`, falls manuelle Quelle ohne erkennbaren Pfad - -Die Spalte kommt aus `DashboardPageService.ResolveDataBasis`. +Nur laden, wenn alte Review-Historie, genaue erledigte Punkte oder fruehere Priorisierung benoetigt werden. diff --git a/TrafagSalesExporter/docs/FINANCE_DASHBOARD_TODO_2026-05-15.md b/TrafagSalesExporter/docs/FINANCE_DASHBOARD_TODO_2026-05-15.md index f04083c..e491868 100644 --- a/TrafagSalesExporter/docs/FINANCE_DASHBOARD_TODO_2026-05-15.md +++ b/TrafagSalesExporter/docs/FINANCE_DASHBOARD_TODO_2026-05-15.md @@ -1,66 +1,13 @@ # Finance Dashboard Todo -Stand: 2026-05-20 +Stand: 2026-05-27 -Hinweis: +Historische Todo-Liste, fuer RAG komprimiert. -Dieses Dokument ist eine historische Todo-Liste vom 2026-05-15 und wurde am 2026-05-20 nachgezogen. Fuer den aktuell fuehrenden Dokumentenstatus siehe: +Aktueller Finance-Kontext steht in `docs/rag/FINANCE.md`. + +Volltext bei Bedarf: ```text -docs/MD_DOKUMENTENSTATUS_2026-05-20.md +docs/raw_md_archive/HISTORY_CANONICAL.md.raw ``` - -Ziel: Aufbau eines modernen, uebersichtlichen Intranet-Dashboards fuer das Group Sales Reporting, zugaenglich fuer alle freigegebenen Benutzer. - -## Todo - -| Prio | Aufgabe | Status | -| --- | --- | --- | -| 1 | Fuehrendes CFO-Dokument verwenden: `FINANCE_CHEF_SUMMARY_2026-05-15.docx` | Historisch; neue Anwenderdoku `FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx` ergaenzt | -| 1 | Offene Finance-Entscheide mit Andreas/Finance durchgehen | Offen | -| 1 | Italien-Abweichung klaeren: Berechnungsart, Deduplizierung, Intercompany | Teilweise geklaert; Finance-Leiter bestaetigte Methode, Restdifferenz dokumentiert | -| 1 | Italien IC-Diagnose besprechen: Trafag, Magnetic Sense/Magnets Sense und Gesellschaft fuer Sensorik erklaeren einen grossen Teil, aber nicht die ganze Abweichung | Historisch; neue IT-Methode verwendet `CustomerName` Trafag Italia und Dublettenregel | -| 1 | Deutschland: finalen Jahresfile 2025 beschaffen | Erledigt technisch; DE Alphaplan ist eingebaut, Fachabgrenzung Kundenlaender bleibt offen | -| 2 | UK/England: Jahresvollstaendigkeit und Restdifferenz pruefen | Teilweise erledigt; UK ist Sage/Manual Excel, Mapping korrigiert, Restdifferenz klein/offen | -| 2 | CH/AT: Sollzuordnung und Trennung final bestaetigen | Offen | -| 2 | Spanien und Oesterreich: kleinere Differenzen klaeren | Offen | -| 2 | Intercompany-/2nd-party-Kundenliste final definieren | Offen | -| 3 | Budgetkurse je Jahr als Quelle festlegen | Offen | -| 3 | Dashboard-Sicht fuer CFO: nur Laender mit Abweichung und Handlungsbedarf anzeigen | In Arbeit; Finance Summary und Soll/Ist Sicht vorhanden | -| 3 | Detailansicht je Land mit Berechnungsart und Pruefspur behalten | In Arbeit; Rohdaten-/Diagnosereiter bleibt erhalten | -| 3 | Freigabe-/Berechtigungskonzept fuer Intranet-Dashboard klaeren | Offen | - -## Naechster Termin - -Ziel im Termin: -- Deutschland und Spanien muss finales Excel schicken (Rohali 2 mal nachgehakt warte auf finales File) -- Grundlogik bestaetigen: Hauswaehrung, Nettofakturawert, Buchungsdatum, Berechnung pro Belegposition. -- Offene Laenderabweichungen priorisieren. -- Pro Land festlegen, welche Datenquelle und Berechnungslogik final gilt. - -## IT / Intercompany Diagnose - -Aktuelle Diagnose fuer Italien: - -| Kennzahl | Wert | -| --- | ---: | -| IT Ist vor IC-Abzug | 14.704.336,29 EUR | -| Rhino/check.xlsx Soll | 7.669.840,00 EUR | -| Abweichung vor IC | +7.034.496,29 EUR | -| Erkannter IC-/2nd-party-Abzug | 4.397.746,90 EUR | -| IT Ist exkl. IC | 10.306.589,39 EUR | -| Restabweichung nach IC | +2.636.749,39 EUR | - -Verwendete IC-/2nd-party-Marker: - -- `TRAFAG` -- `MAGNETIC SENSE` -- `MAGNETS SENSE` -- `GESELLSCHAFT FUER SENSORIK` -- `GESELLSCHAFT FUR SENSORIK` - -Bewertung: - -- Intercompany/2nd-party erklaert einen grossen Teil der IT-Abweichung. -- Die Summe passt dadurch deutlich besser, aber noch nicht vollstaendig. -- Restabweichung weiter pruefen: Summenlogik, Beleg/Position-Deduplizierung, Gutschriften/Storno und weitere lokale IC-Kunden oder Schreibweisen. diff --git a/TrafagSalesExporter/docs/FINANCE_ES_MAIL_ABWEICHUNG_2026-05-15.md b/TrafagSalesExporter/docs/FINANCE_ES_MAIL_ABWEICHUNG_2026-05-15.md index 52e09ea..041d6d4 100644 --- a/TrafagSalesExporter/docs/FINANCE_ES_MAIL_ABWEICHUNG_2026-05-15.md +++ b/TrafagSalesExporter/docs/FINANCE_ES_MAIL_ABWEICHUNG_2026-05-15.md @@ -1,36 +1,13 @@ -# Email an Spanien: Abweichung Net Sales 2025 +# Finance ES Mail Abweichung -**Asunto:** Revision diferencia Net Sales 2025 - Espana +Stand: 2026-05-27 -Hola, +Historischer Mailentwurf, fuer RAG komprimiert. -En la reconciliacion de Net Sales 2025 para Espana hemos identificado una diferencia pendiente de aclarar contra el valor de referencia de Rhino / `check.xlsx`. +Aktueller Spanien-/Finance-Kontext steht in `docs/rag/FINANCE.md`. -Resumen: +Volltext bei Bedarf: -- Actual Espana: `3.082.320,18 EUR` -- Referencia Rhino: `3.102.333,61 EUR` -- Diferencia: `-20.013,43 EUR` - -La diferencia no parece muy grande, pero antes de cerrar el dato necesitamos confirmar la causa. - -Por favor, podeis revisar los siguientes puntos? - -1. Periodo incluido en el fichero - Confirmar que el fichero `Spain_Sales_2025.csv` contiene todo el ano 2025 completo. - -2. Series incluidas - Confirmar que las series `REG`, `LAT`, `PRO` y `REC` deben incluirse en el calculo de Net Sales 2025. - -3. Abonos / Credit Notes - Confirmar que los abonos estan incluidos correctamente y con signo negativo. - -4. Criterio de fecha - Confirmar que fecha debe utilizarse para la delimitacion del ano 2025: fecha de factura, fecha contable u otra fecha. - -5. Importe correcto - Confirmar si el campo utilizado como importe neto de ventas es el correcto para comparar contra Rhino / `check.xlsx`. - -Objetivo: aclarar si la diferencia de `-20.013,43 EUR` se explica por periodo, series, abonos o por el campo de importe utilizado. - -Gracias y saludos, +```text +docs/raw_md_archive/HISTORY_CANONICAL.md.raw +``` diff --git a/TrafagSalesExporter/docs/FINANCE_HANDOFF_2026-05-18.md b/TrafagSalesExporter/docs/FINANCE_HANDOFF_2026-05-18.md index 8895684..c333f30 100644 --- a/TrafagSalesExporter/docs/FINANCE_HANDOFF_2026-05-18.md +++ b/TrafagSalesExporter/docs/FINANCE_HANDOFF_2026-05-18.md @@ -1,386 +1,21 @@ -# Finance Handoff 2026-05-18 +# Finance Handoff -Dieses Dokument fasst den aktuellen Stand der Finance-Abstimmung zusammen, damit die Arbeit ohne Wissensverlust fortgesetzt werden kann. +Stand: 2026-05-27 -## Aktueller Stand +Diese Datei ist fuer tokenarme RAG-Nutzung komprimiert. -Testprogramm: +## Aktueller Kurzstand + +- Fuehrende Finance-Kurzdatei: `docs/rag/FINANCE.md`. +- Manual-Import-Kontext: `docs/rag/MANUAL_IMPORT.md`. +- Aktuelle Finance-Regeln im Detail: `docs/FINANCE_ENTSCHEIDE.md` und `docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md`. + +## Volltext Bei Bedarf + +Die Detailhistorie liegt hier: ```text -http://127.0.0.1:5099/finance +docs/raw_md_archive/HISTORY_CANONICAL.md.raw ``` -Die App laeuft lokal auf `127.0.0.1:5099`. Der letzte Check der Seite ergab HTTP `200`. - -Aktuelle Excel: - -```text -docs/FINANCE_AMPEL_LAENDER_2026-05-18_21-27.xlsx -``` - -Aktuelle Cache-Dateien: - -```text -docs/it_cache_2025.csv -docs/spain_cache_2025.csv -``` - -## Nachtrag 2026-05-19 - -Nach diesem Handoff wurden noch vier relevante Schritte umgesetzt und committed: - -1. Haupt-App-Finance-Vergleich an FinanceProbe angeglichen. -2. Leere Ist-Zeilen ohne belastbaren Ist-Wert aus dem Finance-Vergleich gefiltert. -3. Berechnungsformeln je Land dokumentiert. -4. Finance Cockpit mit separatem Login technisch geschuetzt; fachliche/produktive Abnahme noch offen. - -Wichtige neue Doku: - -```text -docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md -``` - -Diese Datei beschreibt die aktuell verwendete Soll/Ist-Logik fuer `/finance-cockpit/vergleich` und `/finance`, inklusive Jahresfilter, Kandidatenberechnung, Deduplizierung, bevorzugter Ist-Variante und landesspezifischer Quellen/Formeln. - -Neue Finance-Cockpit-Sperre, Stand technisch: - -- `FinanceCockpitAccessService` -- `FinanceCockpitAccessOptions` -- `FinanceCockpitUnlockPanel` -- Konfiguration in `appsettings.json` unter `FinanceCockpitAccess` -- DI-Registrierung in `Program.cs` -- Route-/Navigation-Schutz in `Routes.razor` und `NavMenu.razor` - -Wichtig: Der HR-KPI-Login bleibt separat. Die neue Sperre betrifft das Finance Cockpit und laeuft wie HR-KPI ueber Benutzername plus SHA-256-Passwort-Hash. Finance hat ein eigenes Passwort: - -```text -Benutzer: finance -Passwort: Trafag-Finance-Cockpit-2026! -``` - -AD-/Rollenpruefung ist fuer den Moment nicht geloescht, sondern in `appsettings.json` mit `Security.Enabled = false` deaktiviert. Die vorhandenen `AccessGroups` und `AdminGroups` bleiben in der Konfiguration stehen und koennen spaeter wieder aktiviert werden. Die Finance-Sperre bleibt davon unabhaengig aktiv. - -### Zentrale Excel fuer CFO-/Finance-Filter - -Die zentrale Datei `Sales_All_yyyy-MM-dd.xlsx` enthaelt am rechten Ende einen zusammengehoerigen Finance-Spaltenblock: - -```text -Finance | Year -Finance | Country Key -Finance | Date -Finance | Net Sales Actual -Finance | Currency -Finance | Include -Finance | Source Value Field -``` - -Zusaetzlich wird nur in der zentralen Datei ein Hilfsblatt erzeugt: - -```text -Finance Filter Hilfe -``` - -Damit soll Finance dieselben Ist-Summen aus Excel filtern koennen wie im Testprogramm bzw. auf `/finance-cockpit/vergleich`. - -Vorgehen im Excel: - -1. `Finance | Year` auf das gewuenschte Jahr filtern, z. B. `2025`. -2. `Finance | Country Key` auf Land filtern, z. B. `IT`, `UK`, `ES`, `AT`. -3. `Finance | Include = TRUE` filtern. -4. `Finance | Net Sales Actual` summieren. - -Gepruefter Vergleich gegen `FinanceReconciliationService` fuer 2025: - -| Key | Finance-Service | Excel-Finance-Spalten | Differenz | -| --- | ---: | ---: | ---: | -| AT | `3'438'121.37` | `3'438'121.37` | `0.00` | -| CH | `43'521'390.82` | `43'521'390.82` | `0.00` | -| ES | `3'082'320.18` | `3'082'320.18` | `0.00` | -| FR | `1'471'218.44` | `1'471'218.44` | `0.00` | -| IN | `750'936'591.38` | `750'936'591.38` | `0.00` | -| IT | `7'669'641.47` | `7'669'641.47` | `0.00` | -| UK | `3'533'710.09` | `3'533'710.09` | `0.00` | -| US | `3'749'865.33` | `3'749'865.33` | `0.00` | - -Hinweis: Fuer AT/CH waehlt der Finance-Service intern `Nettofakturawert Hauswaehrung pro Position`; in den aktuellen Daten ist dieser Wert identisch mit `SalesPriceValue`, daher stimmen die Excel-Finance-Spalten exakt. - -## Aktuelle Soll/Ist-Werte - -| Land | Ist | Soll | Differenz | Waehrung | Status | -| --- | ---: | ---: | ---: | --- | --- | -| FR | `1'471'218.44` | `1'471'218.00` | `0.44` | EUR | OK | -| IN | `750'936'591.38` | `750'936'591.00` | `0.38` | INR | OK | -| US | `3'749'865.33` | `3'749'865.00` | `0.33` | USD | OK | -| IT | `7'669'641.47` | `7'669'840.00` | `-198.53` | EUR | Fast passend, Filter fachlich bestaetigen | -| UK | `3'533'710.09` | `3'538'972.00` | `-5'261.91` | GBP | Kleine Restdifferenz | -| AT | `3'438'121.37` | `3'443'863.00` | `-5'741.63` | EUR | Kleine Restdifferenz | -| ES | `3'082'320.18` | `3'102'333.61` | `-20'013.43` | EUR | Groesste Restdifferenz | - -Prioritaet fuer Folgearbeit: - -1. ES pruefen: vermutlich Zuschlaege/Fracht/Nebenkosten/Rhino-Auswertungslogik. -2. AT und UK Restdifferenzen klaeren. -3. IT fachlich bestaetigen, weil der aktuelle Filter noch provisorisch ist. - -## Grundregeln - -- Net Sales Actuals werden in der Hauswaehrung des Landes verglichen. -- CHF ist nur Kontroll-/Reporting-Sicht ueber Budgetkurse, nicht Standardvergleich. -- Fuehrend ist Netto ohne VAT/MwSt. -- Gutschriften/Credit Notes muessen negativ in die Summe laufen. -- Standard-Ist bleibt inklusive Intercompany; IC/2nd-party wird separat gezeigt, ausser ein Land hat fachlich bestaetigte Ausschluesse. -- Jahresabgrenzung: bevorzugt Buchungsdatum/PostingDate. Wenn Quelle kein PostingDate liefert: InvoiceDate, danach ExtractionDate. - -## Italien - -Quelle: - -- `BI1` / SAP B1 via HANA -- TSC `TRIT` -- Schema `it01_p` - -Wichtige Erkenntnisse: - -- Italien ist B1, nicht Sage. -- Frankreich und Italien kommen beide aus BI1/B1; FR passt mit `SalesPriceValue`. -- Screenshot `italien.png` zeigte fuer Italien die relevante B1-/Finance-Sicht auf Konto: - -```text -47005 - Ricavi vendite e prestazioni -``` - -Aktueller technischer Arbeitsfilter in `Services/HanaQueryService.cs` fuer `it01_p`: - -```sql -AcctCode LIKE '47005%' -AcctCode NOT LIKE '4700504%' -CardCode NOT IN ( - 'C_IT01_0022987', - 'C_IT01_0306928', - 'C_IT01_0306138', - 'C_IT01_0309653', - 'C_IT01_0304885', - 'C_IT01_0306475' -) -``` - -Aus Cache berechnete Herleitung: - -```text -10'603'550.59 - 2'933'909.12 = 7'669'641.47 EUR -Soll/Rhino = 7'669'840.00 EUR -Differenz = -198.53 EUR -``` - -Die sechs provisorisch ausgeschlossenen Kunden: - -| Kunde | Betrag | -| --- | ---: | -| FAIVELEY TRANSPORT ITALIA S.P.A. | `1'689'857.70` | -| SYSTEM CERAMICS S.P.A. | `323'409.00` | -| WABTEC MZT | `282'647.40` | -| FINCANTIERI NEXTECH S.P.A | `268'166.37` | -| METAL WORK SERVICE S.R.L. | `203'425.15` | -| ELEMASTER S.P.A. | `166'403.50` | - -Wichtig: Dieser IT-Filter ist ein Arbeits-/Prueffilter, noch nicht fachlich final bestaetigt. - -Nachtrag 2026-05-20: - -- Finance-Leiter bestaetigt als fachliche Methode: `Trafag Italia` aus dem externen IT-Finance-Ist ausschliessen. -- Identische IT-Zeilen mit leerem `Supplier country` nur einmal zaehlen. -- Die alte Kundenausschluss-Kombination bleibt als 2025-Analyse dokumentiert, ist aber nicht die fuehrende Methode fuer Folgejahre. - -Detaildokument: - -```text -docs/FINANCE_IT_VORGEHEN_2026-05-18.md -``` - -## UK - -Quelle: - -- Fachlich Sage, nicht SAP B1. -- TSC `TRUK`. -- App-Anschluss: `MANUAL_EXCEL`. -- SharePoint-Ordner heisst technisch `Import/Finance/UK_B1`, aber das bedeutet nicht B1. - -Aktuelle Berechnung: - -```text -SageNetSales([Sales Price/Value], [Quantity], [Document Type], [DocumentType], [Type]) -``` - -Bedeutung: - -- `Sales Price/Value * Quantity` -- Credit Notes werden bei erkennbarem Sage-Typ negativ erzwungen. -- Waehrung ist GBP. - -Wichtige Korrektur: - -- UK wird gegen Local Currency/GBP geprueft. -- Der fruehere `CheckValue 3'749'865.00` war fuer UK falsch und wurde entfernt. -- Korrektes Soll fuer UK ist `LocalCurrencyValue = 3'538'972.00 GBP`. - -Aktueller Stand: - -```text -Ist = 3'533'710.09 GBP -Soll = 3'538'972.00 GBP -Differenz = -5'261.91 GBP -``` - -Detaildokument: - -```text -docs/FINANCE_UK_QUELLE_KORREKTUR_2026-05-18.md -``` - -## Spanien - -Quelle: - -- Sage CSV -- TSC `TRES` -- Datei: `sageSpain/v2/Spain_Sales_2025.csv` -- Cache: `docs/spain_cache_2025.csv` - -Berechnung: - -- `SalesPriceValue` aus `LineasAlbaranCliente.ImporteNeto` -- Credit Notes/REC negativ -- Datumsbasis: `FechaFactura` -- Waehrung: EUR - -Aktuelle Zerlegung: - -```text -Zeilen = 4'341 -Invoice = 3'140'921.50 EUR -Credit Notes = -58'601.32 EUR -Ist = 3'082'320.18 EUR -Soll/Rhino = 3'102'333.61 EUR -Differenz = -20'013.43 EUR -``` - -Nach Serie: - -| Serie | Zeilen | Betrag | -| --- | ---: | ---: | -| REG | `3'079` | `2'407'451.30` | -| LAT | `1'118` | `480'199.20` | -| PRO | `43` | `253'271.00` | -| REC | `101` | `-58'601.32` | - -Bewertung: - -- Differenz ist ca. `0.65%`. -- Gutschriften sind nicht das Problem, sie sind bereits negativ. -- Wahrscheinlich fehlen oder unterscheiden sich kleinere Sage-/Rhino-Bestandteile: Fracht, Portes, Zuschlaege, Rundungen, Versicherung, Finanzierung, nicht-artikelbezogene Belegpositionen oder eine andere Sage-Auswertung. -- Nicht einfach auf Belegkopf `DocumentNetAmount` wechseln: deduplizierter Belegkopf liegt bei `2'907'901.79` und passt schlechter. - -## Geaenderte Programmteile - -Wichtige Dateien: - -```text -Services/HanaQueryService.cs -Services/ManualExcelImportService.cs -Services/DatabaseSeedService.cs -scripts/Export-SageSpainSalesCsv.ps1 -SageSpainFinalExportPackage/Export-SageSpainSalesCsv.ps1 -TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs -``` - -Wichtige technische Aenderungen: - -- IT: provisorischer B1-Konto-/Kundenausschlussfilter fuer `it01_p`. -- UK: `SageNetSales(...)` im Manual-Excel-Importer. -- UK: `FinanceReference` nutzt fuer UK nur `LocalCurrencyValue = 3'538'972`, kein `CheckValue`. -- ES: Sage-Spain-SQL erzwingt Credit Notes mit `-ABS(...)`. -- Test ergaenzt, der positive Credit-Note-Rohbetraege negativ macht. - -## Validierung - -Build: - -```text -dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_uk_reference\ --verbosity minimal -``` - -Ergebnis: erfolgreich. - -Tests: - -```text -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false --verbosity minimal -``` - -Ergebnis: - -```text -71/71 Tests gruen -``` - -FinanceProbe: - -```text -http://127.0.0.1:5099/finance -``` - -Ergebnis: HTTP `200`. - -## Commits - -Relevante Commits: - -| Commit | Inhalt | -| --- | --- | -| `fb85e2e` | Sage-Berechnungen korrigiert, IT/UK-Doku und Ampel ergaenzt | -| `3d40d76` | UK auf GBP Local Currency als Referenz umgestellt | -| `f721d95` | Aktuelle Excel und Spanien-Cache ergaenzt | -| `bc6bfdf` | Finance-Handoff dokumentiert | -| `8f1b1b8` | Haupt-Finance-Vergleich an Probe angeglichen | -| `f855e06` | Leere Ist-Zeilen im Finance-Vergleich gefiltert | -| `5c654ad` | Finance-Berechnungsformeln je Land dokumentiert | -| `9c544af` | Finance Cockpit mit Login technisch geschuetzt | -| `ebbc5a1` | Finance-Filterspalten in zentrale Excel ergaenzt | -| `b23f73e` | Finance-Hilfsblatt in zentrale Excel ergaenzt | - -Dieses Handoff wurde danach als weiterer Commit hinzugefuegt. - -## Nicht aufraeumen ohne Ruecksprache - -Es gibt noch untracked/temporaere Arbeitsdateien und alte Word-/Excel-Backups. Diese wurden bewusst nicht committed, weil sie entweder temporär, defekt, Logdateien oder Zwischenstaende sind. - -Bekannt uncommitted: - -```text -.tmp_tools/ -Tools/FinanceProbe/.tmp_tools/ -verify_probe_out*/ -financeprobe.*.log -docs/CFO_Kurzbericht_270515.docx -docs/CFO_Kurzbericht_270515*.bak.docx -docs/CFO_Kurzbericht_270515_NEU*.docx -docs/FINANCE_AMPEL_LAENDER_2026-05-18.xlsx -docs/FINANCE_AMPEL_LAENDER_2026-05-18_20-32.xlsx -docs/FINANCE_AMPEL_LAENDER_2026-05-19.xlsx -docs/it_cache_2025.csv -italien.png -financeprobe.*.log -mainapp.*.log -``` - -Wenn weitergearbeitet wird, zuerst `git status --short` pruefen und keine fremden/alten Dateien blind loeschen. - -## Naechste sinnvolle Schritte - -1. ES: Sage-/Rhino-Unterschied von `20'013.43 EUR` gegen Fracht/Zuschlaege/Nebenkosten pruefen. -2. AT: Differenz `-5'741.63 EUR` analysieren. -3. UK: Restdifferenz `-5'261.91 GBP` klaeren, aber UK ist jetzt nahe am LC-Soll. -4. IT: provisorischen Kundenausschluss fachlich bestaetigen oder durch offizielle B1/Rhino-Filterregel ersetzen. -5. AD-/Rollenpruefung spaeter wieder aktivieren, sobald geklaert ist, welche Gruppen produktiv gelten. Dazu `Security.Enabled` wieder auf `true` setzen; Gruppen sind nicht geloescht. -6. `/finance-cockpit/vergleich` und `/finance` nebeneinander pruefen, wenn neue Daten geladen wurden; beide sollen dieselbe `FinanceReconciliationService`-Logik nutzen. +Nur laden, wenn der Zwischenstand vom 2026-05-18 oder alte Finance-Abweichungen genau nachvollzogen werden muessen. diff --git a/TrafagSalesExporter/docs/FINANCE_IT_MAIL_ABWEICHUNG_2026-05-15.md b/TrafagSalesExporter/docs/FINANCE_IT_MAIL_ABWEICHUNG_2026-05-15.md index c7b7694..7f89bde 100644 --- a/TrafagSalesExporter/docs/FINANCE_IT_MAIL_ABWEICHUNG_2026-05-15.md +++ b/TrafagSalesExporter/docs/FINANCE_IT_MAIL_ABWEICHUNG_2026-05-15.md @@ -1,39 +1,13 @@ -# Email an Italien: Abweichung Net Sales 2025 +# Finance IT Mail Abweichung -**Oggetto:** Verifica differenza Net Sales 2025 - Italia +Stand: 2026-05-27 -Ciao, +Historischer Mailentwurf, fuer RAG komprimiert. -nella riconciliazione dei Net Sales 2025 per l'Italia abbiamo identificato una differenza significativa rispetto al valore di riferimento Rhino / `check.xlsx`. +Aktueller Italien-/Finance-Kontext steht in `docs/rag/FINANCE.md`. -Riepilogo: +Volltext bei Bedarf: -- Actual Italia: `14.704.336,29 EUR` -- Riferimento Rhino: `7.669.840,00 EUR` -- Differenza: `+7.034.496,29 EUR` - -La differenza e molto rilevante. Prima di chiudere il dato dobbiamo confermare quale logica di calcolo e corretta per l'Italia. - -Potete per favore verificare i seguenti punti? - -1. Base di calcolo corretta - Confermare quale valore deve essere usato per i Net Sales 2025: valore netto per riga/posizione, totale documento deduplicato oppure un'altra logica. - -2. Totali documento vs. posizioni - Verificare se i totali documento sono ripetuti su piu righe e quindi devono essere conteggiati una sola volta per documento. - -3. Intercompany / 2nd-party - Confermare quali clienti o transazioni devono essere esclusi come Intercompany o 2nd-party. - -4. Note di credito / Credit Notes - Confermare che le note di credito sono incluse correttamente e con segno negativo. - -5. Criterio data - Confermare quale data deve essere utilizzata per delimitare il 2025: data registrazione, data fattura o altra data. - -6. Valuta - Confermare che la valuta di confronto per l'Italia e `EUR`. - -Obiettivo: capire se la differenza di `+7.034.496,29 EUR` deriva da doppio conteggio dei documenti, trattamento Intercompany, criteri data o dal campo importo utilizzato. - -Grazie e saluti, +```text +docs/raw_md_archive/HISTORY_CANONICAL.md.raw +``` diff --git a/TrafagSalesExporter/docs/FINANCE_UK_MAIL_ABWEICHUNG_2026-05-15.md b/TrafagSalesExporter/docs/FINANCE_UK_MAIL_ABWEICHUNG_2026-05-15.md index 6463604..59a1a12 100644 --- a/TrafagSalesExporter/docs/FINANCE_UK_MAIL_ABWEICHUNG_2026-05-15.md +++ b/TrafagSalesExporter/docs/FINANCE_UK_MAIL_ABWEICHUNG_2026-05-15.md @@ -1,45 +1,13 @@ -# Email an UK / England: Abweichung Net Sales 2025 +# Finance UK Mail Abweichung -**Subject:** Review difference Net Sales 2025 - UK +Stand: 2026-05-27 -Hi, +Historischer Mailentwurf, fuer RAG komprimiert. -In the Net Sales 2025 reconciliation for UK / England, we identified a difference against the Rhino / `check.xlsx` reference value. +Aktueller UK-/Finance-Kontext steht in `docs/rag/FINANCE.md` und `docs/rag/MANUAL_IMPORT.md`. -Summary: +Volltext bei Bedarf: -- Actual UK: `3,533,710.09 GBP` -- Rhino reference: `3,749,865.00 GBP` -- Reference UK LC/GBP: `3,538,972.00 GBP` -- Difference: `-5,261.91 GBP` - -The mapping has already been reviewed technically, but we still need to clarify the remaining difference before closing the 2025 value. - -Important clarification: UK / England is treated as a Sage source. The current SharePoint folder name `UK_B1` is only a technical folder/source reference and does not mean that UK is read from SAP Business One. - -Could you please check the following points? - -1. Full-year completeness - Confirm that the UK source file/import contains the full year 2025 and not only a partial period. - -2. Period included - We currently see data from approximately `03.01.2025` to `22.12.2025`. Please confirm whether this is complete for 2025 or if transactions outside this range are missing. - -3. Credit notes - Confirm that credit notes are included correctly and with the correct negative sign. - -4. Net sales field - Confirm which column should be used as the net sales amount for comparison with Rhino / `check.xlsx`. - -5. Discounts, freight or additional charges - Please check whether discounts, freight, additional charges or other adjustments are included in the Rhino reference but not in the current import value, or vice versa. - -6. 2nd-party / 3rd-party / Intercompany - Confirm whether any customers or transactions should be excluded from the Net Sales 2025 value. - -7. Currency - Confirm that the correct comparison currency for UK is `GBP`. - -Goal: clarify whether the difference of `-216,154.91 GBP` is caused by an incomplete period, credit notes, a different net sales field, adjustments, or 2nd-party/3rd-party handling. - -Thanks and best regards, +```text +docs/raw_md_archive/HISTORY_CANONICAL.md.raw +``` diff --git a/TrafagSalesExporter/docs/FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md b/TrafagSalesExporter/docs/FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md index 1f02129..d3df86b 100644 --- a/TrafagSalesExporter/docs/FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md +++ b/TrafagSalesExporter/docs/FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md @@ -1,75 +1,14 @@ -# Finance: Welches Dokument gilt? +# Finance: Welches Dokument Gilt? -Stand: 2026-05-20 +Stand: 2026-05-27 -## Aktueller Nachtrag 2026-05-20 +Historische Dokumentgueltigkeitsnotiz, fuer RAG komprimiert. -Zum alten CFO-/Finance-Termin-Dokument ist eine neue Anwenderdoku fuer das Cockpit hinzugekommen: +Aktueller Dokumentrouter: `docs/RAG_ROUTER.md`. +Aktueller Dokumentstatus: `docs/MD_DOKUMENTENSTATUS_2026-05-20.md`. + +Volltext bei Bedarf: ```text -docs/FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx +docs/raw_md_archive/HISTORY_CANONICAL.md.raw ``` - -Diese neue Word-Datei ist die bessere Anleitung fuer Finance-Anwender im Cockpit. Das CFO-Dokument vom 2026-05-15 bleibt historische Termin-/Entscheidgrundlage. - -Technisch/fachlich aktuell fuehrend: - -- `Management Analyse` Reiter `Finance Summary` -- zentrale Excel `Finance Summary` -- `FinanceRuleEngine` -- `docs/FINANCE_ENTSCHEIDE.md` -- `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` - -## Fuehrendes Dokument - -Fuer den CFO-/Finance-Termin vom 2026-05-15 galt: - -```text -docs/FINANCE_CHEF_SUMMARY_2026-05-15.docx -``` - -Dieses Dokument ist die aktuellste CFO-Kurzfassung mit Ampel, Laendertabelle, Pruefquellen, Prioritaeten und empfohlenen Massnahmen. - -## Geloeschte alte Fassung - -Die alte Fassung `docs/FINANCE_CHEF_SUMMARY_2026-05-13.docx` wurde entfernt, weil sie durch die Version vom 2026-05-15 ersetzt ist. - -## Entscheidbasis - -Die fachlichen Entscheide stehen separat hier: - -```text -entscheide.md -docs/FINANCE_ENTSCHEIDE.md -``` - -Kurzfassung der wichtigsten Entscheide: - -| Thema | Entscheid | -| --- | --- | -| Fuehrende Waehrung | Hauswaehrung je Land | -| CHF-Sicht | Nur separat mit Budgetkursen | -| Aggregation | Pro Artikel bzw. Belegposition | -| Wertbasis | Nettofakturawert | -| Jahresabgrenzung 2025 | Buchungsdatum | -| Gutschriften / Storno | Separat ausweisen, positionsbasiert behandeln | -| Intercompany / 2nd-party | Separat klassifizieren und als Auswahl/Sicht fuehren | -| Indien | INR ist fuehrend | -| Italien | Hauswaehrung, Intercompany separat pruefen | - -## Wichtig fuer Rueckfragen - -Falls im Termin gefragt wird, ob die Berechnungslogik schon entschieden ist: - -> Ja. Die Grundlogik ist entschieden: Hauswaehrung, Nettofakturawert, Buchungsdatum und Berechnung pro Belegposition. Offen sind vor allem Datenvollstaendigkeit, Intercompany-Abgrenzung, Budgetkursquelle und die fachliche Freigabe einzelner Laenderabweichungen. - -## Was noch nicht final ist - -| Thema | Status | -| --- | --- | -| IT | Kritisch; grosse Abweichung, Berechnungsart/IC/Deduplizierung pruefen | -| UK / EN | Hoch; Restdifferenz und Jahresvollstaendigkeit pruefen | -| DE | Hoch; finaler Jahresfile fehlt, Sample nicht verwenden | -| CH / AT | Hoch; Sollzuordnung und Trennung finalisieren | -| ES / AT | Mittel; kleinere Differenzen klaeren | -| FR / IN / US | Rechnerisch freigabefaehig | diff --git a/TrafagSalesExporter/docs/MD_DOKUMENTENSTATUS_2026-05-20.md b/TrafagSalesExporter/docs/MD_DOKUMENTENSTATUS_2026-05-20.md index db2a335..38e2758 100644 --- a/TrafagSalesExporter/docs/MD_DOKUMENTENSTATUS_2026-05-20.md +++ b/TrafagSalesExporter/docs/MD_DOKUMENTENSTATUS_2026-05-20.md @@ -2,6 +2,8 @@ Stand: 2026-05-20 +RAG-Hinweis: Fuer tokenarme Kontextauswahl zuerst `docs/RAG_ROUTER.md` laden. Standardmaessig nur die Kurzdateien unter `docs/rag/` laden; diese Datei und andere Original-MDs nur bei Detail-/Auditbedarf. + Diese Datei ordnet die vorhandenen Markdown-Dateien ein. Ziel ist, alte Arbeitsnotizen nicht mit dem aktuellen Produktstand zu verwechseln. ## Aktuell fuehrend diff --git a/TrafagSalesExporter/docs/RAG_ROUTER.md b/TrafagSalesExporter/docs/RAG_ROUTER.md new file mode 100644 index 0000000..1be2e13 --- /dev/null +++ b/TrafagSalesExporter/docs/RAG_ROUTER.md @@ -0,0 +1,52 @@ +# RAG Router + +Stand: 2026-05-27 + +Zweck: Diese Datei zuerst laden. Danach nur die Dateien aus dem passenden Themenblock laden. + +## Lade-Regel + +1. Immer nur diese Router-Datei zuerst lesen. +2. Thema bestimmen. +3. Zuerst nur die passende Kurzdatei aus `docs/rag/` laden. +4. Rohquellen nur laden, wenn Details, alte Zahlen, Codepfade, Mailtexte oder Audit gefragt sind. + +## Themen + +| Thema | Wann laden | Standard laden | +| --- | --- | --- | +| Aktueller Stand | Projektstatus, letzte Aenderungen, offene Punkte | `docs/rag/PROJECT.md` | +| Finance Cockpit | Soll/Ist, Finance Summary, Regeln, Laenderlogik | `docs/rag/FINANCE.md` | +| Finance Spezialfaelle | IT, UK, ES, Abweichungen | `docs/rag/FINANCE.md` | +| Manual Import | UK-Deltas, ES/DE Vollfiles, Importprozess | `docs/rag/MANUAL_IMPORT.md` | +| HR KPI | HR Dashboard, Formeln, Datenqualitaet, Anwenderstand | `docs/rag/HR_KPI.md` | +| Deployment/IIS | Publish, Server, BiDashboard, TLS, lokaler Uebergang | `docs/rag/DEPLOYMENT.md` | +| Admin/Startseite | Admin Login, Sessions, Landing Page | `docs/rag/ADMIN.md` | +| Architektur | Systemuebersicht, Diagramme, technische Einordnung | `docs/rag/ARCHITECTURE.md` | + +## Rohquellen Nur Bei Bedarf + +| Datei | Nur laden fuer | +| --- | --- | +| `docs/raw_md_archive/HISTORY_CANONICAL.md.raw` | kanonische Detailhistorie mit Quellenangaben | +| `docs/raw_md_archive/original_history_raws.zip` | exakte Originaldateien nur zur Wiederherstellung, nicht fuer RAG laden | +| `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` | Einordnung alter Dokumente | +| `docs/FINANCE_ENTSCHEIDE.md` | Finance-Entscheide im Detail | +| `docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md` | Formeln pro Land | +| `docs/MANUAL_IMPORT_DELTA_STAND_2026-05-21.md` | Manual-Import-Details | +| `docs/HR_KPI_NACHDOKU_2026-05-13.md` | HR-KPI-Details | +| `docs/DEPLOYMENT_IIS_HANDOFF_2026-05-19.md` | IIS-/Publish-Details | +| `docs/LOCAL_DEV_SERVER_UEBERGANG_2026-05-21.md` | lokaler Server im Detail | +| `docs/ADMIN_BEREICH_STARTSEITE_2026-05-21.md` | Admin-/Landing-Details | + +## Suchwoerter + +| Suchwort | Thema | +| --- | --- | +| `Finance Summary`, `Soll/Ist`, `check.xlsx`, `FinanceRuleEngine` | Finance Cockpit | +| `TRUK`, `UK_B1`, `Delta`, `Manual Excel` | Manual Import / Finance Spezialfaelle | +| `TRDE`, `Alphaplan`, `NettoPreisGesamtX` | Finance Cockpit / Manual Import | +| `TRSE`, `Spain`, `Sage`, `ImporteNeto` | Finance Spezialfaelle | +| `HR KPI`, `Rexx`, `Austritte`, `Absenzen` | HR KPI | +| `IIS`, `BiDashboard`, `Publish`, `TLS`, `Client certificate` | Deployment/IIS | +| `Admin Bereich`, `AdminAccess`, `LandingPage` | Admin/Startseite | diff --git a/TrafagSalesExporter/docs/rag/ADMIN.md b/TrafagSalesExporter/docs/rag/ADMIN.md new file mode 100644 index 0000000..6c9f376 --- /dev/null +++ b/TrafagSalesExporter/docs/rag/ADMIN.md @@ -0,0 +1,22 @@ +# RAG Admin + +Stand: 2026-05-27 + +## Kurzstand + +- Admin Bereich ist eigener Hauptmenuepunkt, nicht unter Finance. +- Route: `/admin/sessions`. +- Schutz: eigener App-interner Admin-Login ueber `AdminAccess`. +- Admin-Login ist unabhaengig vom Finance-Cockpit-Passwort. +- Admin Bereich darf nicht durch Finance-Cockpit-Login blockiert werden. + +## Startseite + +- Route `/` ist neutral und verlangt keinen Finance-Login. +- Landing Page nutzt Trafag-nahe Schrift, Manometer und optionales Strichmaennchen. +- Schalter fuer Strichmaennchen liegt im Admin Bereich. + +## Rohquellen Nur Bei Bedarf + +- Detaildoku: `docs/ADMIN_BEREICH_STARTSEITE_2026-05-21.md` + diff --git a/TrafagSalesExporter/docs/rag/ARCHITECTURE.md b/TrafagSalesExporter/docs/rag/ARCHITECTURE.md new file mode 100644 index 0000000..93330b2 --- /dev/null +++ b/TrafagSalesExporter/docs/rag/ARCHITECTURE.md @@ -0,0 +1,15 @@ +# RAG Architecture + +Stand: 2026-05-27 + +## Kurzstand + +- App sammelt Daten aus SAP OData, HANA/SAP B1, SharePoint und manuellen Excel-/CSV-Quellen. +- Zentrale Persistenz ueber `CentralSalesRecords`. +- Finance-Auswertung und zentrale Excel sollen dieselbe Regelengine verwenden. +- Diagramme und Anwenderdokus existieren fuer Keyuser-Prozess und technische Architektur. + +## Rohquellen Nur Bei Bedarf + +- Diagramme: `docs/PROGRAMM_DIAGRAMME.md` +- technischer Handoff und alter LLM-Systemkontext: `docs/raw_md_archive/HISTORY_CANONICAL.md.raw` diff --git a/TrafagSalesExporter/docs/rag/DEPLOYMENT.md b/TrafagSalesExporter/docs/rag/DEPLOYMENT.md new file mode 100644 index 0000000..f2a1141 --- /dev/null +++ b/TrafagSalesExporter/docs/rag/DEPLOYMENT.md @@ -0,0 +1,22 @@ +# RAG Deployment + +Stand: 2026-05-27 + +## Kurzstand + +- `TrafagSalesExporter` wird als ASP.NET/IIS-Webanwendung im bisherigen `BiDashboard`-Schema publiziert. +- Lokaler Uebergangsserver: `http://172.16.9.185:5000` im Trafag-Netz, IP kann wechseln. +- Lokale URLs bleiben `https://localhost:55415` und `http://localhost:55416`. +- Fuer andere PCs nutzt der Uebergang bewusst HTTP auf Port `5000`. + +## Serverproblem + +- IIS/HTTPS blockiert vor der App. +- Dokumentierter Befund: TLS fordert Client-Zertifikat. +- IT soll IIS SSL Settings pruefen: Client certificates `Ignore` oder hoechstens `Accept`, nicht `Require`. + +## Rohquellen Nur Bei Bedarf + +- IIS-Handoff: `docs/DEPLOYMENT_IIS_HANDOFF_2026-05-19.md` +- lokaler Server: `docs/LOCAL_DEV_SERVER_UEBERGANG_2026-05-21.md` + diff --git a/TrafagSalesExporter/docs/rag/FINANCE.md b/TrafagSalesExporter/docs/rag/FINANCE.md new file mode 100644 index 0000000..52ea9a3 --- /dev/null +++ b/TrafagSalesExporter/docs/rag/FINANCE.md @@ -0,0 +1,45 @@ +# RAG Finance + +Stand: 2026-05-27 + +## Kurzstand + +- Fuehrende Sicht: `Finance Summary`. +- `Finance Summary` nutzt dieselbe `FinanceRuleEngine` wie das zentrale Excel. +- `Management Analyse` bleibt Diagnose-/Plausibilitaetssicht, nicht fuehrende Finance-Zahl. +- Filter fuer Jahr, Land und Waehrung wirken auf das Finance-Endergebnis. +- Standard-Ist bleibt inklusive Positionen; Intercompany/2nd-party wird separat ausgewiesen. + +## Wichtige Regeln + +- Hauswaehrung des Landessystems ist fuehrend. +- Wertbasis ist Nettofakturawert pro Position. +- Jahresabgrenzung ueber `PostingDate`, Fallback `InvoiceDate`, danach `ExtractionDate`. +- Gutschriften/Storno laufen als negative Beleg-/Positionszeilen. +- Budget-CHF ist Kontroll-/Reporting-Kandidat, nicht Standardabgleich. + +## Offene Fachpunkte + +- DE: Finance/Munir muss bestaetigen, welche Kundenlaender/Filter zum offiziellen DE-Ist gehoeren. +- IT: Nach neuem IT-Export pruefen, ob die vollstaendige `Trafag Italia`-Summe sichtbar wird. +- ES: Differenz zu Rhino/check.xlsx bleibt fachlich zu klaeren. + +## Land-Kurzindex + +| Land | Kurzregel | +| --- | --- | +| CH/AT | SAP OData `ZSCHWEIZ`, Trennung ueber Buchungskreis/Reporting-Land | +| DE | Alphaplan Excel, `NettoPreisGesamtX`, 2025-Zwang | +| ES | Sage CSV, `ImporteNeto`, REC/Credit negativ | +| IT | Hauswaehrung, `Trafag Italia` ausgeschlossen, Duplikatlogik fuer leeres Supplier country | +| UK | Sage/Manual Excel, GBP, `[Sales Price/Value] * [Quantity]`, Credit Notes negativ | +| IN | INR als Hauswaehrung | + +## Rohquellen Nur Bei Bedarf + +- Entscheide: `docs/FINANCE_ENTSCHEIDE.md`, `entscheide.md` +- Formeln je Land: `docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md` +- IT Detail: `docs/FINANCE_IT_VORGEHEN_2026-05-18.md` +- UK Korrektur: `docs/FINANCE_UK_QUELLE_KORREKTUR_2026-05-18.md` +- ES Detail: `SAGE_SPAIN_EXPORT_2026-05-05.md` +- alter Finance-Handoff: `docs/raw_md_archive/HISTORY_CANONICAL.md.raw` diff --git a/TrafagSalesExporter/docs/rag/HR_KPI.md b/TrafagSalesExporter/docs/rag/HR_KPI.md new file mode 100644 index 0000000..63d5dac --- /dev/null +++ b/TrafagSalesExporter/docs/rag/HR_KPI.md @@ -0,0 +1,21 @@ +# RAG HR KPI + +Stand: 2026-05-27 + +## Kurzstand + +- HR KPI Cockpit wurde um produktive Cockpit-Funktionen erweitert. +- Enthalten sind Anleitung, Datenordner, Dateifrische, Datenstatus, Ampeln, Periodenvergleich, Datenqualitaet, Austritte, Absenzen, Managementsicht und Drucken/PDF. +- Managementsicht anonymisiert Personennamen in Detailtabellen. + +## Datenquellen + +- Rexx-/SAP-Dateien aus konfiguriertem Datenordner. +- Datenordner im Cockpit je Lauf anpassbar und dauerhaft ueber `HrKpi:DataFolder`. + +## Rohquellen Nur Bei Bedarf + +- Nachdoku: `docs/HR_KPI_NACHDOKU_2026-05-13.md` +- Fachpruefung: `docs/HR_KPI_PRUEFUNG_SWISS_BEST_PRACTICES.md` +- Anwenderdoku: `docs/HR_KPI_ANLEITUNG_HR_2026-05-20.docx` + diff --git a/TrafagSalesExporter/docs/rag/MANUAL_IMPORT.md b/TrafagSalesExporter/docs/rag/MANUAL_IMPORT.md new file mode 100644 index 0000000..6015609 --- /dev/null +++ b/TrafagSalesExporter/docs/rag/MANUAL_IMPORT.md @@ -0,0 +1,32 @@ +# RAG Manual Import + +Stand: 2026-05-27 + +## Kurzstand + +- Manual-Importe ersetzen pro Standort den aktuellen Stand in `CentralSalesRecords`. +- Delta-Dateien muessen zusammen mit der passenden Basisdatei gelesen werden. +- Das ist aktuell nur fuer UK vorgesehen. +- ES und DE muessen Vollfiles liefern. + +## Laender + +| Standort | Quelle | Delta | Finance-Wert | +| --- | --- | --- | --- | +| UK / `TRUK` | SharePoint `Import/Finance/UK_B1`, Sage Excel | ja | `[Sales Price/Value] * [Quantity]`, Credit Notes negativ, GBP | +| ES / `TRSE`/`TRES` | Sage CSV | nein | `ImporteNeto`, REC/Credit negativ, EUR | +| DE / `TRDE` | Alphaplan Excel | nein | `NettoPreisGesamtX`, GS negativ, Ausschlussregeln | + +## Bedienreihenfolge + +1. Datei oder Delta im richtigen Ordner bereitstellen. +2. In `Manuelle Importe` Pfad/Standort pruefen. +3. Standortexport ausfuehren. +4. Zentrale Datei neu erzeugen. +5. `Finance Summary` und `Finance Details` pruefen. + +## Rohquellen Nur Bei Bedarf + +- Detailstand: `docs/MANUAL_IMPORT_DELTA_STAND_2026-05-21.md` +- Workflow-Historie: `NEXT_STEPS_2026-04-15.md` + diff --git a/TrafagSalesExporter/docs/rag/PROJECT.md b/TrafagSalesExporter/docs/rag/PROJECT.md new file mode 100644 index 0000000..31ad7d5 --- /dev/null +++ b/TrafagSalesExporter/docs/rag/PROJECT.md @@ -0,0 +1,24 @@ +# RAG Project + +Stand: 2026-05-27 + +## Kurzstand + +- Fuehrende App: `TrafagSalesExporter`, publiziert als `BiDashboard`. +- Letzter dokumentierter Stand: Rebase/Push synchron mit `origin/main`, Head `d853f53 Add published HR KPI workflow fixes`. +- Validierung laut Doku: Build erfolgreich, Tests zuletzt `78/78` gruen. +- Fuer normale Weiterarbeit diese Datei plus den passenden Themen-RAG laden. + +## Aktive Themen + +- Finance Cockpit: `docs/rag/FINANCE.md` +- Manual Import: `docs/rag/MANUAL_IMPORT.md` +- HR KPI: `docs/rag/HR_KPI.md` +- Deployment/IIS: `docs/rag/DEPLOYMENT.md` +- Admin/Startseite: `docs/rag/ADMIN.md` + +## Rohquellen Nur Bei Bedarf + +- kanonische Detailhistorie: `docs/raw_md_archive/HISTORY_CANONICAL.md.raw` +- exakte Originaldateien zur Wiederherstellung: `docs/raw_md_archive/original_history_raws.zip` +- Dokumentstatus: `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` diff --git a/TrafagSalesExporter/docs/raw_md_archive/HISTORY_CANONICAL.md.raw b/TrafagSalesExporter/docs/raw_md_archive/HISTORY_CANONICAL.md.raw new file mode 100644 index 0000000..dd92dcb --- /dev/null +++ b/TrafagSalesExporter/docs/raw_md_archive/HISTORY_CANONICAL.md.raw @@ -0,0 +1,8359 @@ +# History Canonical + +Stand: 2026-05-27 + +Diese Datei ist die kanonische Roh-Historie fuer Detail-/Auditbedarf. +Sie wurde aus docs/raw_md_archive/*.raw erzeugt und entfernt exakt gleiche Markdown-Abschnitte nach Normalisierung von Whitespace und Stand-Zeilen. +Nicht exakt gleiche, aber fachlich aehnliche Abschnitte bleiben erhalten, damit keine Information verloren geht. + +## Quellen + +- lastchange.md.raw (84859 bytes) +- NEXT_STEPS_2026-04-15.md.raw (48631 bytes) +- HANDOFF_2026-04-15.md.raw (65523 bytes) +- LLM_SYSTEM_GUIDE.md.raw (26020 bytes) +- FINANCE_HANDOFF_2026-05-18.md.raw (12491 bytes) +- FINANCE_DASHBOARD_TODO_2026-05-15.md.raw (3242 bytes) +- FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md.raw (2519 bytes) +- FINANCE_ES_MAIL_ABWEICHUNG_2026-05-15.md.raw (1338 bytes) +- FINANCE_IT_MAIL_ABWEICHUNG_2026-05-15.md.raw (1576 bytes) +- FINANCE_UK_MAIL_ABWEICHUNG_2026-05-15.md.raw (1999 bytes) + +## Deduplizierung + +- Behaltene eindeutige Abschnitte: 323 +- Entfernte exakt doppelte Abschnitte: 0 + +## Kanonische Abschnitte + +## H1 - Last Change 2026-05-04 + +Quelle: lastchange.md.raw + +# Last Change 2026-05-04 + +## H2 - In-App-Schulungen und Finance-Detaildoku 2026-05-21 + +Quelle: lastchange.md.raw + +## In-App-Schulungen und Finance-Detaildoku 2026-05-21 + +Geaendert: + +- Neue HTML-/Razor-Schulungsseite `HR KPI Schulung` unter `/hr-kpi/schulung`. +- Neue HTML-/Razor-Schulungsseite `Finance Schulung` unter `/finance-cockpit/schulung`. +- Navigation erweitert: + - `Finance Cockpit` enthaelt jetzt `Finance Schulung`. + - `HR KPI (Login)` ist jetzt eine Gruppe mit `HR Dashboard` und `HR KPI Schulung`. +- Finance-Schulung ist wie die restlichen Finance-Seiten ueber die Finance-Cockpit-Entsperrung geschuetzt. +- Schulungsseiten enthalten Tabellen, Checklisten, Prozessablauf und eingebettete Grafiken aus `wwwroot/training`. +- Sprachtexte fuer die neuen Menuepunkte in Englisch, Spanisch, Italienisch und Hindi ergaenzt. +- Word-Schulungsdokumente fuer HR und Finance neu erzeugt und Umlaut-Schreibweisen korrigiert. +- Neue Markdown-Doku `docs/MANUAL_IMPORT_DELTA_STAND_2026-05-21.md` beschreibt den aktuellen Delta-/Vollfile-Stand: + - UK kann Basis plus Deltas lesen. + - Spanien und Deutschland muessen vollstaendige Dateien liefern. + - Manual-Importe ersetzen pro Standort den aktuellen Stand in `CentralSalesRecords`. + +Verifiziert: + +- `dotnet test TrafagSalesExporter.sln --verbosity minimal --no-restore -p:BaseOutputPath=.tmp_build\bin\ -p:BaseIntermediateOutputPath=.tmp_build\obj\` +- Normaler Debug-Build war lokal durch eine von Visual Studio/.NET Host gesperrte `bin\Debug\net8.0\BiDashboard.dll` blockiert. + +## H3 - Lokaler Uebergangsserver bis IIS-Fix 2026-05-21 + +Quelle: lastchange.md.raw + +## Lokaler Uebergangsserver bis IIS-Fix 2026-05-21 + +Zweck: + +- Falls der zentrale IIS-Server noch nicht erreichbar ist, kann die App voruebergehend auf dem Entwicklungs-PC laufen. +- Andere Mitarbeitende greifen dann im Firmennetz ueber die IP des PCs zu. +- Ausfuehrliche Betriebsdoku: `docs/LOCAL_DEV_SERVER_UEBERGANG_2026-05-21.md`. + +Start auf dem Entwicklungs-PC: + +```powershell +dotnet run --urls "http://0.0.0.0:5000" +``` + +Nachtrag: + +- `Properties/launchSettings.json` wurde so angepasst, dass das Entwicklungsprofil zusaetzlich auf `http://0.0.0.0:5000` lauscht. +- Bei Start aus Visual Studio bzw. ueber das Projektprofil bleibt `https://localhost:55415` lokal verfuegbar, Port `5000` ist aber zusaetzlich fuer andere PCs erreichbar. +- Falls bereits eine alte Visual-Studio-Instanz laeuft, App stoppen und neu starten, damit die geaenderte URL-Bindung aktiv wird. + +Zugriff von anderen PCs: + +```text +http://:5000 +``` + +Aktueller Stand vom 2026-05-21: + +```text +PC-IP im WLAN/Firmennetz: 172.16.9.185 +Lokale Test-URL: http://172.16.9.185:5000 +``` + +IP des PCs ermitteln: + +```powershell +ipconfig +``` + +Firewall-Regel einmalig in einer PowerShell "Als Administrator" anlegen: + +```powershell +netsh advfirewall firewall add rule name="TrafagSalesExporter local web 5000" dir=in action=allow protocol=TCP localport=5000 profile=domain,private +``` + +Am 2026-05-21 wurde eine allgemeine Port-5000-Regel angelegt und danach auf alle Firewall-Profile erweitert: + +```text +Regelname: Local Dev Web Port 5000 +Aktiviert: Ja +Profile: Domaene, Privat, Oeffentlich +Protokoll: TCP +Lokaler Port: 5000 +Aktion: Zulassen +``` + +Damit koennen spaeter auch andere lokale Entwicklungsprogramme auf Port 5000 von anderen Firmen-PCs erreicht werden, sofern sie an `0.0.0.0:5000` oder die konkrete PC-IP binden. + +Pruefen: + +```powershell +netsh advfirewall firewall show rule name="TrafagSalesExporter local web 5000" +``` + +Spaeter wieder entfernen: + +```powershell +netsh advfirewall firewall delete rule name="TrafagSalesExporter local web 5000" +``` + +Hinweise: + +- Die Firewall-Regel bleibt nach einem Windows-Neustart aktiv. +- Die Firewall-Regel bleibt normalerweise auch nach Windows-Updates aktiv. +- Da die Regel auf Domaene, Privat und Oeffentlich gilt, ist Port 5000 auch abgedeckt, wenn AlwaysOnVPN oder Windows das Netzwerk nicht als Domaenenprofil erkennt. +- Die App selbst startet nach einem Neustart nicht automatisch; `dotnet run ...` muss erneut gestartet werden. +- Die PC-IP kann sich nach Neustart, WLAN-Wechsel oder DHCP-Erneuerung aendern; dann `ipconfig` ausfuehren und die neue URL weitergeben. +- Der PC muss eingeschaltet bleiben und das PowerShell-Fenster muss offen bleiben. +- Nur im Firmennetz verwenden, nicht oeffentlich freigeben. +- Die lokale Uebergangs-URL ist bewusst HTTP, nicht HTTPS. Fuer diesen temporaeren internen Betrieb reicht das; lokales HTTPS waere moeglich, wuerde aber Zertifikats-/Trust-Aufwand fuer andere PCs verursachen. +- Finance Cockpit und HR KPI bleiben ueber ihre App-internen Logins geschuetzt. +- Wenn ein Finance-User im Buero die App ueber die VPN-IP des Entwicklungs-PCs trotzdem nicht erreicht, liegt es wahrscheinlich am AlwaysOnVPN-/Firmennetz-Routing. Das kann lokal auf dem PC nicht sicher freigeschaltet werden. + +Serverbefund: + +- Der IIS-Server fordert beim HTTPS/TLS-Handshake ein Client-Zertifikat (`RequestedClientCert=True`). +- Dadurch erreichen Requests weder `diag.txt` noch `BiDashboard.dll`. +- Marco/IT muss in IIS die SSL Settings pruefen und Client Certificates auf `Ignore` oder hoechstens `Accept` setzen, nicht `Require`. + +## H4 - Adminbereich und Passwortwechsel 2026-05-21 + +Quelle: lastchange.md.raw + +## Adminbereich und Passwortwechsel 2026-05-21 + +Geaendert: + +- Finance Cockpit und HR KPI Login-Masken haben einen Bereich `Passwort ändern`. +- Passwortaenderung verlangt Benutzername, aktuelles Passwort, neues Passwort und Wiederholung. +- Neue Passwoerter muessen mindestens 8 Zeichen haben. +- Gespeichert wird ein SHA-256-Hash in `appsettings.json`, kein Klartext. +- Neuer interner Adminbereich `/admin/sessions`. +- Der Adminbereich hat eine eigene App-interne Sperre `AdminAccess`. +- Adminseite `Aktive Logins` zeigt App-interne HR-/Finance-Entsperrungen seit dem letzten App-Start: + - Bereich + - Login-Name + - IP-Adresse, soweit aus dem Request verfuegbar + - Entsperrt seit + - Zuletzt gesehen +- Hinweis: Da HR und Finance gemeinsame App-Logins verwenden, zeigt die Seite nicht zwingend die echte Person, sondern die verwendete App-Session. +- Standorte-Tabelle zeigt jetzt Icons fuer den Quellentyp: + - Upload-Datei = Manual Excel / CSV + - Cloud Sync = SAP OData + - Storage = HANA / Server + +Initialer Adminzugang: + +```text +Username: admin +Initialpasswort: TrafagAdmin2026! +``` + +Nach erster Nutzung sollte das Adminpasswort ueber die Admin-Loginmaske geaendert werden. + +Verifiziert: + +- `dotnet build .\TrafagSalesExporter.csproj --no-restore --verbosity minimal -p:OutDir=C:\TMP\trafag_out\` +- Ergebnis: Build erfolgreich, nur bestehende MudBlazor-Analyzer-Warnungen zu `Dense` auf vorhandenen Controls. + +## H5 - Markdown-Doku und Anwenderdokus nachgezogen 2026-05-20 + +Quelle: lastchange.md.raw + +## Markdown-Doku und Anwenderdokus nachgezogen 2026-05-20 + +Geaendert: + +- Neue zentrale Markdown-Uebersicht `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` erstellt. +- Markdown-Dateien werden dort als aktuell fuehrend, Detaildoku oder historisch eingeordnet. +- Alte Markdown-Dateien wurden nicht geloescht, weil sie Pruefwerte, Zwischenentscheide und Audit-Spuren enthalten. +- HR- und Finance-Word-Anleitungen wurden visuell ueberarbeitet: + - Titelbereich + - Tabellen + - Hinweisboxen + - eingebettete neutrale Cockpit-Vorschaugrafiken +- Neue Bilddateien: + - `docs/hr_kpi_cockpit_preview.png` + - `docs/finance_cockpit_preview.png` + +Commits: + +- `0bff161 Document HR cockpit feature list` +- `a044040 Improve cockpit user guide documents` + +## H6 - Management Analyse auf Finance Summary ausgerichtet 2026-05-20 + +Quelle: lastchange.md.raw + +## Management Analyse auf Finance Summary ausgerichtet 2026-05-20 + +Geaendert: + +- `Management Analyse` hat jetzt einen fuehrenden Reiter `Finance Summary`. +- Die Kennzahlen in diesem Reiter verwenden dieselbe `FinanceRuleEngine` wie das zentrale Excel-Blatt `Finance Summary`. +- Filter fuer Jahr, Land und Waehrung wirken auf das Endergebnis, nicht nur auf eine Rohdatenansicht. +- Die bisherige Management-Tabelle bleibt als separater Rohdaten-/Diagnose-Reiter erhalten. +- Fuer DE 2026 wird kein Fehler mehr geworfen. Da DE/Alphaplan fachlich auf 2025 gezwungen ist, zeigt das Dashboard fuer DE 2026 einen leeren Zustand mit Hinweis. + +Verifiziert: + +- Lokale Probe gegen DB und Excel zeigte, dass die alte `Management Analyse` wegen Rohwerten, anderem Datum und EUR-Umrechnung nicht mit der Finance Summary uebereinstimmte. +- Tests: `dotnet test TrafagSalesExporter.sln --verbosity minimal` mit `77/77` bestanden. + +Commit: + +- `610e771 Add finance summary view and HR guide` + +## H7 - HR KPI Cockpit erweitert und Anwenderdokus erstellt 2026-05-20 + +Quelle: lastchange.md.raw + +## HR KPI Cockpit erweitert und Anwenderdokus erstellt 2026-05-20 + +Geaendert: + +- `HR KPI Cockpit` hat einen neuen Reiter `Anleitung` fuer HR-Anwenderinnen. +- Der Datenordner fuer Rexx-/SAP-Dateien ist im Cockpit sichtbar und je Lauf anpassbar; dauerhaft ueber `HrKpi:DataFolder` in `appsettings.json`. +- Dateistatus zeigt jetzt letzte Aenderung, Dateialter und Frischebewertung. +- Neue Auswertungen: Ampeln, Periodenvergleich, Datenqualitaets-Hinweise, Austritte nach Typ/Organisation und Absenzen nach Organisation. +- Managementsicht anonymisiert personenbezogene Details und reduziert die Anzeige auf aggregierte Kennzahlen. +- Print-/PDF-Funktion im Cockpit ergaenzt. + +Anwenderdokus: + +- `docs/HR_KPI_ANLEITUNG_HR_2026-05-20.docx` +- `docs/FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx` + +Verifiziert: + +- Word-Dateien als gueltige DOCX-Pakete geprueft. +- Tests: `dotnet test TrafagSalesExporter.sln --verbosity minimal` mit `77/77` bestanden. + +Commit: + +- `06fb560 Expand HR KPI cockpit and add user guides` + +## H8 - Workflow-Konsistenz fuer Keyuser verbessert 2026-05-20 + +Quelle: lastchange.md.raw + +## Workflow-Konsistenz fuer Keyuser verbessert 2026-05-20 + +Geaendert: + +- Export Dashboard zeigt jetzt Warnungen, wenn aktive Manual-Excel-Standorte noch keine Datei/Pfad hinterlegt haben. +- Nach einem Einzelstandortexport wird darauf hingewiesen, dass die zentrale Excel separat neu erzeugt werden muss. +- Dashboard markiert, wenn seit der letzten zentralen Excel ein Standortexport gelaufen ist. +- Neuer Keyuser-Menuepunkt `Manuelle Importe` fuer DE/UK/ES-artige Excel-/CSV-Quellen: + - Pfad/SharePoint-Referenz pflegen + - Datei hochladen + - Standort aktiv/inaktiv setzen + - Pfad pruefen +- Live-Status startet nicht mehr pauschal mit `HANA Abfrage...`, sondern quellenneutral bzw. fuer Manual Excel/SAP passender. +- Zentrale Excel enthaelt ein neues Blatt `Finance Summary` mit Summen nach Jahr, Land und Waehrung. +- `Management Analyse` ist klarer als Rohdaten-/Plausibilitaetssicht markiert. +- `Soll/Ist Vergleich` ist klarer als verbindliche Finance-Sicht markiert. + +Nachtrag: + +- Unter `Manuelle Importe` gibt es jetzt einen zweiten Reiter `Anleitung`. +- Der Reiter zeigt den Keyuser-Ablauf grafisch: + - Excel bereitstellen + - speichern und aktivieren + - Standort exportieren + - zentrale Excel erzeugen + - Finance pruefen +- Zusatzhinweise markieren die richtige Reihenfolge, den offenen DE-Fachentscheid und dass auf dem Server kein Microsoft Excel benoetigt wird. + +Bewusst nicht geaendert: + +- DE-Fachregel bleibt offen, bis Munir/Finance bestaetigt, welche Kundenlaender/Filter zum offiziellen DE-Ist gehoeren. + +## H9 - Keyuser Prozessdoku SVG 2026-05-20 + +Quelle: lastchange.md.raw + +## Keyuser Prozessdoku SVG 2026-05-20 + +Erstellt: + +- `docs/KEYUSER_PROZESSDOKU_2026-05-20.svg` + +Inhalt: + +- Prozess von Vorbereitung ueber Standortexport, zentrale Excel und Finance-Soll/Ist bis Fehlerbehandlung. +- Fokus auf Keyuser-Aktionen in der App: Settings, Standorte, Export Dashboard, Management Analyse, Soll/Ist Vergleich, Logs. +- Enthaltene Fachpunkte: Manual Excel fuer UK/ES/DE, DE Alphaplan, IT-Sonderregel, Finance-Spalten im Endexcel. +- Technische Implementierungsdetails und Testprogramme sind bewusst ausgeklammert. + +## H10 - Technische Systemarchitektur SVG 2026-05-20 + +Quelle: lastchange.md.raw + +## Technische Systemarchitektur SVG 2026-05-20 + +Erstellt: + +- `docs/SYSTEMARCHITEKTUR_TECHNISCH_2026-05-20.svg` + +Inhalt: + +- Laufzeit und IIS-Publish als `BiDashboard.dll` ohne EXE/AppHost. +- Blazor-UI, Authentisierung, Start-/Background-Services. +- Applikationskern: Export-Orchestrierung, Standortexport, Adapter, Transformationen, zentrale Tabelle. +- Datenquellen: SAP HANA/BI1/SAGE, SAP Gateway/OData, Manual Excel/CSV, SharePoint. +- Persistenzmodell mit wichtigsten SQLite-Tabellen. +- Output-/SharePoint-Pfade, Finance-Sonderregeln, HR/Finance-Zugriff und Betriebspruefpunkte. +- Test-/Probeprogramme sind bewusst nicht enthalten. + +## H11 - IT Finance-Methode fachlich bestaetigt 2026-05-20 + +Quelle: lastchange.md.raw + +## IT Finance-Methode fachlich bestaetigt 2026-05-20 + +Entscheid: + +- Fuer Italien gilt die vom Finance-Leiter bestaetigte Methode. +- `CustomerName` enthaelt `Trafag Italia` wird aus dem IT-Finance-Ist ausgeschlossen. +- Doppelte IT-Zeilen mit leerem `Supplier country` werden nur einmal gezaehlt. +- Diese Regel gilt nur fuer IT. + +Wichtig: + +- Die bisherige Kundenausschluss-Kombination passte 2025 numerisch naeher an den Sollwert, ist aber nicht die belastbare Methode fuer Folgejahre. +- Der 2025-Zufallstreffer wird deshalb nicht als fachliche Regel weiterverwendet. + +Gegen aktuelle DB getestet: + +```text +Soll IT: 7'669'840.00 +Bisherige IT-Summe: 7'669'641.47 +Bisherige Differenz: -198.53 +Trafag Italia Abzug in DB: 6'495.71 +Dubletten-Abzug SupplierCountry leer: 0.00 +Neue fachliche Methode: 7'663'145.76 +Neue Differenz: -6'694.24 +``` + +Umsetzung: + +- `Services/FinanceReconciliationService.cs` +- `Services/ExcelExportService.cs` +- Tests in `TrafagSalesExporter.Tests/FinanceReconciliationServiceTests.cs` + +## H12 - IIS Deployment Handoff 2026-05-19 + +Quelle: lastchange.md.raw + +## IIS Deployment Handoff 2026-05-19 + +Aktueller Deployment-/IIS-Stand wurde hier dokumentiert: + +```text +docs/DEPLOYMENT_IIS_HANDOFF_2026-05-19.md +``` + +Kurzstand: + +- `TrafagSalesExporter` veroeffentlicht jetzt als `BiDashboard.dll`. +- Keine EXE im Publish. +- Publish-Ziel: `\\trch-webapp-bidashboard.trafagch.local\BiDashboard$\`. +- Wahrscheinliche URL: `https://trch-webapp-bidashboard.trafagch.local/BiDashboard/`. +- Diagnose-`web.config` ist aktiv mit `httpErrors Detailed` und `stdoutLogEnabled=true`. +- `logs`-Ordner existiert auf dem Share, blieb nach dem 500 aber leer. +- ACL-Befund: `IIS_IUSRS` hat nur `ReadAndExecute`; App braucht fuer SQLite/logs wahrscheinlich `Modify`. +- Rechte konnten lokal nicht gesetzt werden: `icacls` auf dem Share endete mit `Zugriff verweigert`. + +Naechster Schritt: + +- Server-Spezialist muss App-Pool-Identity bzw. `IIS_IUSRS` mit `Modify` auf Publish-Ordner, `logs` und `trafag_exporter.db*` berechtigen und danach App-Pool neu starten. + +## H13 - ASP.NET Publish direkt aus TrafagSalesExporter 2026-05-19 + +Quelle: lastchange.md.raw + +## ASP.NET Publish direkt aus TrafagSalesExporter 2026-05-19 + +Entscheid: + +- `TrafagSalesExporter` bleibt das fuehrende Projekt. +- Das separate `BiDashboard`-Projekt wird fuer den aktuellen Stand nicht benoetigt. +- `TrafagSalesExporter` ist bereits eine ASP.NET/Blazor-Webanwendung (`Microsoft.NET.Sdk.Web`) und kann direkt veroeffentlicht werden. + +Umsetzung: + +- `OutputType=WinExe` wurde aus `TrafagSalesExporter.csproj` entfernt. +- Der `BiDashboard`-Verweis wurde aus `TrafagSalesExporter.sln` entfernt. +- Das Publish-Profil `Properties/PublishProfiles/FolderProfile.pubxml` zeigt auf den Server-Publish-Pfad: + +```text +\\trch-webapp-bidashboard.trafagch.local\BiDashboard$ +``` + +Wichtig fuer Deployment: + +- Die Anwendung wird nicht durch Doppelklick auf eine EXE gestartet. +- Der Server-Spezialist soll die publish-Ausgabe als ASP.NET-Webanwendung/IIS-App betreiben. +- Publish lokal: + +```powershell +dotnet publish .\TrafagSalesExporter.csproj -c Release +``` + +## H14 - Finance Cockpit Login und Vergleichsnachtrag 2026-05-19 + +Quelle: lastchange.md.raw + +## Finance Cockpit Login und Vergleichsnachtrag 2026-05-19 + +Nach dem Finance-Handoff vom 2026-05-18 wurden noch mehrere Schritte umgesetzt: + +- Haupt-App-Seite `/finance-cockpit/vergleich` wurde an die Logik und Darstellung der FinanceProbe angeglichen. +- Leere Ist-Zeilen ohne belastbaren Ist-Wert werden im Finance-Vergleich ausgefiltert. +- Die verwendeten Berechnungsformeln je Land wurden dokumentiert: + +```text +docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md +``` + +- Finance Cockpit erhielt einen separaten Login, unabhaengig vom HR-KPI-Login. + +Technischer Stand Finance-Cockpit-Login: + +- Konfiguration: `FinanceCockpitAccess` in `appsettings.json` +- Benutzer im aktuellen Stand: `finance` +- Passwort ist als SHA-256-Hash gespeichert. +- Finance nutzt ein eigenes Passwort: `Trafag-Finance-Cockpit-2026!`. +- HR-KPI nutzt weiterhin seine eigene `HrKpiAccess`-Konfiguration. +- Umsetzung: + - `Services/FinanceCockpitAccessService.cs` + - `Security/FinanceCockpitAccessOptions.cs` + - `Components/FinanceCockpit/FinanceCockpitUnlockPanel.razor` + - `Components/Routes.razor` + - `Components/Layout/NavMenu.razor` + - Registrierung in `Program.cs` + +AD-/Rollenstand: + +- `Security.Enabled = false` deaktiviert die globale AD-/Rollenpruefung fuer den Moment. +- Die vorhandenen `AccessGroups` und `AdminGroups` bleiben in `appsettings.json` stehen und wurden nicht geloescht. +- Wenn AD/Rollen wieder gelten sollen, `Security.Enabled` auf `true` setzen. +- Finance- und HR-KPI-Sperren bleiben auch bei deaktivierter AD-Pruefung aktiv. + +Relevante Commits: + +```text +8f1b1b8 Align main finance comparison with probe +f855e06 Filter empty actual finance rows +5c654ad Document finance formulas by country +9c544af Protect finance cockpit with login +``` + +## H15 - Zentrale Excel Finance-Filter 2026-05-19 + +Quelle: lastchange.md.raw + +## Zentrale Excel Finance-Filter 2026-05-19 + +Die zentrale Laenderdatei `Sales_All_yyyy-MM-dd.xlsx` wurde fuer den CFO-/Finance-Abgleich erweitert. + +Im Blatt `Sales` gibt es rechts einen zusammengehoerigen Finance-Spaltenblock: + +```text +Finance | Year +Finance | Country Key +Finance | Date +Finance | Net Sales Actual +Finance | Currency +Finance | Include +Finance | Source Value Field +``` + +Ziel: + +- Finance kann im zentralen Excel dieselben Ist-Summen erzeugen wie im Testprogramm. +- Es muss nicht geraten werden, ob `Land`, `TSC`, `Sales Price/Value`, `Document Total LC`, `posting date` oder `invoice date` zu verwenden ist. + +Filterregel fuer Finance: + +```text +Finance | Year = 2025 +Finance | Country Key = gewuenschtes Land +Finance | Include = TRUE +Summe ueber Finance | Net Sales Actual +``` + +Nur in der zentralen Datei wird ein zweites Blatt erzeugt: + +```text +Finance Filter Hilfe +``` + +Dieses Hilfsblatt beschreibt die zusammengehoerigen Finance-Spalten und die konkrete Filter-/Summenlogik. + +Verifikation: + +- Build erfolgreich: + +```text +dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_finance_help_sheet\ --verbosity minimal +``` + +- Preview-Excel erzeugt und geprueft: + +```text +.tmp_tools\GenerateConsolidatedPreview\out\Sales_All_2026-05-19.xlsx +``` + +- Gepruefte Blaetter: + +```text +Sales | Finance Filter Hilfe +``` + +- Finance-Spaltenblock im Blatt `Sales`: + +```text +36: Finance | Year +37: Finance | Country Key +38: Finance | Date +39: Finance | Net Sales Actual +40: Finance | Currency +41: Finance | Include +42: Finance | Source Value Field +``` + +- Summenvergleich gegen `FinanceReconciliationService` fuer 2025: + +| Key | Finance-Service | Excel-Finance-Spalten | Status | +| --- | ---: | ---: | --- | +| AT | `3'438'121.37` | `3'438'121.37` | MATCH | +| CH | `43'521'390.82` | `43'521'390.82` | MATCH | +| ES | `3'082'320.18` | `3'082'320.18` | MATCH | +| FR | `1'471'218.44` | `1'471'218.44` | MATCH | +| IN | `750'936'591.38` | `750'936'591.38` | MATCH | +| IT | `7'669'641.47` | `7'669'641.47` | MATCH | +| UK | `3'533'710.09` | `3'533'710.09` | MATCH | +| US | `3'749'865.33` | `3'749'865.33` | MATCH | + +Relevante Commits: + +```text +ebbc5a1 Add finance filter columns to consolidated export +b23f73e Add finance filter help sheet +``` + +## H16 - UK_B1 Mapping / FinanceProbe Nachtrag 2026-05-11 + +Quelle: lastchange.md.raw + +## UK_B1 Mapping / FinanceProbe Nachtrag 2026-05-11 + +Anlass: + +- In der FinanceProbe zeigte UK/England fuer `TRUK` nur `395'605.82 GBP` Ist gegen `3'749'865.00 GBP` Soll. +- In den Varianten fehlten weitere sinnvolle Abgrenzungen; sichtbar war nur `Positions-Netto (Sales Price/Value)`. +- Der Standort soll weiterhin `UK_B1` verwenden. + +Technischer Befund: + +- Standort: + - `Land = England` + - `TSC = TRUK` + - `SourceSystem = MANUAL_EXCEL` +- Korrekte Quelle: + +```text +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1 +``` + +- Lokal waren fuer `TRUK` keine `ManualExcelColumnMappings` vorhanden. +- Der Import lief deshalb ueber die Header-Automatik. +- Die Header-Automatik behandelte `Sales Price/Value` als fertigen Positionswert. +- In der UK-B1-Datei ist `Sales Price/Value` nach aktuellem Befund aber ein Stueckpreis. +- Der Finance-Positionswert muss deshalb berechnet werden: + +```text +[Sales Price/Value] * [Quantity] +``` + +Probe auf den bereits geladenen UK-Daten: + +| Berechnung | Wert | +| --- | ---: | +| Bisher importiert: Summe `SalesPriceValue` | `395'605.82 GBP` | +| Rekonstruiert: Summe `SalesPriceValue * Quantity` | `3'533'348.89 GBP` | +| Soll `check.xlsx` | `3'749'865.00 GBP` | +| Restdifferenz nach Multiplikation | ca. `216'516.11 GBP` | + +Umgesetzte Codeaenderung: + +- `Services/ManualExcelImportService.cs` + - grafische Manual-Excel-Mappings koennen jetzt einfache berechnete Quellen auswerten + - aktuell benoetigte Syntax: + +```text +=[Header A]*[Header B] +``` + + - Konstanten wie `=GBP` bleiben unveraendert gueltig + +- `Services/DatabaseSeedService.cs` + - England/TRUK wird auf den SharePoint-Ordner `Import/Finance/UK_B1` repariert, wenn der alte/falsche Pfad `Import/Finance/England` oder ein leerer Pfad vorhanden ist + - fuer `TRUK` wird ein grafisches Manual-Excel-Mapping geseedet + - wichtigste Zuordnung: + +```text +SalesPriceValue <- =[Sales Price/Value]*[Quantity] +SalesCurrency <- =GBP +DocumentCurrency<- =GBP +CompanyCurrency <- =GBP +PostingDate <- invoice date +InvoiceDate <- invoice date +``` + +- `TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs` + - neuer Test fuer Multiplikationsausdruck im Manual-Excel-Mapping + - prueft, dass `123.45 * 7 = 864.15` als `SalesPriceValue` importiert wird + +Aktueller Verifikationsstand: + +```text +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false --verbosity minimal +``` + +Ergebnis: + +- Tests erfolgreich. +- `59/59` Tests gruen. +- Bekannte Warnungen bleiben die bestehenden MudBlazor-Analyzerwarnungen zu `Dense`. + +Zusatzfix: + +- `DatabaseSeedService` wurde gehaertet. +- Der UK-Mapping-Seed wird nur ausgefuehrt, wenn `ManualExcelColumnMappings` sauber auf `Sites` referenziert. +- Dadurch wird der Initialisierungslauf nicht blockiert, wenn eine bestehende SQLite-DB gerade noch aus alten Reparaturtabellen wie `Sites_repair_old` bereinigt wird. + +Naechster praktischer Schritt: + +- Lokale DB wurde direkt aktualisiert: + - `TRUK` zeigt auf `https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1` + - `TRUK` hat `18` aktive Manual-Excel-Mapping-Zeilen + - `SalesPriceValue <= =[Sales Price/Value]*[Quantity]` +- FinanceProbe wurde auf `http://127.0.0.1:5099` neu gestartet. +- `/finance` antwortet mit HTTP `200`. +- `/run/export/TRUK` wurde angestossen, konnte aber wegen lokaler SharePoint-/Graph-Authentifizierung nicht neu laden: + +```text +ClientSecretCredential authentication failed +Es konnte keine Verbindung hergestellt werden, da der Zielcomputer die Verbindung verweigerte. (127.0.0.1:9) +``` + +Damit gilt: + +- Code, Seed und lokale Mapping-Konfiguration sind vorbereitet. +- Die zentrale Tabelle `CentralSalesRecords` enthaelt fuer UK noch den alten Importstand, bis der SharePoint-Zugriff wieder funktioniert und `TRUK` neu exportiert wird. +- Aktueller alter Zentralstand bleibt deshalb: + - `1'882` Zeilen + - `395'605.82 GBP` Summe `SalesPriceValue` + - rekonstruiert `3'533'348.89 GBP` ueber `SalesPriceValue * Quantity` + +Offen fachlich fuer UK: + +- Nach neuem Export mit Mapping muss die Restdifferenz gegen `check.xlsx` erneut gemessen werden. +- Wenn der Wert bei ca. `3.53 Mio. GBP` liegt, UK-Datei auf Rabatte, Fracht, Nebenpositionen oder eine andere Netto-Spalte pruefen. +- Wenn der Wert auf `3.75 Mio. GBP` steigt, war das Mapping die Hauptursache. + +## H17 - Manual Excel/CSV SharePoint-Ordner und Quellordner-Export 2026-05-08 + +Quelle: lastchange.md.raw + +## Manual Excel/CSV SharePoint-Ordner und Quellordner-Export 2026-05-08 + +Umgesetzte Anpassungen: + +- Manual Excel/CSV Quellen erzeugen nun immer eine neue Exportdatei; die Quelldatei wird nicht als Exportdatei weitergereicht. +- Lokale Manual-Dateien schreiben die neue Exportdatei in denselben lokalen Ordner wie die Quelldatei. +- SharePoint-Manual-Dateien schreiben die neue Exportdatei in denselben SharePoint-Ordner wie die Quelldatei. +- SharePoint-Referenzen ohne Dateiendung werden als Ordner behandelt. +- Bei SharePoint-Ordnern sucht die App die neueste passende Excel-/CSV-Datei fuer den Standort. +- Fuer datierte Dateien wird das Muster `ddMMyy_TSC.xlsx` bzw. `ddMMyy_TSC.csv` ausgewertet. +- Beispiel England/UK: + - Ordner: `https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1` + - `010526_TRUK.xlsx` wird vor `010426_TRUK.xlsx` gewaehlt. + - Falls kein Datum aus dem Dateinamen gelesen werden kann, faellt die Auswahl auf das SharePoint-Aenderungsdatum zurueck. + +Technischer Befund aus den Logs: + +- Spanien konnte die SharePoint-Datei lesen (`4'341` Zeilen), fiel danach aber auf einen ungueltigen lokalen Pfad, weil die URL als lokale Exportdatei behandelt wurde. +- Fehlerpfad war sinngemaess `...\https:\trafagag.sharepoint.com\...\Spain_Sales_2025.csv`. +- Deutschland hatte keinen manuellen Dateipfad hinterlegt. +- England/TRUK zeigte lokal versehentlich auf die Deutschland-Alphaplan-Datei; die lokale DB wurde auf den UK_B1-Ordner korrigiert. + +Codeaenderungen: + +- `DataSourceFetchResult` enthaelt optionale Overrides fuer lokalen Output-Ordner und SharePoint-Zielordner. +- `ManualExcelDataSourceAdapter` erkennt SharePoint-Dateien vs. SharePoint-Ordner und waehlt bei Ordnern die neueste passende Datei. +- `SharePointUploadService` kann den neuesten passenden Datei-Eintrag in einem SharePoint-Ordner aufloesen. +- `SiteExportService` nutzt fuer Manual-Quellen den Quellordner als Zielordner. +- `StandortePageService` erlaubt fuer Manual-Importe nun auch SharePoint-Ordnerreferenzen. +- Standort-UI-Hilfetext wurde entsprechend angepasst. +- `DatabaseSeedService` repariert England/TRUK auf den UK_B1-Ordner, wenn der Manual-Pfad leer ist. + +Letzte technische Verifikation: + +```text +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore --verbosity minimal +``` + +Ergebnis: + +- Tests erfolgreich, `55/55` +- Bekannte MudBlazor-Analyzerwarnungen zu `Dense` bleiben bestehen. + +## H18 - FinanceProbe erweitert fuer alle Finance-Referenzen 2026-05-08 + +Quelle: lastchange.md.raw + +## FinanceProbe erweitert fuer alle Finance-Referenzen 2026-05-08 + +Umgesetzte Anpassungen: + +- FinanceProbe zeigt nun alle aktiven `FinanceReferences` fuer 2025, auch wenn noch kein aktiver/importierter Standort dazu Daten liefert. +- Damit werden auch Laender wie AT, CH, CN, CZ, GFS, JP, MS, MSA, PL und RU sichtbar als `Keine Daten`, bis Ist-Daten vorhanden sind. +- Zusaetzliche Sektion `Datenabdeckung je Standort`: + - Standort / TSC + - Quellsystem und Anschlussart + - Manual-Datei- oder SharePoint-Pfad + - Aktivstatus + - Anzahl 2025-Zeilen in `CentralSalesRecords` + - Summe `SalesPriceValue` + - Waehrungen + - importierte Periode + - letzter Exportstatus und Hinweis +- Referenzschluessel-Erkennung wurde fuer CH/AT praezisiert: + - `AT`, `AUT`, `Oesterreich`/`Austria` -> `AT` + - `CH`, `CHE`, `Schweiz`/`Switzerland` -> `CH` +- Damit koennen Zeilen aus `ZSCHWEIZ` mit `LAND1 = AT` fachlich Oesterreich zugeordnet werden. + +Verifikation: + +- `Tools/FinanceProbe` Build erfolgreich. +- Haupttests wurden mit separatem Output/Obj-Pfad ausgefuehrt, damit die laufende App nicht stoert. + +## H19 - FinanceProbe als KI-Steuerprogramm 2026-05-11 + +Quelle: lastchange.md.raw + +## FinanceProbe als KI-Steuerprogramm 2026-05-11 + +Die FinanceProbe ist bewusst als temporaeres Test-/KI-Steuerprogramm erweitert worden. Die produktive Blazor-App bleibt davon getrennt. + +Neue Routen: + +- `/run/export/{siteKey}` + - startet einen Standortexport nach `Id`, `TSC` oder `Land` + - Beispiele: `/run/export/TRUK`, `/run/export/Spanien`, `/run/export/7` +- `/run/export-all` + - startet Export aller aktiven Standorte + - erzeugt danach die zentrale Datei +- `/run/consolidated` + - erzeugt nur die zentrale Datei aus `CentralSalesRecords` + +Nach jedem Lauf zeigt die FinanceProbe eine Run Summary: + +- neue Exportlogs seit Start +- Finance-Abgleich gegen `check.xlsx` +- Datenabdeckung je Standort + +Zweck: + +- Exporte und Finance-Abgleich koennen fuer Tests von der KI per HTTP angestossen werden. +- Die Funktion ist nicht als produktive Bedienoberflaeche gedacht und kann spaeter wieder entfernt werden. + +## H20 - Mapper-/Finance-Konfiguration konsolidiert 2026-05-07 + +Quelle: lastchange.md.raw + +## Mapper-/Finance-Konfiguration konsolidiert 2026-05-07 + +Umgesetzte Aufraeumarbeiten: + +- Die doppelte SAP-OData/HANA-Mapping-Engine wurde entfernt. +- Neuer gemeinsamer Service: `MappedSalesRecordComposer`. +- `SapCompositionService` und `HanaQueryService.GetMappedSalesRecordsAsync` laden ihre Quellen weiterhin separat, nutzen danach aber denselben Composer fuer: + - Primaerquelle + - Left Joins + - `SapFieldMapping` nach `SalesRecord` + - Konstanten wie `=SAP` / `=HANA` + - Datums-/Zahlenkonvertierung +- Der alte HANA-B1-Pfad fuer `OINV/INV1/ORIN/RIN1` bleibt bewusst bestehen, damit BI1/SAGE ohne grafisches Mapping weiter laufen. +- Die SAP-Mapping-Normalisierung liegt nur noch in `StandorteSapEditorService`; `StandortePageService` ruft diesen Service beim Speichern auf. +- Der tote Parameter im konsolidierten Export wurde entfernt. `ConsolidatedExportService.ExportAsync()` liest eindeutig aus `CentralSalesRecords`. +- Manueller Import erlaubt in UI und Service jetzt `.xlsx` und `.csv`. + +Finance-Konfiguration: + +- Neue Tabelle `FinanceReferences` fuer Soll-/check.xlsx-Referenzen je Jahr. +- Neue Tabelle `FinanceIntercompanyRules` fuer 2nd-party/IC-Erkennung nach `ScopeKey`, Kundennummer oder Namensmarker. +- Budgetkurse 2025 werden in `CurrencyExchangeRates` mit `Notes = Budget 2025` geseedet. +- `FinanceReconciliationService` liest Sollwerte, Budgetkurse und IC-Regeln aus der DB. +- Config-Export/-Import enthaelt jetzt `FinanceReferences` und `FinanceIntercompanyRules`. + +Noch bewusst offen: + +- HANA-B1-Spezialpfad und generischer HANA-Mapper laufen parallel. Das ist aktuell noetig fuer bestehende BI1/SAGE-Standorte ohne Mapping. +- Manual Excel hat weiterhin Header-Automatik und grafisches Mapping. Naechster Aufraeumpunkt waere eine gemeinsame Import-Mapping-Engine. + +Letzte technische Verifikation: + +```text +dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false --verbosity minimal +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore --verbosity minimal +``` + +Ergebnis: + +- Build erfolgreich +- Tests erfolgreich, `52/52` +- Bekannte MudBlazor-Analyzerwarnungen zu `Dense` bleiben bestehen. + +## H21 - SAP OData / ZSCHWEIZ / HANA Mapping 2026-05-07 + +Quelle: lastchange.md.raw + +## SAP OData / ZSCHWEIZ / HANA Mapping 2026-05-07 + +Aktueller Entscheid: + +- `ZSCHWEIZ` wird nicht direkt als SAP-HANA-Spezialfall gelesen. +- `ZSCHWEIZ` wird ueber den bestehenden SAP-OData/Gateway-Pfad gelesen. +- Der grafische Quellen- und Feldmapper bleibt dafuer aktiv. +- Feldinfos muessen nicht hart codiert werden, solange der Gateway-Service `$metadata` fuer das EntitySet liefert. + +Quellsystem-Namen wurden zur Entwirrung geschaerft: + +- Code `SAP` bleibt technisch bestehen, DisplayName ist jetzt `SAP OData`. +- Code `SAP_HANA` bleibt fuer direkte HANA-Tabellen/Views bestehen, DisplayName ist jetzt `SAP HANA Tables/Views`. +- Bestehende Konfigurationen bleiben dadurch kompatibel. + +Seed / Vorkonfiguration: + +- Standort `ZSCHWEIZ` / Land `Schweiz/Oesterreich` wird als inaktiver Standort angelegt bzw. repariert. +- `SourceSystem = SAP`. +- Quelle: Alias `Z`, EntitySet `ZSCHWEIZSet`. +- Mapping ist grafisch editierbar und wird auf die Felder der Tabelle `ZSCHWEIZ` gesetzt. +- Die Seed-/Repair-Logik zieht Quelle und Mapping auch bei bereits vorhandener ZSCHWEIZ-Konfiguration nach; manuelles Mapping ist nur noetig, wenn die Gateway-Feldnamen vom erwarteten `ZSCHWEIZ`-Layout abweichen. + +Wichtig fuer die UI: + +1. App neu starten, damit Seed/Repair laeuft. +2. `Settings -> Quellsysteme`: `SAP` sollte als `SAP OData` erscheinen. +3. `Standorte -> ZSCHWEIZ`: + - Quellsystem `SAP OData (SAP)` + - SAP Service URL Override auf den finalen OData-Service fuer `ZSCHWEIZ` setzen, falls die zentrale SAP-URL noch auf `ZPOWERBI_EINKAUF_SRV` zeigt. + - `Entity Sets refreshen`. + - Quelle `Z` soll auf `ZSCHWEIZSet` zeigen. + - `Felder aus Quellen laden`. + - Mapping kontrollieren. + +ABAP / SAP: + +- ABAP-Report liegt in `report.abap`. +- Report fuellt Tabelle `ZSCHWEIZ` aus Buchungskreis `1100` = Schweiz und `1200` = Oesterreich. +- `LAND1` ist Reporting-Land aus Buchungskreis. +- `CUSTOMER_LAND` ist Kundenland aus `KNA1-LAND1`. +- Upsert erfolgt per `MODIFY zschweiz FROM TABLE`. + +Letzte technische Verifikation: + +```text +dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false --verbosity minimal +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore --verbosity minimal +``` + +Ergebnis: + +- Build erfolgreich +- Tests erfolgreich, `50/50` + +## H22 - Finance-Abgrenzung: Antworten Andreas 2026-05-07 + +Quelle: lastchange.md.raw + +## Finance-Abgrenzung: Antworten Andreas 2026-05-07 + +Fachliche Vorgabe nach Rueckmeldung: + +- Net Sales Actuals werden in Hauswaehrung gerechnet. +- Massgebend ist der Nettofakturawert. +- Umrechnung nach CHF erfolgt mit Budgetkursen, nicht mit Tageskursen. +- Umrechnung/Summierung soll pro Artikel bzw. Belegposition erfolgen. +- Indien wird in INR betrachtet. +- Italien wird in Hauswaehrung betrachtet; Intercompany-/2nd-party-Abgrenzung wird separat angeschaut. +- UK wird in GBP betrachtet. +- Gutschriften haben eigene Rechnungsnummern/Rechnungspositionen und sollen ueber Artikelnummern/Positionen behandelt werden. +- Intercompany soll im zweiten Schritt als 2nd-party/3rd-party-Klassifikation pflegbar werden. +- Genannte 2nd-party/Intercompany-Indikatoren: Trafag, Magnetic Sense/Magnets Sense, Gesellschaft fuer Sensorik; Nummern/Uebersetzungen koennen je Land abweichen. + +Budgetkurse 2025 fuer CHF-Ausweis: + +```text +USD/CHF = 0.85 +EUR/CHF = 0.95 +GBP/CHF = 1.13 +CHF/INR = 90.91 +CHF/CZK = 25.64 +PLN/CHF = 0.22 +CHF/JPY = 156.25 +``` + +Umsetzung in der FinanceProbe: + +- Auswahl der Ist-Variante bevorzugt nun `Nettofakturawert Hauswaehrung` (`DocTotal - VatSum`). +- `Sales Price/Value` bleibt als Vergleichsvariante sichtbar. +- Zusaetzlicher Kandidat `Nettofakturawert Hauswaehrung -> CHF Budget 2025`. +- Referenz in der Oberflaeche wird als `check.xlsx Sollwert` bezeichnet, nicht mehr als fuehrende Power-BI-Referenz. +- Intercompany-Anzeige wurde fachlich als `2nd-party/IC` beschriftet; Regeln werden jetzt in `FinanceIntercompanyRules` geseedet und per Config exportiert/importiert. + +## H23 - Finance Probe / Sales-Abgrenzung + +Quelle: lastchange.md.raw + +## Finance Probe / Sales-Abgrenzung + +Ziel der heutigen Arbeit: + +- separate kleine Pruef-GUI fuer Finanz-/Sales-Abgrenzungen bauen +- moeglichst viel Logik aus dem Hauptprogramm wiederverwenden +- verschiedene Summenlogiken pro Land nebeneinander sichtbar machen +- gegen `check.xlsx` vergleichen + +Wichtiges fachliches Verstaendnis nach Klaerung im Chat: + +- `check.xlsx` kommt von Rhino und enthaelt die Soll-Zahlen von Andreas. +- Aus den Landessystemen kommt der Ist-Wert. +- Power BI soll in der fachlichen Kommunikation nicht als fuehrende Referenz genannt werden. +- Ziel ist nicht, zufaellig die passendste technische Variante zu nehmen, sondern je Land/System die fachlich korrekte Abgrenzungslogik zu klaeren. + +## H24 - Commit + +Quelle: lastchange.md.raw + +## Commit + +Rollback-Commit fuer die Finance-Probe wurde erstellt: + +```text +15dec06 Add finance reconciliation probe +``` + +Dieser Commit enthaelt gezielt: + +- `Services/FinanceReconciliationService.cs` +- `Tools/FinanceProbe/FinanceProbe.csproj` +- `Tools/FinanceProbe/Program.cs` +- DI-Registrierung in `Program.cs` +- Dashboard nutzt den ausgelagerten Finance-Service +- `TrafagSalesExporter.csproj` schliesst `Tools/**` aus dem Hauptprojekt aus +- `TrafagSalesExporter.sln` enthaelt das neue Tool-Projekt + +Andere bereits vorhandene Worktree-Aenderungen wurden nicht mitcommitted. + +## H25 - Neues Tool + +Quelle: lastchange.md.raw + +## Neues Tool + +Neues separates Probe-GUI: + +```text +Tools/FinanceProbe +``` + +Start: + +```powershell +dotnet run --project Tools\FinanceProbe\FinanceProbe.csproj --urls http://localhost:55417 +``` + +URL: + +```text +http://localhost:55417/finance +``` + +Aktueller Start im Chat: + +- Probe-GUI wurde auf `localhost:55417` gestartet +- HTTP `200` bestaetigt + +Hinweis Netzwerk: + +- Start mit `localhost` ist nur lokal auf dem Laptop erreichbar. +- Andere im Trafag-Netz koennen es so normalerweise nicht ueber Laptop-IP oeffnen. +- Fuer Netzwerkzugriff waere `http://0.0.0.0:55417` noetig. +- Probe-GUI hat aktuell keine Authentifizierung, daher nicht unkontrolliert im Netzwerk freigeben. + +## H26 - FinanceReconciliationService + +Quelle: lastchange.md.raw + +## FinanceReconciliationService + +Neue wiederverwendbare Logik: + +```text +Services/FinanceReconciliationService.cs +``` + +Interface: + +```csharp +IFinanceReconciliationService +``` + +Aktuelle Funktion: + +```csharp +Task> BuildNetSalesReferenceRowsAsync(int year = 2025) +``` + +Logik: + +- liest `CentralSalesRecords` +- filtert Jahr ueber `InvoiceDate`, fallback `ExtractionDate` +- gruppiert pro Referenz-Key/Land +- berechnet Kandidaten: + - `SalesPriceValue` + - `DocTotalFC - VatSumFC` + - `DocTotal - VatSum` +- Belegkopfwerte werden vor Summierung dedupliziert: + - bevorzugt `TSC + DocumentType + DocumentEntry` + - fallback `TSC + DocumentType + InvoiceNumber` +- erkennt aktuell Intercompany nur pragmatisch fuer IT/TRIT anhand bekannter Kunden +- liefert pro Kandidat Wert, Waehrung, IC-Wert, Differenzen + +## H27 - FinanceProbe Darstellung + +Quelle: lastchange.md.raw + +## FinanceProbe Darstellung + +Die Tabelle zeigt aktuell: + +- Status +- Firma +- gewaehlte Abgrenzung +- Ist-Waehrung +- Ist 2025 +- Referenz-Waehrung +- Referenz +- Excel LC +- Excel CHF +- Excel Power BI +- Excel Status +- Differenz +- Differenz ohne IC +- Waehrung +- Zeilen +- Varianten aufklappbar + +Wichtig: + +- Die Bezeichnung `Power BI` ist in der Probe-Oberflaeche noch sichtbar, weil `check.xlsx` diese Spalte enthaelt. +- Fachlich soll in Kommunikation gegen Andreas aber `check.xlsx` / Soll-Zahl genannt werden, nicht Power BI als fuehrende Referenz. +- Eine sinnvolle naechste UI-Bereinigung waere, die Spalte/Labels in der Probe auf `Excel Sollwert` oder `Rhino Sollwert` umzubenennen. + +## H28 - Probe-Output vom 2026-05-04 09:55 + +Quelle: lastchange.md.raw + +## Probe-Output vom 2026-05-04 09:55 + +Zusammenfassung: + +```text +8 Standorte +4 OK +1 Pruefen +3 Keine Daten +Excel-Referenzen gelesen: 17 +``` + +Befunde: + +## H29 - CH + +Quelle: lastchange.md.raw + +### CH + +- Keine Ist-Daten +- keine sichtbare Soll-Zahl + +## H30 - DE + +Quelle: lastchange.md.raw + +### DE + +- Keine Ist-Zeilen aus Systemdaten +- Soll/LC aus Excel vorhanden: + - Referenz ca. `3'635'923` + - Excel LC `3'635'922.91` + - Excel CHF `3'407'000.00` + +Offen: + +- Quelle fuer DE klaeren +- evtl. MANUAL_EXCEL oder noch nicht exportiert + +## H31 - ES + +Quelle: lastchange.md.raw + +### ES + +- Keine Ist-Zeilen aus Systemdaten +- Soll/LC aus Excel vorhanden: + - Referenz ca. `3'102'334` + - Excel LC `3'102'333.61` + - Excel CHF `2'907'000.00` + +Offen: + +- Quelle fuer ES klaeren +- evtl. MANUAL_EXCEL oder noch nicht exportiert + +## H32 - FR + +Quelle: lastchange.md.raw + +### FR + +- Status OK +- gewaehlte Abgrenzung: `Sales Price/Value` +- Ist-Waehrung: `EUR` +- Ist: `1'471'218.44` +- Soll/Referenz: `1'471'218.00` +- Differenz: `0.44` +- Zeilen: `1649` + +Befund: + +- FR passt praktisch exakt mit `Sales Price/Value` in EUR. + +Offene Frage an Andreas: + +- Ist `Sales Price/Value` in EUR fuer FR fachlich korrekt? + +## H33 - IN + +Quelle: lastchange.md.raw + +### IN + +- Status OK +- gewaehlte Abgrenzung: `Sales Price/Value` +- Ist-Waehrungen: `CHF, EUR, GBP, INR, JPY, USD` +- Ist: `750'936'591.38` +- Soll/Referenz: `750'936'591.00` +- Differenz: `0.38` +- Zeilen: `4000` + +Befund: + +- IN passt rechnerisch fast exakt, aber Waehrungen sind gemischt. + +Offene Frage an Andreas: + +- Ist diese gemischte Summe fachlich korrekt? +- Oder muss nach CHF umgerechnet bzw. nach Waehrung getrennt werden? + +## H34 - IT + +Quelle: lastchange.md.raw + +### IT + +- Status Pruefen +- gewaehlte Abgrenzung: `DocTotal - VatSum` +- Ist-Waehrung: `EUR` +- Ist: `11'866'896.53` +- Soll/Referenz LC: `7'669'840.00` +- Differenz: `4'197'056.53` +- Differenz ohne IC: `3'733.67` +- Zeilen: `15883` + +Befund: + +- IT liegt ohne IC-Abzug stark daneben. +- Mit erkanntem IC-Abzug ist die Differenz sehr klein. + +Offene Frage an Andreas: + +- Soll IT mit Intercompany-Abzug gerechnet werden? +- Falls ja: nach welchen Kunden/Kriterien erkennt Finance Intercompany? + +## H35 - UK + +Quelle: lastchange.md.raw + +### UK + +- Status OK +- gewaehlte Abgrenzung: `Sales Price/Value` +- Ist-Waehrung: `USD` +- Ist: `3'749'865.33` +- Soll/Referenz: `3'749'865.00` +- Differenz: `0.33` +- Zeilen: `942` + +Befund: + +- UK passt praktisch exakt mit `Sales Price/Value` in USD. + +Offene Frage an Andreas: + +- Ist USD fuer UK korrekt? +- Oder muss fuer offizielles Reporting nach CHF umgerechnet werden? + +## H36 - US + +Quelle: lastchange.md.raw + +### US + +- Status OK +- gewaehlte Abgrenzung: `Sales Price/Value` +- Ist-Waehrung: `USD` +- Ist: `3'749'865.33` +- Soll/Referenz: `3'749'865.00` +- Differenz: `0.33` +- Zeilen: `942` + +Befund: + +- US zeigt denselben Ist-Wert wie UK. +- Das wirkt auffaellig und sollte fachlich/technisch geprueft werden. + +Offene Frage: + +- Welche Quelle und Logik ist fuer US korrekt? +- Ist US im aktuellen System richtig zugeordnet? + +## H37 - Word-Datei fuer Andreas + +Quelle: lastchange.md.raw + +## Word-Datei fuer Andreas + +Erstellt: + +```text +FINANZ_OFFENE_FRAGEN_ANDREAS.docx +``` + +Inhalt: + +- kurze Mail an Andreas +- `check.xlsx` als Soll-Zahl von Andreas/Rhino formuliert +- Power BI fachlich nicht als Referenz genannt +- bisherige Befunde pro Land: + - FR + - IN + - IT + - UK + - US + - DE / ES +- offene Fragen zu: + - Waehrung und CHF-Umrechnung + - Umsatzdefinition + - Periodenabgrenzung + - Gutschriften/Storno + - Intercompany + - Entscheid-Tabelle pro Land + +## H38 - Markdown-Datei fuer Andreas + +Quelle: lastchange.md.raw + +## Markdown-Datei fuer Andreas + +Erstellt/angepasst: + +```text +FINANZ_FRAGEN_ANDREAS.md +``` + +Aktuelle Formulierung: + +- `check.xlsx` kommt von Rhino und enthaelt Soll-Zahlen von Andreas. +- Landessysteme liefern Ist-Werte. +- offen ist, welche fachliche Logik pro Land/System zur Soll-Zahl fuehren soll. +- Power BI ist nicht mehr als fuehrende Referenz formuliert. + +## H39 - Verifikation + +Quelle: lastchange.md.raw + +## Verifikation + +Ausgefuehrt: + +```powershell +dotnet build .\TrafagSalesExporter.csproj --verbosity minimal +dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal +``` + +Ergebnis: + +- Hauptprojekt baut erfolgreich +- FinanceProbe baut erfolgreich +- Tests erfolgreich +- `48/48` Tests gruen + +Bekannte Warnungen: + +- `NU1900` im Probe-Build, weil NuGet-Sicherheitsdaten wegen Netzwerk/nuget.org nicht geladen werden konnten +- bekannte MudBlazor Analyzer-Warnungen zu `Dense` + +## H40 - Offene sinnvolle naechste Schritte + +Quelle: lastchange.md.raw + +## Offene sinnvolle naechste Schritte + +1. In der Probe-UI `Power BI`-Labels fachlich bereinigen: + - z. B. `Excel Sollwert` / `Rhino Sollwert` +2. Andreas' Antworten in eine Konfiguration ueberfuehren: + - Land/System + - Summenlogik + - System-Waehrung + - CHF-Umrechnung ja/nein + - Periodendatum + - IC-Regel +3. DE/ES Quelle klaeren: + - aktuell keine Ist-Daten +4. US/UK Doppelwert pruefen: + - US zeigt denselben Ist-Wert wie UK +5. IT Intercompany-Regel fachlich bestaetigen +6. Wenn Regeln bestaetigt sind: + - Finance-Probe erweitert anzeigen + - spaeter produktiv ins Hauptprogramm uebernehmen + +--- + +## H41 - Nachtrag 2026-05-04: Excel-Spaltenmapper fuer manuelle Land-Excel-Dateien + +Quelle: lastchange.md.raw + +## Nachtrag 2026-05-04: Excel-Spaltenmapper fuer manuelle Land-Excel-Dateien + +Ausloeser: + +- Deutschland hat ein eigenes Excel-Beispiel geliefert. +- Das Format entspricht nicht dem bisherigen Standard-Excel-Import. +- Ziel war, nicht fuer jedes Land statischen Spezialcode zu schreiben, sondern die Spaltenzuordnung konfigurierbar zu machen. + +Beispielhafte deutsche Spalten: + +- `Export-Datum` +- `Firma` +- `Belegnummer` +- `Position` +- `ArtikelBezeichnung` +- `Warengruppen-Bezeichnung` +- `Anz. VE` +- `Lieferanten Nummer` +- `Name Lieferant` +- `Land Lieferant` +- `AdressNummer-Kunde` +- `Name Kunde` +- `Land Kunde` +- `Branche` +- `EinstandsPreis` +- `Währung` +- `BestellNummer` +- `NettoPreisEinzelX` +- `NettoPreisGesamtX` +- `Versandbedingung` +- `AdressNummer_V` +- `Belegdatum-Rechnung` +- `BelegDatum Auftrag` +- `ArtikelNummer` + +Wichtige fachliche/technische Interpretation fuer Deutschland: + +- `NettoPreisGesamtX` wird als `SalesPriceValue` verwendet. +- `Währung` wird fuer `SalesCurrency`, `DocumentCurrency`, `CompanyCurrency` und `StandardCostCurrency` verwendet. +- `Belegdatum-Rechnung` wird als `InvoiceDate` verwendet. +- `BelegDatum Auftrag` wird als `OrderDate` verwendet. +- `ArtikelNummer` wird als `Material` verwendet. +- Kommentar-/Info-Zeilen ohne echte Position und ohne Betrag werden beim Import ignoriert. + +## H42 - Neue Datenstruktur + +Quelle: lastchange.md.raw + +## Neue Datenstruktur + +Neue Tabelle / neues Model: + +```text +ManualExcelColumnMappings +Models/ManualExcelColumnMapping.cs +``` + +Felder: + +- `SiteId` +- `TargetField` +- `SourceHeader` +- `IsRequired` +- `IsActive` +- `SortOrder` + +Zweck: + +- Pro Standort kann festgelegt werden, welche Excel-Spalte auf welches internes `SalesRecord`-Feld gemappt wird. +- Konstanten sind moeglich, wenn `SourceHeader` mit `=` beginnt, z. B. `=Manual Excel`. + +## H43 - Geaenderte Hauptlogik + +Quelle: lastchange.md.raw + +## Geaenderte Hauptlogik + +Geaendert: + +```text +Services/ManualExcelImportService.cs +``` + +Neue Logik: + +- Beim manuellen Excel-Import werden zuerst aktive `ManualExcelColumnMappings` des Standorts geladen. +- Wenn Mapping-Zeilen vorhanden sind, wird dieses Mapping verwendet. +- Wenn kein Mapping vorhanden ist, laeuft weiterhin die bisherige statische Standarderkennung. +- Damit bleiben bestehende manuelle Excel-Imports abwaertskompatibel. + +Wichtig: + +- Der Mapper ersetzt nicht die fachliche Finanzlogik. +- Er sorgt nur dafuer, dass fremde Excel-Spalten korrekt in die internen Felder geschrieben werden. +- Welche Summe spaeter fuer Finance gilt, muss weiterhin fachlich entschieden werden. + +## H44 - Geaenderte Standort-UI + +Quelle: lastchange.md.raw + +## Geaenderte Standort-UI + +Geaendert: + +```text +Components/Pages/Standorte.razor +Services/StandortePageService.cs +``` + +In der Standortbearbeitung fuer manuelle Excel-Standorte gibt es neu: + +- Bereich `Excel-Spaltenmapping` +- Button `Spalten aus Excel laden` +- Button `Auto-Match` +- Button `Mapping hinzufuegen` +- Tabelle mit: + - Zielfeld + - Excel-Spalte / Konstante + - Pflicht + - Aktiv + - Loeschen + +Auto-Match erkennt aktuell u. a. die deutschen Spalten und schlaegt passende Zuordnungen vor. + +## H45 - Config-Export / Import + +Quelle: lastchange.md.raw + +## Config-Export / Import + +Geaendert: + +```text +Services/ConfigTransferService.cs +Models/ConfigTransferPackage.cs +``` + +Neu: + +- `ManualExcelColumnMappings` werden im Konfigurationspaket mit exportiert. +- Beim Import werden die Mapping-Zeilen wieder hergestellt. + +Damit kann die Konfiguration spaeter zwischen Umgebungen mitgenommen werden. + +## H46 - Datenbank-Schema + +Quelle: lastchange.md.raw + +## Datenbank-Schema + +Geaendert: + +```text +Data/AppDbContext.cs +Services/DatabaseInitializationService.SchemaSql.cs +Services/DatabaseSchemaMaintenanceService.cs +``` + +Neu: + +- `DbSet` +- `CREATE TABLE ManualExcelColumnMappings` +- Schema-Wartung legt die Tabelle nachtraeglich an, falls sie in einer bestehenden DB fehlt. +- Beim Loeschen eines Standorts werden dessen manuelle Excel-Mappings mit geloescht. + +## H47 - Deutschland lokal eingerichtet + +Quelle: lastchange.md.raw + +## Deutschland lokal eingerichtet + +Am 2026-05-04 wurde Deutschland in der lokalen Datenbank direkt ohne UI eingerichtet. + +Lokale DB: + +```text +C:\Users\koi\source\repos\Ai\TrafagSalesExporter\trafag_exporter.db +``` + +Gefundener/konfigurierter Standort: + +```text +Id=8 +TSC=TRDE +Land=Deutschland +SourceSystem=MANUAL_EXCEL +``` + +Aktive Mapping-Zeilen: + +```text +26 +``` + +Konkrete Zuordnung fuer DE: + +```text +ExtractionDate <- Export-Datum +InvoiceNumber <- Belegnummer +PositionOnInvoice <- Position +Material <- ArtikelNummer +Name <- ArtikelBezeichnung +ProductGroup <- Warengruppen-Bezeichnung +Quantity <- Anz. VE +SupplierNumber <- Lieferanten Nummer +SupplierName <- Name Lieferant +SupplierCountry <- Land Lieferant +CustomerNumber <- AdressNummer-Kunde +CustomerName <- Name Kunde +CustomerCountry <- Land Kunde +CustomerIndustry <- Branche +StandardCost <- EinstandsPreis +StandardCostCurrency <- Währung +PurchaseOrderNumber <- BestellNummer +SalesPriceValue <- NettoPreisGesamtX +SalesCurrency <- Währung +DocumentCurrency <- Währung +CompanyCurrency <- Währung +Incoterms2020 <- Versandbedingung +SalesResponsibleEmployee <- AdressNummer_V +InvoiceDate <- Belegdatum-Rechnung +OrderDate <- BelegDatum Auftrag +DocumentType <- =Manual Excel +``` + +Wichtig fuer Rollback/Umzug: + +- Diese DE-Einrichtung wurde direkt in `trafag_exporter.db` gespeichert. +- Die DB-Aenderung ist kein Git-Commit-Inhalt, weil SQLite-Datenbankdaten normalerweise nicht sauber versioniert werden. +- Der Code fuer den Mapper ist aktuell im Worktree vorhanden, aber noch nicht committed. +- Wenn die DB zurueckgerollt oder neu erstellt wird, muss das DE-Mapping erneut ueber die UI, Config-Import oder ein Hilfsskript eingerichtet werden. + +## H48 - Tests + +Quelle: lastchange.md.raw + +## Tests + +Ergaenzt: + +```text +TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs +``` + +Neuer Test: + +```text +ReadSalesRecordsAsync_Uses_Configured_Manual_Excel_Mapping_For_German_Headers +``` + +Der Test prueft: + +- deutsches Excel-Headerformat +- Kommentarzeile ohne echte Position wird ignoriert +- echte Belegposition wird importiert +- `NettoPreisGesamtX` mit Schweizer Tausenderzeichen wird korrekt als Dezimalzahl gelesen +- Waehrung `EUR` wird in Sales-/Document-/Company-Currency uebernommen +- Rechnungsdatum und Auftragsdatum werden korrekt gelesen + +Letzter bekannter Teststand nach Mapper-Arbeit: + +```text +dotnet build .\TrafagSalesExporter.csproj --verbosity minimal +dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal --no-restore +``` + +Ergebnis: + +- Hauptprojekt baut erfolgreich +- FinanceProbe baut erfolgreich +- Tests erfolgreich +- `49/49` Tests gruen + +Bekannte Warnung: + +- `NU1900`, weil NuGet-Sicherheitsdaten wegen Netzwerk/nuget.org nicht geladen werden konnten + +## H49 - Aktueller Laufstand + +Quelle: lastchange.md.raw + +## Aktueller Laufstand + +Die Haupt-App war nach der DE-Konfiguration erreichbar: + +```text +http://localhost:55416/standorte +HTTP 200 +``` + +Hinweis: + +- Der Browser kann geschlossen sein, waehrend der Serverprozess weiterlaeuft. +- Wenn ein Build wegen gesperrter Dateien fehlschlaegt, zuerst den laufenden `TrafagSalesExporter`-Prozess beenden. + +## H50 - Noch offen nach Excel-Spaltenmapper + +Quelle: lastchange.md.raw + +## Noch offen nach Excel-Spaltenmapper + +1. Mapper-Code committen, sobald der aktuelle Stand als Rollback-Punkt gesichert werden soll. +2. In der Standort-UI Deutschland oeffnen und visuell pruefen, ob die 26 Mapping-Zeilen angezeigt werden. +3. Mit echtem DE-Excel einen Importlauf testen. +4. Danach Finance-Probe erneut pruefen: + - ob DE nicht mehr `Keine Daten` ist + - ob `SalesPriceValue` gegen Soll aus `check.xlsx` passt +5. Falls weitere Laender eigene Excel-Formate liefern: + - nicht statischen Code bauen + - neues Mapping pro Standort pflegen +6. Klaeren, ob DE fachlich `NettoPreisGesamtX` in EUR als Ist-Wert verwenden soll oder ob CHF-Umrechnung noetig ist. + +--- + +## H51 - Nachtrag 2026-05-05: FinanceProbe Ampel, Spanien v2 und Deutschland-Beispielfile + +Quelle: lastchange.md.raw + +## Nachtrag 2026-05-05: FinanceProbe Ampel, Spanien v2 und Deutschland-Beispielfile + +## H52 - FinanceProbe Management-Ansicht + +Quelle: lastchange.md.raw + +### FinanceProbe Management-Ansicht + +Das Testprogramm `Tools/FinanceProbe` wurde fuer das Finance-Meeting erweitert. + +URL lokal: + +```text +http://localhost:55417/finance +``` + +Neue Ansicht: + +- `Meeting Ampel 2025` +- Ampel pro Land: + - Gruen: Zahl passt rechnerisch gegen Referenz + - Gelb: Differenz oder fachliche Abgrenzung offen + - Grau: keine belastbaren Importdaten +- Anzeige pro Land: + - Ist + - Soll / Referenz + - Differenz + - passender technischer Wert + - Waehrung / CHF-Hinweis + - kurze fachliche Begruendung + +Wichtig zur Waehrung: + +- Wenn Quelle `CHF` liefert, kann CHF direkt gezeigt werden. +- Wenn Quelle `EUR`, `USD`, `GBP`, `INR` usw. liefert, ist es Mandanten-/Originalwaehrung. +- CHF-Ausweis braucht dann eine separate FX-Regel bzw. offiziellen Umrechnungskurs. + +## H53 - Spanien v2 im Testprogramm + +Quelle: lastchange.md.raw + +### Spanien v2 im Testprogramm + +Spanien wird im FinanceProbe nicht mehr nur als normaler Zentralimport betrachtet. + +Direkter CSV-Check: + +```text +sagespain/v2/Spain_Sales_2025.csv +``` + +Gelesene Werte: + +- Zeilen: `4'341` +- Ist 2025 / `SalesPriceValue`: `3'082'320.18` +- Waehrung: `EUR` +- Soll aus `check.xlsx`: `3'102'333.61` +- Differenz: `-20'013.43` + +Status: + +- Ampel: Gelb / Pruefen +- Grund: Export technisch lesbar, aber Differenz zu `check.xlsx` offen. + +Offen fuer Spanien: + +- korrekte Datumsabgrenzung (`FechaFactura` vs. Alternativen) +- Serien `REG`, `LAT`, `PRO`, `REC` +- Behandlung von Gutschriften / `REC` +- offizielle Sage-Auswertung mit identischem Filter zur Sollzahl + +## H54 - Deutschland-Beispielfile + +Quelle: lastchange.md.raw + +### Deutschland-Beispielfile + +Neues File im Projektordner: + +```text +DE_Beispiel_Export_Daten.xlsx +``` + +Hinweis: + +- Der Benutzer hatte zuerst `.xls` genannt, vorhanden ist `.xlsx`. +- Das File ist als Beispielfile zu behandeln, nicht als finale Jahresdatei. + +Technischer Check: + +- relevante Spalte: `NettoPreisGesamtX` +- Mapping-Ziel: `SalesPriceValue` +- Betragszeilen: `2` +- Summe `NettoPreisGesamtX`: `8'290.70` +- Waehrung: `EUR` + +Einbau im FinanceProbe: + +- eigener Abschnitt `Germany Excel sample check` +- zeigt Datei, Zeilenzahl, Summe und Referenz aus `check.xlsx` +- markiert explizit, dass die Differenz nur Sample-Charakter hat +- in der Management-Ampel wird Deutschland weiter nicht als OK gewertet, solange kein finaler DE-Jahresexport/import vorliegt + +Fachliche Interpretation fuer Deutschland: + +- Das Mapping funktioniert technisch. +- `NettoPreisGesamtX` kann als Kandidat fuer `SalesPriceValue` gelesen werden. +- Das Beispielfile darf nicht gegen die Jahresreferenz `3'635'922.91` als finale Ist-Zahl verwendet werden. +- Fuer das Meeting ist die Aussage: + - Deutschland-Format ist technisch verstanden. + - Finale DE-Zahl fehlt noch. + - Benoetigt wird ein vollstaendiger DE-Jahresfile 2025 oder ein bestaetigter Importlauf. + +## H55 - Verifikation 2026-05-05 + +Quelle: lastchange.md.raw + +### Verifikation 2026-05-05 + +Ausgefuehrt: + +```text +dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal --no-restore +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal --no-restore +``` + +Ergebnis: + +- FinanceProbe Build erfolgreich +- Tests erfolgreich +- `50/50` Tests gruen +- Web UI liefert `HTTP 200` +- FinanceProbe enthaelt: + - `Meeting Ampel 2025` + - `Spain CSV direct check` + - `Germany Excel sample check` + +## H56 - Financechef-Regeln abgesichert 2026-05-11 + +Quelle: lastchange.md.raw + +## Financechef-Regeln abgesichert 2026-05-11 + +Umgesetzt: + +- `PostingDate` als eigenes Feld in `SalesRecord` und `CentralSalesRecord`. +- Zentrale SQLite-Tabelle erhaelt `PostingDate` automatisch per Schema-Maintenance. +- HANA-B1 liest `DocDate` als Buchungsdatum und `TaxDate` als Fakturadatum. +- Excel/CSV-Import erkennt `posting date`, `Buchungsdatum` und `LineRegistrationDate`. +- Finance-Abgleich filtert das Jahr nach `PostingDate`, mit Fallback auf `InvoiceDate` und danach `ExtractionDate`. +- Finance-Abgleich bevorzugt Nettofakturawert in Hauswaehrung positionsweise. +- Wenn lokale Belegkopfwerte pro Position wiederholt wirken, wird die Ueberzaehlung erkannt: + - B1-Positionswert `SalesPriceValue` wird dann als Positions-Netto bevorzugt. + - deduplizierter Belegkopfwert bleibt als Kandidat sichtbar. +- Intercompany wird weiterhin separat ausgewiesen und nicht still entfernt. + +Verifikation: + +```text +dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\verify_probe_out\ --verbosity minimal +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false --verbosity minimal +``` + +Ergebnis: + +- FinanceProbe Build erfolgreich. +- Tests erfolgreich: `57/57`. +- Bekannte externe Warnung: NuGet-Sicherheitsdaten konnten wegen fehlendem Zugriff auf `api.nuget.org` nicht geladen werden. +- Lokaler Smoke-Test `/finance`: `HTTP 200`. +- Hinweis: Ein bestehender `dotnet`-Prozess sperrt den normalen FinanceProbe-Build-Output. Der Smoke-Test wurde deshalb ohne Rebuild direkt aus dem vorhandenen Output gestartet. + +## H57 - Finance-Entscheide dokumentiert 2026-05-11 + +Quelle: lastchange.md.raw + +## Finance-Entscheide dokumentiert 2026-05-11 + +Neue Doku: + +```text +docs/FINANCE_ENTSCHEIDE.md +``` + +Enthaelt die verbindlichen Financechef-Entscheide: + +- Hauswaehrung ist fuehrend. +- CHF-Umrechnung ueber Budgetkurse. +- Aggregation pro Artikel/Belegposition. +- Net Sales Actuals = Nettofakturawert. +- Jahresabgrenzung ueber Buchungsdatum. +- Gutschriften separat ueber Beleg-/Positionslogik. +- Intercompany/2nd-party separat ausweisen. +- Indien fachlich immer in `INR`. + +## H58 - FinanceProbe / UK Nachdokumentation 2026-05-11 + +Quelle: lastchange.md.raw + +## FinanceProbe / UK Nachdokumentation 2026-05-11 + +Ergaenzt in `docs/FINANCE_ENTSCHEIDE.md`: + +- Pruefstand der Finance-Regeln. +- Testergebnis `58/58`. +- UK/England-Befund: + - `TRUK` + - `1'881` geladene Zeilen + - `395'605.82 GBP` Ist + - `3'749'865.00` Soll + - Differenz `-3'354'259.18` + - Interpretation: vermutlich Teilmenge/Monatsfile statt Jahreswert. +- Offener UK-Entscheid: Monatsdateien aufsummieren oder kumulierten Jahresfile lesen. + +Ergaenzt in `docs/PROGRAMM_DIAGRAMME.md`: + +- FinanceProbe-Start und Hinweis zu Console-Logging. +- Hinweis zu DLL-Sperren durch Visual Studio bzw. alte `dotnet`-Prozesse. + +## H59 - HR KPI Cockpit und Filterkorrektur 2026-05-13 + +Quelle: lastchange.md.raw + +## HR KPI Cockpit und Filterkorrektur 2026-05-13 + +Ergaenzt: + +- Separater HR-KPI-Reiter `/hr-kpi`. +- Dashboard-Tabs fuer Ueberblick, Fluktuation, Absenzen, Zeit/Ferien, Mitarbeitende und Datenstatus. +- Fluktuationsvisuals: Gauge, Funnel, Donut, Organisation-Balken und Monatsbalken. +- Architektur-Cleanup: `HrKpiService` als Fassade, Build-Pipeline in `Services/HrKpi/HrKpiDashboardBuilder.cs`, UI-Tabs in `Components/HrKpi/HrKpiDashboardTabs.razor`. +- Konfigurierbare HR-Dateiquellen ueber `HrKpi` in `appsettings.json`. +- HR-KPI-Regressionstests. + +Korrigiert: + +- `Austrittsjahr` ist jetzt optional. +- Leeres Austrittsjahr bedeutet: alle Austritte. +- Von/Bis-Austritt hat Vorrang vor Austrittsjahr. +- Die Austrittsjahr-Auswahl wird aus den vorhandenen Austrittsdaten aufgebaut. +- `Austrittsjahr` ist beim Start leer statt automatisch aktuelles Jahr. +- Fluktuation nutzt nur vergleichbare Filter auf Mitarbeitenden- und Austrittsdaten. +- Kostenstelle, GLZ und Restferien filtern nicht die Fluktuation, weil die Austrittsdatei diese Felder nicht stabil enthaelt; das Cockpit zeigt dazu einen Hinweis. +- Bei Mehrjahresauswahl wird die Fluktuation als Auswahlwert statt als Jahreswert gefuehrt. +- Fluktuationsvisuals zaehlen distinct nach Personalnummer. +- Fluktuationsraten nutzen nun durchschnittlichen Headcount statt Stichtags-Headcount: Monat, Quartal und Jahr folgen `formeln.docx`. +- Krankenquote nutzt den FTE-Nenner: `Krankheitstage / (FTE * 21 Tage)`. +- Rexx-Austrittsarten mit Umlaut werden korrekt normalisiert: `Kündigung AN` zaehlt als Arbeitnehmerkuendigung, `Kündigung AG` als Arbeitgeberkuendigung-Ausschluss, `Ruhestand` als Pensionierung. + +Nachdokumentation: + +```text +docs/HR_KPI_NACHDOKU_2026-05-13.md +``` + +Verifikation: + +- `dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_app\ --verbosity minimal` +- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_tests\ --verbosity minimal` +- Ergebnis: `69/69` Tests bestanden. +- Kontrollwert `C:\temp\Personalausgeschieden.xlsx`: `104` Austritte total, `42` `Kündigung AN`, `34` `Kündigung AG`, `33` fluktuationsrelevant. +- Kontrollwert neuer Nenner: Avg Headcount 2025 `211.3`, Fluktuation Jahr effektiv `15.6%`. + +## H60 - FinanceProbe Finanzchef-Uebersicht 2026-05-13 + +Quelle: lastchange.md.raw + +## FinanceProbe Finanzchef-Uebersicht 2026-05-13 + +Ergaenzt: + +- Neuer Reiter `Finanzchef Uebersicht` in `Tools/FinanceProbe`. +- Kompakte Soll/Ist-Sicht nur fuer offene Laender. +- Spalten reduziert auf Status, Land, Waehrung, Ist, Soll, Abweichung und Pruefgrund. +- Bestehende Detailtabellen bleiben unveraendert fuer Analyse/Nachvollzug. + +Verifikation: + +- `dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_financeprobe\ --verbosity minimal` +- Ergebnis: Build erfolgreich, `0` Fehler. +- Hinweis: `NU1900` wegen nicht erreichbarer NuGet-Sicherheitsdaten im eingeschraenkten Netzwerk. + +## H61 - Finance CFO Word-Kurzbericht 2026-05-13 + +Quelle: lastchange.md.raw + +## Finance CFO Word-Kurzbericht 2026-05-13 + +Erstellt: + +- `docs/FINANCE_CHEF_SUMMARY_2026-05-13.docx` +- Kurzbericht fuer Finance/CFO mit Kernaussagen und Massnahmen. +- Enthalten: FR, IN, US, AT, ES, UK/EN, DE, CH, IT. +- Ausgeschlossen: GFS und reine 0-/Leer-Faelle ohne operative Aussage. + +Inhaltlicher Fokus: + +- Freigabefaehige Laender: FR, IN, US. +- Kleine/mittlere Klaerung: AT, ES. +- Hohe Prioritaet: UK/EN, DE, CH. +- Kritisch: IT wegen groesster Abweichung und offener Berechnungsart. + +## H62 - Finance CFO Word-Kurzbericht Erweiterung 2026-05-15 + +Quelle: lastchange.md.raw + +## Finance CFO Word-Kurzbericht Erweiterung 2026-05-15 + +Ergaenzt: + +- Aktuelle Fassung: `docs/FINANCE_CHEF_SUMMARY_2026-05-15.docx` +- Erweiterte Tabellenansicht mit Status, Ist, Soll/Rhino, Abweichung, Pruefquelle, Massnahme und Prioritaet. +- Grafische Ampel-Uebersicht fuer OK/Klaeren/Hoch/Kritisch. +- Prioritaetsgrafik fuer IT, DE, UK/EN, CH, AT/ES. +- Abschnitt `Geprueft gegen` mit Rhino/Andreas `check.xlsx`, FinanceProbe/CentralSalesRecords, Spain CSV, Deutschland-Beispielfile und UK_B1. + +Verifikation: + +- DOCX enthaelt `word/document.xml`. +- Inhalte `Rhino / Andreas check.xlsx`, `Management-Ampel`, `Prioritaetsgrafik` und `Laendertabelle mit Massnahmen` wurden im Dokumentpaket geprueft. + +## H63 - Finance Spanien Mailentwurf 2026-05-15 + +Quelle: lastchange.md.raw + +## Finance Spanien Mailentwurf 2026-05-15 + +Erstellt: + +- `docs/FINANCE_ES_MAIL_ABWEICHUNG_2026-05-15.md` +- Spanischer Mailentwurf zur Abweichung Spanien Net Sales 2025. +- Enthaltene Pruefpunkte: Zeitraum, Serien `REG/LAT/PRO/REC`, Abonos/Credit Notes, Datumslogik und verwendetes Netto-Umsatzfeld. + +## H64 - Finance IT und UK Mailentwuerfe 2026-05-15 + +Quelle: lastchange.md.raw + +## Finance IT und UK Mailentwuerfe 2026-05-15 + +Erstellt: + +- `docs/FINANCE_IT_MAIL_ABWEICHUNG_2026-05-15.md` +- `docs/FINANCE_UK_MAIL_ABWEICHUNG_2026-05-15.md` + +Inhalt: + +- Italien: grosse Abweichung `+7.034.496,29 EUR`, Fokus Berechnungsart, Beleg/Position-Deduplizierung, Intercompany, Credit Notes, Datumslogik und Waehrung. +- UK/England: Restdifferenz `-216,154.91 GBP`, Fokus Jahresvollstaendigkeit, Periodenbereich, Credit Notes, Nettofeld, Discounts/Freight/Charges, 2nd-/3rd-party und Waehrung. + +## H65 - Finance Entscheide Extraktion 2026-05-15 + +Quelle: lastchange.md.raw + +## Finance Entscheide Extraktion 2026-05-15 + +Erstellt: + +- `entscheide.md` + +Inhalt: + +- Fragen und Entscheide aus der Finance-Abstimmung extrahiert. +- Festgehaltene Kernentscheide: Hauswaehrung je Land, Budgetkurse fuer CHF-Sicht, Berechnung pro Artikel/Belegposition, Nettofakturawert, Buchungsdatum, separate Gutschriftenausweisung und Intercompany/2nd-party als eigenes Auswahlfeld. +- Intercompany-Marker dokumentiert: `MAGNETS SENSE`, `MAGNETIC SENSE`, `TRAFAG`, `GESELLSCHAFT FUER SENSORIK`, `GESELLSCHAFT FUR SENSORIK`. + +## H66 - Finance Dokumentgueltigkeit 2026-05-15 + +Quelle: lastchange.md.raw + +## Finance Dokumentgueltigkeit 2026-05-15 + +Erstellt: + +- `docs/FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md` + +Festgelegt: + +- Fuehrendes CFO-Dokument: `docs/FINANCE_CHEF_SUMMARY_2026-05-15.docx` +- Alte CFO-Version `docs/FINANCE_CHEF_SUMMARY_2026-05-13.docx` entfernt, weil sie durch die Version vom 2026-05-15 ersetzt wurde. +- Entscheidbasis: `entscheide.md` und `docs/FINANCE_ENTSCHEIDE.md`. + +## H67 - Finance Dashboard Todo 2026-05-15 + +Quelle: lastchange.md.raw + +## Finance Dashboard Todo 2026-05-15 + +Erstellt: + +- `docs/FINANCE_DASHBOARD_TODO_2026-05-15.md` + +Inhalt: + +- Todo-Liste fuer Group Sales Reporting Intranet-Dashboard. +- Priorisierte Punkte fuer CFO-Dokument, offene Laenderabweichungen, Intercompany, Budgetkurse und Berechtigungskonzept. + +## H68 - Navigation und HR-KPI-Zugriff 2026-05-15 + +Quelle: lastchange.md.raw + +## Navigation und HR-KPI-Zugriff 2026-05-15 + +Geaendert: + +- Linke Navigation reduziert: + - Hauptgruppe `Finance Cockpit` + - eigener Hauptpunkt `HR KPI (Login)` +- Bisherige Finance-Seiten liegen als Unterpunkte unter `Finance Cockpit`: + - Dashboard + - Management Cockpit + - Standorte + - Transformationen + - Settings + - Logs +- HR KPI hat eine separate zweite Zugriffssperre mit Name und Passwort. +- HR-Daten werden erst geladen und angezeigt, wenn die HR-KPI-Sperre erfolgreich entsperrt wurde. + +Konfiguration: + +- Abschnitt `HrKpiAccess` in `appsettings.json` +- Benutzer: `hr` +- Passwortvorschlag: `Trafag-HR-KPI-2026!` +- Im Repo ist nur der SHA-256-Hash gespeichert, nicht das Klartextpasswort. + +Verifikation: + +```text +dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_hrlogin\ --verbosity minimal +``` + +Ergebnis: + +- Build erfolgreich. +- 3 bestehende MudBlazor-Analyzer-Warnungen in `Logs.razor`, `Transformations.razor` und `Standorte.razor`. + +## H69 - IIS 500 Diagnose und Hosting-Modell 2026-05-20 + +Quelle: lastchange.md.raw + +## IIS 500 Diagnose und Hosting-Modell 2026-05-20 + +Geaendert: + +- `web.config` fuer IIS auf `hostingModel="outofprocess"` umgestellt. +- `stdoutLogEnabled="true"` bleibt aktiv, Logziel bleibt `.\logs\stdout`. +- `ASPNETCORE_DETAILEDERRORS=true` fuer die temporaere IIS-Fehlerdiagnose gesetzt. +- Ziel: Wenn IIS/ASP.NET Core vor dem App-Start scheitert, sollen eher verwertbare Startlogs entstehen; ausserdem wird die App nicht mehr direkt im IIS Worker-Prozess gehostet. + +Aktueller Stand: + +- Publish-Ordner `\\trch-webapp-bidashboard.trafagch.local\BiDashboard$\` enthaelt `BiDashboard.dll`, `web.config`, `wwwroot`, `runtimes`, `trafag_exporter.db` und `logs`. +- `logs` war trotz aktivem stdout-Logging leer. +- Die veroeffentlichte DLL liess sich vom Publish-Ordner aus starten und brach nicht sofort mit einer Exception ab. +- Remote-Pruefung der installierten .NET-Runtimes per WinRM war nicht moeglich; der Serveradmin muss deshalb am Server pruefen, ob das .NET 8 Hosting Bundle installiert ist. + +Naechste Server-Pruefpunkte: + +- URL `https://trch-webapp-bidashboard.trafagch.local/BiDashboard/diag.txt` testen. +- Wenn `diag.txt` nicht erreichbar ist, stimmt IIS-Anwendung/virtueller Pfad/Binding nicht. +- Wenn `diag.txt` erreichbar ist, aber die App 500 liefert, Windows Event Viewer pruefen: + - Windows Logs > Application + - Quellen: `IIS AspNetCore Module V2`, `.NET Runtime`, `Application Error` +- App Pool pruefen: + - .NET CLR Version: `No Managed Code` + - Pipeline: `Integrated` + - 32-bit Applications: `False` + - Identity muss Modify-Rechte auf Publish-Ordner und `logs` haben. + +## H70 - Architekturreview Static/Hardcoding 2026-05-15 + +Quelle: lastchange.md.raw + +## Architekturreview Static/Hardcoding 2026-05-15 + +Erstellt: + +- `docs/ARCHITEKTUR_REVIEW_STATICS_HARDCODING_2026-05-15.md` + +Inhalt: + +- Bewertung der vielen `static`-Methoden im Code. +- Ergebnis: `static` ist fuer kleine zustandslose Helper akzeptabel; problematisch sind fachliche Regeln und grosse Klassen mit zu vielen Verantwortungen. +- Dokumentierte Befunde: + - HR-Testpersonen sind aktuell Code-Regel und sollten in Konfiguration/DB. + - Finance Vergleich ist aktuell fix auf `2025` und Referenztext. + - Hauswaehrungen je Land sollten langfristig in Finance-/Standortkonfiguration. + - Finance-Sollwerte, Budgetkurse und IC-Regeln sind als Seed okay, aber produktiv pflegbar machen. +- Empfehlung: nicht blind alle `static`-Methoden entfernen, sondern zuerst fachlich veraenderbare Regeln auslagern. + +## H71 - CFO-Bericht IT/Intercompany Diagnose 2026-05-15 + +Quelle: lastchange.md.raw + +## CFO-Bericht IT/Intercompany Diagnose 2026-05-15 + +Ergaenzt: + +- `docs/CFO_Kurzbericht_270515.docx` +- `docs/FINANCE_DASHBOARD_TODO_2026-05-15.md` + +Inhalt: + +- IT/Intercompany-Diagnose fuer die grosse Italien-Abweichung. +- Marker dokumentiert: `TRAFAG`, `MAGNETIC SENSE`, `MAGNETS SENSE`, `GESELLSCHAFT FUER SENSORIK`, `GESELLSCHAFT FUR SENSORIK`. +- Zahlen: + - IT Ist vor IC-Abzug: `14.704.336,29 EUR` + - IC-/2nd-party-Abzug: `4.397.746,90 EUR` + - IT Ist exkl. IC: `10.306.589,39 EUR` + - Rhino/check.xlsx Soll: `7.669.840,00 EUR` + - Restabweichung nach IC: `+2.636.749,39 EUR` + +Bewertung: + +- Intercompany/2nd-party erklaert einen grossen Teil der IT-Abweichung. +- Restabweichung bleibt offen und muss ueber Summenlogik, Beleg/Position-Deduplizierung, Gutschriften/Storno und weitere lokale IC-Kunden oder Schreibweisen geprueft werden. + +## H72 - HR KPI Testpersonen-Ausschluss 2026-05-15 + +Quelle: lastchange.md.raw + +## HR KPI Testpersonen-Ausschluss 2026-05-15 + +Geaendert: + +- Folgende Testpersonen werden zentral aus dem HR-KPI-Dashboard ausgeschlossen: + - Angelina Jolie + - Brad Pitt + - Peter Muster + - ICT Trafag + - Empfanger Reminder / Empfaenger Reminder +- Der Ausschluss erfolgt vor KPI-, Filter- und Tabellenberechnung. +- Betroffen sind aktive Mitarbeitende, Absenzen und Austritte. +- Im Dashboard erscheint eine Notice, wie viele Testpersonen-Zeilen ausgeschlossen wurden. + +Verifikation: + +```text +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_hr_exclusions\ --verbosity minimal +``` + +Ergebnis: + +- 70/70 Tests erfolgreich. +- 3 bestehende MudBlazor-Analyzer-Warnungen in `Logs.razor`, `Transformations.razor` und `Standorte.razor`. + +## H73 - KI-Arbeitsanweisung 2026-05-15 + +Quelle: lastchange.md.raw + +## KI-Arbeitsanweisung 2026-05-15 + +Erstellt: + +- `persona.md` + +Inhalt: + +- Rolle der KI als Entwicklungs-, Analyse- und Dokumentationswerkzeug. +- Grenzen der KI bei fachlicher Verantwortung, Finance, HR, Datenschutz und Freigaben. +- Arbeitsprinzipien fuer dieses Projekt: bestehende Architektur nutzen, kritisch testen, sauber dokumentieren und offene fachliche Punkte als Pruefpunkte markieren. + +## H74 - Navigation in Finance/HR/Admin gegliedert 2026-05-15 + +Quelle: lastchange.md.raw + +## Navigation in Finance/HR/Admin gegliedert 2026-05-15 + +Geaendert: + +- Linke Navigation neu gegliedert: + - `Finance Cockpit` + - `HR KPI (Login)` + - `Admin` +- Unter `Finance Cockpit` stehen: + - `Export Dashboard` + - `Management Analyse` + - `Soll/Ist Vergleich` +- Unter `Admin` stehen: + - `Standorte` + - `Transformationen` + - `Settings` + - `Logs` +- Seitentitel wurden an die neuen Menuebezeichnungen angepasst. + +Verifikation: + +```text +dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_nav_groups\ --verbosity minimal +``` + +Ergebnis: + +- Build erfolgreich. +- 3 bestehende MudBlazor-Analyzer-Warnungen in `Logs.razor`, `Transformations.razor` und `Standorte.razor`. + +## H75 - DE Alphaplan-Excel provisorisch vorbereitet 2026-05-20 + +Quelle: lastchange.md.raw + +## DE Alphaplan-Excel provisorisch vorbereitet 2026-05-20 + +Geaendert: + +- Deutschland wird beim Start als manueller Excel-Standort vorbereitet: + - `TSC = TRDE` + - `Land = Deutschland` + - `SourceSystem = MANUAL_EXCEL` + - `IsActive = false`, damit der Gesamtexport ohne gesetzte Datei nicht scheitert. +- Alphaplan-Mapping wird fuer Deutschland geseedet: + - `NettoPreisGesamtX` -> `SalesPriceValue` + - `Belegnummer`, `Position`, `ArtikelNummer`, `ArtikelBezeichnung` + - `Warengruppen-Bezeichnung`, `Anz. VE` + - Lieferant/Kunde/Land/Branche + - `Waehrung`, `Versandbedingung`, `AdressNummer_V` + - `Belegdatum-Rechnung` fuer Posting-/Invoice-Date + - `DocumentType = Alphaplan Excel` +- Testdatei erhalten und eingeordnet: + - `docs/2025_DataExport_DE.xlsx` + +Erster Befund: + +- `NettoPreisGesamtX` komplett: `4'154'690.05 EUR` +- `Land Kunde = Deutschland`: `3'455'276.64 EUR` +- `Land Kunde = Deutschland + China`: `3'647'592.44 EUR` +- Sollwert DE: `3'635'923.00 EUR` + +Offen: + +- Finance/Munir muss bestaetigen, welche Kundenlaender und Filter in Alphaplan fuer den offiziellen DE-Istwert gelten. +- Manager-Input nennt Warengruppen- und Versandbedingungs-Codes; im Excel sind aktuell vor allem Bezeichnungen/Texte sichtbar. + +Verifikation: + +```text +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_de_alphaplan\ --verbosity minimal +``` + +Ergebnis: + +- 75/75 Tests erfolgreich. +- Bestehende Warnungen: NU1900 wegen lokaler Paket-Sicherheitsdatenabfrage, sowie bekannte MudBlazor-Analyzer-Warnungen zu `Dense`. + +## H76 - Management Cockpit zentrale Filterkopplung 2026-05-15 + +Quelle: lastchange.md.raw + +## Management Cockpit zentrale Filterkopplung 2026-05-15 + +Geaendert: + +- Die untere `Zentrale Roh-Auswertung` im Management Cockpit ist nicht mehr nur global. +- Neue Filterfelder: `Landfilter` und `TSC`. +- Wenn oben eine Einzeldatei analysiert wird, uebernimmt die zentrale Auswertung automatisch Land und TSC aus dieser Datei. +- Beispiel: Auswahl `USA | TRUS | Sales_TRUS_2026-05-08.xlsx` setzt unten automatisch `USA / TRUS`. +- Button `Global` leert die Filter, falls wieder alle Laender/Standorte ausgewertet werden sollen. +- Jahres-, Monats-, Jahreswerte-, Monatswerte-, Tageswerte-, Quellen- und Laendertabellen verwenden denselben Land/TSC-Filter. + +Verifikation: + +```text +dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_management_scope2\ --verbosity minimal +``` + +Ergebnis: + +- Build erfolgreich. +- 3 bestehende MudBlazor-Analyzer-Warnungen in `Logs.razor`, `Transformations.razor` und `Standorte.razor`. + +## H77 - Finance Vergleich als eigener Reiter 2026-05-15 + +Quelle: lastchange.md.raw + +## Finance Vergleich als eigener Reiter 2026-05-15 + +Geaendert: + +- `Net Sales Actuals 2025 Referenz` aus dem Start-Dashboard entfernt. +- Neue Seite `Finance Vergleich` unter `Finance Cockpit` angelegt. +- Route: `/finance-cockpit/vergleich` +- Die Seite zeigt den Soll/Ist-Vergleich gegen `check.xlsx` separat, inklusive IC-Abzug, Referenzwert, Summenfeld, Differenz, Waehrung, Zeilen und Status. +- `DashboardPageService` laedt die Finance-Referenzdaten nicht mehr automatisch mit dem operativen Dashboard. + +Verifikation: + +```text +dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_finance_compare_tab\ --verbosity minimal +``` + +Ergebnis: + +- Build erfolgreich. +- 3 bestehende MudBlazor-Analyzer-Warnungen in `Logs.razor`, `Transformations.razor` und `Standorte.razor`. + +## H78 - Finance-Regeln und Dashboard-Basis-Spalte 2026-05-20 + +Quelle: lastchange.md.raw + +## Finance-Regeln und Dashboard-Basis-Spalte 2026-05-20 + +Geaendert: + +- Neuer Admin-Reiter `Finance Regeln` angelegt. + - Route: `/finance-rules` + - Navigation: `Admin -> Finance Regeln` + - Zugriff wie andere Admin-Seiten ueber `AdminOnly`. +- Neue Tabelle/Model `FinanceRules`. +- Finance-Regeln werden beim Start geseedet und sind danach in der UI pflegbar. +- Die Regeln wirken auf die Finance-Sicht, nicht auf Rohdaten und nicht auf das technische Spaltenmapping. +- DE- und IT-Sonderlogik wurde aus dem zentralen Excel-Export in eine generische Regel-Engine verschoben. +- `ConfigTransferService` exportiert/importiert `FinanceRules` mit. +- `FinanceReconciliationService` nutzt dieselbe Regel-Engine wie das zentrale Excel, damit Soll/Ist-Vergleich und Endexcel dieselbe Finance-Sicht verwenden. +- Export Dashboard: + - neue Spalte `Basis` direkt nach `Land` + - zeigt Datenbasis mit Icon und Text: + - `Excel-Datei` + - `CSV-Datei` + - `SAP Service` + - `Server` + - `Manuelle Datei` + +Aktuelle Default-Finance-Regeln: + +- `DE` + - Jahr auf `2025` erzwingen fuer das Alphaplan-Jahresfile. + - `CustomerName = Trafag AG` ausschliessen. + - `CustomerName contains Magnetic Sense` ausschliessen. + - `InvoiceNumber = GS2510095` ausschliessen, weil bereits 2024 erfasst. + - `InvoiceNumber starts with GS` als negativer Betrag zaehlen. +- `IT` + - `CustomerName contains Trafag Italia` ausschliessen. + - doppelte Zeilen ohne `SupplierCountry` deduplizieren. + +DE-Fachabgleich nach Rueckmeldung Deutschland: + +```text +Gesamtumsatz NettoPreisGesamtX: 4'154'690.05 +- Weiterberechnungen Trafag AG: 391'655.88 +- Weiterberechnungen Magnetic Sense 2025: 55'648.21 +- Gutschriften GS als negativ statt positiv: 28'205.60 doppelte Wirkung +- GS2510095 nicht in 2025: 1'419.70 += DE Jahresabschluss-Umsatz: 3'652'394.46 +``` + +Verifikation: + +```text +dotnet test TrafagSalesExporter.sln --verbosity minimal +``` + +Ergebnis: + +- 76/76 Tests erfolgreich. + +Echter DE-Import und zentrale Excel erneut geprueft: + +```text +CentralSalesRecords DE 2025 rows: 4'430 +CentralSalesRecords DE 2025 SalesPriceValue: 3'652'394.46 +Central Excel Sales sheet Finance DE 2025 sum: 3'652'394.46 +Central Excel Finance Summary DE 2025 sum: 3'652'394.46 +``` + +Technische Hauptdateien: + +- `Models/FinanceRule.cs` +- `Services/FinanceRuleEngine.cs` +- `Services/FinanceRulesPageService.cs` +- `Components/Pages/FinanceRules.razor` +- `Services/ExcelExportService.cs` +- `Services/FinanceReconciliationService.cs` +- `Services/DashboardPageService.cs` +- `Components/Pages/Dashboard.razor` +- `Data/AppDbContext.cs` +- `Services/DatabaseInitializationService.SchemaSql.cs` +- `Services/DatabaseSchemaMaintenanceService.cs` +- `Services/DatabaseSeedService.cs` +- `Services/ConfigTransferService.cs` + +## H79 - Finales zentralisiertes Excel `finall.xlsx` geprueft 2026-05-20 + +Quelle: lastchange.md.raw + +## Finales zentralisiertes Excel `finall.xlsx` geprueft 2026-05-20 + +Gepruefte Datei: + +- `C:\Users\koi\Downloads\finall.xlsx` + +Ergebnis: + +- Datei ist als zentralisierter Export lesbar. +- Blaetter: + - `Finance Summary` + - `Sales` + - `Finance Filter Hilfe` +- `Sales` enthaelt 67'247 Datenzeilen. +- `Finance Summary` stimmt gegen die Finance-Spalten im Blatt `Sales` exakt: + - Differenz je Land/Jahr/Waehrung: `0.00` +- Die Summen entsprechen der lokal erzeugten zentralen Datei `output\Sales_All_2026-05-20.xlsx`. +- Deutschland 2025 bleibt korrekt: + - `DE 2025 EUR = 3'652'394.46` + +Finance-Summen 2025 aus `finall.xlsx`: + +```text +AT EUR 3'438'121.37 +CH CHF 43'521'390.82 +DE EUR 3'652'394.46 +ES EUR 3'082'320.18 +FR EUR 1'471'218.44 +IN INR 750'936'591.38 +IT EUR 7'663'145.76 +UK GBP 3'533'710.09 +US USD 3'749'865.33 +``` + +Hinweis: + +- Der direkte Vergleich gegen die lokale SQLite-Datei `trafag_exporter.db` war nicht aussagekraeftig, weil diese lokale DB keine passenden `CentralSalesRecords` fuer diesen Stand enthaelt. +- Die Excel-interne Summenpruefung und der Vergleich gegen `output\Sales_All_2026-05-20.xlsx` waren konsistent. + +## H80 - Admin Bereich und Startseite aktualisiert 2026-05-21 + +Quelle: lastchange.md.raw + +## Admin Bereich und Startseite aktualisiert 2026-05-21 + +Admin Bereich: + +- `/admin/sessions` ist nicht mehr durch den Finance-Cockpit-Login vorgeschaltet. +- Der Admin Bereich nutzt weiterhin ein eigenes Admin-Passwort über `AdminAccess`. +- Initialer Benutzer: `admin` +- Initiales Passwort: `TrafagAdmin2026!` +- Das Admin-Passwort ist unabhängig vom Finance-Cockpit-Passwort. +- Dokumentation ergänzt: `docs/ADMIN_BEREICH_STARTSEITE_2026-05-21.md` + +Startseite: + +- Corporate-Schrift auf `Open Sans` mit Trafag-nahen Fallbacks angepasst. +- Manometer-Startgrafik bleibt auf weißem Hintergrund, schwarz gezeichnet und mit Trafag-Schriftzug. +- Willkommenstext ist sprachabhängig. +- Optionales Strichmännchen mit Kittel unter dem Willkommenstext ergänzt. +- Das Strichmännchen ist standardmäßig deaktiviert. +- Aktivierung über `Admin Bereich` -> `Strichmännchen anzeigen`. +- Einstellung wird in `appsettings.json` unter `LandingPage.ShowWalkingLabFigure` gespeichert. + +Technische Dateien: + +- `Components/Routes.razor` +- `Components/App.razor` +- `wwwroot/css/app.css` +- `Components/Pages/Dashboard.razor` +- `Components/Pages/AdminSessions.razor` +- `Program.cs` +- `Security/LandingPageOptions.cs` +- `Services/LandingPageSettingsService.cs` +- `Services/UiTextService.cs` +- `appsettings.json` + +## H81 - Nachtrag 2026-05-26: Publish-Fixes, HR-KPI-Upload, Varianten und PDF + +Quelle: lastchange.md.raw + +## Nachtrag 2026-05-26: Publish-Fixes, HR-KPI-Upload, Varianten und PDF + +Deployment / Blazor: + +- Interaktive Blazor-Server-Render-Mode-Deklarationen fuer die routbaren Seiten ergaenzt, damit Buttons und Formulare auf der publizierten IIS-Seite reagieren. +- Navigation auf relative Links umgestellt, damit die Anwendung unter `/BiDashboard` nicht auf Root-URLs ohne PathBase springt. +- Admin-, Finance- und HR-KPI-Login auf serverseitige POST-Endpunkte mit Unlock-Cookies umgestellt, damit Login auch auf der publizierten Seite ohne Blazor-Click-Event funktioniert. +- SAP-HANA Native DLL `libadonetHDB.dll` wird mitpubliziert und `HDBDOTNETCORE` im `web.config` auf den Publish-Ordner gesetzt. + +HR-KPI: + +- Massenupload fuer die fuenf HR-KPI-Dateien direkt im HR-KPI-Cockpit eingebaut. +- Upload-Ziel auf dem Server: `C:\inetpub\wwwcust\BiDashboard\hrdata`. +- Erwartete Dateien: + - `Saldiperstichdatum.xlsx` + - `Exportkommengehen.xlsx` + - `HR_KPI_Export.xlsx` + - `Abwesenheitinstunden.xlsx` + - `Personalausgeschieden.xlsx` +- Allgemeiner Zeitraumfilter `Von Datum` / `Bis Datum` ersetzt die reine Austrittsbeschriftung. +- Fluktuation nutzt den Zeitraum ueber `Austrittsdatum`. +- Absenzquote nutzt den Zeitraum als Nenner mit Arbeitstagen statt fix `21 Tage`. +- Wenn die Rexx-Absenzen selbst Datumsfelder enthalten, werden Absenzen auf den Zeitraum gefiltert. +- Wenn die Rexx-Absenzen keine Datumsfelder enthalten, wird angenommen, dass `Abwesenheitinstunden.xlsx` bereits fuer den gewaehlten Zeitraum exportiert wurde. +- `MudDatePicker` nutzt explizit `de-CH`, damit Eingaben wie `31.03.2026` auf Server und Browser stabil geparst werden. +- PDF-/Druckbuttons je HR-KPI-Reiter ergaenzt, z. B. fuer `Fluktuation`, `Absenzen`, `Ampel`, `Mitarbeitende` und `Datenstatus`. +- Der Druck/PDF-Export rendert nur den jeweiligen Reiterinhalt inkl. Titel, Datenordner und Filterzusammenfassung. +- Serverseitige HR-KPI-Varianten eingefuehrt: + - Speicherdatei: `C:\inetpub\wwwcust\BiDashboard\hrdata\hr-kpi-variants.json` + - letzte Selektion wird serverseitig gespeichert und beim Oeffnen wieder geladen + - Varianten sind fuer alle Benutzer sichtbar + - Varianten koennen gespeichert, geladen, aktualisiert, umbenannt und geloescht werden +- Initiale Testvarianten fuer HR wurden auf dem Server angelegt: + - `Fluktuation Q1 2026` + - `Fluktuation Jahr 2026` + - `Absenzquote Q1 2026` + +Firewall / Betrieb: + +- Aktueller HANA-Fehler nach DLL-Fix ist Netzwerk/Firewall, nicht mehr SAP-DLL: + - Webserver: `10.120.1.17` + - HANA Internal: `10.194.65.22:30015` + - India HANA: `20.197.20.60:30015` + - SAP OData: `10.194.64.29:8000` + - SharePoint: `trafagag.sharepoint.com:443` +- Support-Mail an externen Support vorbereitet; Freigabe muss vom Webserver zu den Zielsystemen erfolgen. + +Validierung: + +- `dotnet build .\TrafagSalesExporter.csproj --no-restore --verbosity minimal` erfolgreich. +- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore --verbosity minimal` erfolgreich mit `78/78` Tests. +- Mehrfach erfolgreich nach `\\trch-webapp-bidashboard.trafagch.local\BiDashboard$\` publiziert. + +## H82 - Nachtrag 2026-05-26: Nachdokumentation Remote-/Refactoring-Commits + +Quelle: lastchange.md.raw + +## Nachtrag 2026-05-26: Nachdokumentation Remote-/Refactoring-Commits + +Beim Rebase auf `origin/main` wurden zusaetzliche lokal noch nicht vorhandene Commits integriert. Der lokale Stand und `origin/main` sind danach synchron. + +Finance Details / Export: + +- Finanzdetail-Export und erweiterte Uebersetzungen wurden ergaenzt. +- Betroffene Bereiche: + - `Services/ExcelExportService.cs` + - `Services/ConsolidatedExportService.cs` + - `Services/SharePointUploadService.cs` + - `Services/UiTextService.cs` + - `Components/Layout/MainLayout.razor` + - `Components/Layout/NavMenu.razor` +- Tests fuer Excel-Export und UI-Texte wurden erweitert. +- SharePoint-Upload-Schnittstelle wurde leicht angepasst. + +In-App-Training / Anwenderdoku: + +- Neue Trainingsseiten in der Anwendung: + - `Components/Pages/FinanceTraining.razor` + - `Components/Pages/HrKpiTraining.razor` + - `Components/TrainingSection.razor` +- Navigation um Trainingseintraege ergaenzt. +- Neue Trainingsassets: + - `wwwroot/training/systemarchitektur.svg` + - `wwwroot/training/keyuser-prozess.svg` + - `wwwroot/training/finance_cockpit_preview.png` + - `wwwroot/training/hr_kpi_cockpit_preview.png` +- Aktualisierte Anwenderdokumente: + - `docs/FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx` + - `docs/HR_KPI_ANLEITUNG_HR_2026-05-20.docx` + - `docs/MANUAL_IMPORT_DELTA_STAND_2026-05-21.md` + +Lokaler Dev-Server / Uebergang: + +- `launchSettings.json` wurde fuer den lokalen Uebergang angepasst. +- Doku ergaenzt: + - `docs/LOCAL_DEV_SERVER_UEBERGANG_2026-05-21.md` + - `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` +- Ziel: lokal lauffaehige Umgebung dokumentieren, falls IIS/Publish nicht erreichbar ist. + +Admin / Startseite: + +- Admin-Bereich wurde von Finance-Login getrennt. +- Startseite/Landing-Dashboard und Admin-Sessions wurden erweitert. +- Doku: + - `docs/ADMIN_BEREICH_STARTSEITE_2026-05-21.md` +- Relevante technische Bereiche: + - `Components/AdminAccessPanel.razor` + - `Components/Pages/AdminSessions.razor` + - `Security/AdminAccessOptions.cs` + - `Services/AdminAccessService.cs` + - `Services/AccessSessionTracker.cs` + - `Services/AccessPasswordSettingsWriter.cs` + - `Security/LandingPageOptions.cs` + - `Services/LandingPageSettingsService.cs` + +Trading Engine: + +- Ein Python-Trading-Engine-Paket wurde unter `trade_web` ergaenzt. +- Dateien: + - `trade_web/trading_engine.py` + - `trade_web/trading_engine/__init__.py` +- Zweck laut Commit-Historie: Trading-Cockpit-Engine als importierbares Paket bereitstellen. +- Dieser Bereich ist separat vom TrafagSalesExporter/.NET-BI-Dashboard zu betrachten. + +Aktueller Git-Stand: + +- Rebase auf `origin/main` erfolgreich. +- Neuer Head nach Rebase und Push: `d853f53 Add published HR KPI workflow fixes`. +- `HEAD` und `origin/main` sind synchron. +- Lokal unversioniert bleiben nur Arbeitsartefakte/Screenshots: + - `../BiDashboard/` + - `error.png` + - `it_export_result.html` + - `italien.png` + +## H83 - Next Steps + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +# Next Steps + +Stand: 2026-05-20 + +RAG-Hinweis: Fuer tokenarme Weiterarbeit zuerst `docs/RAG_ROUTER.md` laden. Diese Datei nur lesen, wenn die Kurzdatei `docs/rag/PROJECT.md` nicht reicht. + +## H84 - Nachtrag 2026-05-20 Dokumentation bereinigt + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-20 Dokumentation bereinigt + +Erledigt: + +- Markdown-Bestand eingeordnet in `docs/MD_DOKUMENTENSTATUS_2026-05-20.md`. +- HR-Anwenderdoku als Word-Datei optisch ueberarbeitet: + - `docs/HR_KPI_ANLEITUNG_HR_2026-05-20.docx` + - inklusive 10 neuer HR-Cockpit-Punkte, Tabellen, Hinweisboxen und Vorschaugrafik. +- Finance-Anwenderdoku als Word-Datei optisch ueberarbeitet: + - `docs/FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx` + - inklusive Finance Summary Workflow, Filterregeln und Pruefpunkten. +- Neue neutrale Vorschaubilder fuer die Word-Dokus: + - `docs/hr_kpi_cockpit_preview.png` + - `docs/finance_cockpit_preview.png` + +Bewusst nicht geloescht: + +- Alte Markdown-Dateien und alte Eintraege bleiben erhalten, wenn sie Pruefwerte, Zwischenentscheide, Mailkontext oder Audit-Spuren enthalten. +- Nicht mehr fuehrende Dateien sind in `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` als historisch markiert. + +## H85 - Nachtrag 2026-05-20 Workflow-Fixes nach Review + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-20 Workflow-Fixes nach Review + +Umgesetzt: + +- Dashboard warnt vor aktiven manuellen Standorten ohne Datei. +- Nach Einzelstandortexport wird sichtbar, dass die zentrale Excel neu erzeugt werden muss. +- Dashboard erkennt eine veraltete zentrale Excel nach neuem Standortexport. +- Neuer Menuepunkt `Manuelle Importe` fuer Keyuser. +- `Manuelle Importe` hat jetzt die Reiter `Importdateien` und `Anleitung`. +- Der Reiter `Anleitung` zeigt den Upload-/Export-/Zentraldatei-/Finance-Pruefprozess grafisch. +- Zentrale Excel hat ein Blatt `Finance Summary`. +- `Management Analyse` ist als Rohdaten-/Plausibilitaetssicht markiert. +- `Soll/Ist Vergleich` ist als verbindliche Finance-Sicht markiert. +- Export-Live-Status ist nicht mehr pauschal `HANA Abfrage...`. + +Weiterhin offen: + +- DE Alphaplan-Fachabgrenzung: Kundenlaender/Filter muessen von Munir/Finance bestaetigt werden. + +## H86 - Nachtrag 2026-05-20 Keyuser Prozess-SVG + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-20 Keyuser Prozess-SVG + +Erstellt: + +```text +docs/KEYUSER_PROZESSDOKU_2026-05-20.svg +``` + +Zielgruppe: + +- Finance Keyuser / Poweruser. + +Inhalt: + +- Vorbereitung in Settings und Standorte. +- Manual-Excel-Dateien fuer UK/ES/DE. +- Einzelstandortexport, Export aller Standorte und zentrale Excel. +- Finance-Filter im Endexcel. +- Soll/Ist Vergleich, Management Analyse, Logs. +- Fehlerbehandlung und fachliche Freigabe. + +## H87 - Nachtrag 2026-05-20 Technische Architektur-SVG + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-20 Technische Architektur-SVG + +Erstellt: + +```text +docs/SYSTEMARCHITEKTUR_TECHNISCH_2026-05-20.svg +``` + +Zielgruppe: + +- Systemarchitekt / Serveradmin / technischer Projektkontext. + +Abgrenzung: + +- Nur produktive Applikation. +- Keine Testapp, Probe-Tools oder temporaeren Analyseprogramme. + +Status: + +- Keyuser-Prozessdoku wurde als separate SVG erstellt. + +## H88 - Nachtrag 2026-05-20 DE Alphaplan-Excel provisorisch eingebaut + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-20 DE Alphaplan-Excel provisorisch eingebaut + +Erledigt: + +- Deutschland wird als manueller Excel-Standort vorbereitet: + - `TSC = TRDE` + - `Land = Deutschland` + - `SourceSystem = MANUAL_EXCEL` + - neuer Standort ist standardmaessig inaktiv, damit Export-All nicht ohne Datei scheitert +- Alphaplan-Mapping wird automatisch geseedet: + - `NettoPreisGesamtX` -> `SalesPriceValue` + - `Belegnummer` -> `InvoiceNumber` + - `Position` -> `PositionOnInvoice` + - `ArtikelNummer` -> `Material` + - `ArtikelBezeichnung` -> `Name` + - `Warengruppen-Bezeichnung` -> `ProductGroup` + - `Anz. VE` -> `Quantity` + - `Name/Land Lieferant`, `Name/Land Kunde`, `Branche`, `Versandbedingung` + - `Belegdatum-Rechnung` -> `PostingDate` und `InvoiceDate` + - `DocumentType = Alphaplan Excel` +- Datei erhalten: + +```text +docs/2025_DataExport_DE.xlsx +``` + +Bedienung: + +1. App starten. +2. `Standorte` oeffnen. +3. Deutschland / `TRDE` oeffnen. +4. Alphaplan-Excel hochladen oder Pfad setzen. +5. Standort aktivieren. +6. Standortexport fuer DE ausfuehren. +7. Danach zentrale Excel erzeugen; DE ist dann in `CentralSalesRecords` und im Endexcel enthalten. + +Offen fachlich: + +- Komplette Summe `NettoPreisGesamtX`: `4'154'690.05 EUR`. +- Nur `Land Kunde = Deutschland`: `3'455'276.64 EUR`. +- Sollwert DE: `3'635'923.00 EUR`. +- Finance/Munir muss bestaetigen, welche Kundenlaender oder Filter zum offiziellen DE-Ist gehoeren. + +## H89 - Nachtrag 2026-05-20 IIS 500 aktueller Stand + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-20 IIS 500 aktueller Stand + +Vollstaendige Doku: + +```text +docs/DEPLOYMENT_IIS_HANDOFF_2026-05-19.md +``` + +Was sicher bewiesen ist: + +- `https://trch-webapp-bidashboard.trafagch.local/BiDashboard/diag.txt` ist erreichbar. +- Browser zeigt dort: + +```text +BiDashboard publish folder reached 2026-05-20T08:19:14.2667783+02:00 +``` + +- Damit stimmt IIS-URL `/BiDashboard` und der Physical Path zum Publish-Ordner. +- Der verbleibende `500` ist kein falscher Pfad und kein HTTP/HTTPS-Verwechslungsproblem. + +Was umgesetzt wurde: + +- Publish weiterhin aus `TrafagSalesExporter`. +- Ausgabe weiterhin `BiDashboard.dll`, keine EXE. +- `web.config` auf `hostingModel="outofprocess"` umgestellt. +- `stdoutLogEnabled="true"` bleibt aktiv. +- `ASPNETCORE_DETAILEDERRORS=true` fuer Diagnose gesetzt. +- Neu publiziert auf `\\trch-webapp-bidashboard.trafagch.local\BiDashboard$\`. + +Offen fuer Server-Spezialist: + +- .NET 8 Hosting Bundle / AspNetCoreModuleV2 pruefen. +- App Pool pruefen: + - `.NET CLR Version = No Managed Code` + - `Managed Pipeline Mode = Integrated` + - `Enable 32-bit Applications = False` +- Event Viewer lesen: + - `IIS AspNetCore Module V2` + - `.NET Runtime` + - `Application Error` +- App-Pool-Identity mit `Modify` auf Publish-Ordner, `logs` und `trafag_exporter.db*` bestaetigen. + +Wichtig: + +- Der Server braucht kein installiertes Microsoft Excel. +- XLSX wird ueber ClosedXML/OpenXML gelesen. +- CSV-Umstellung ist fuer diesen 500-Fehler nicht noetig. + +## H90 - Nachtrag 2026-05-20 IT Finance-Methode + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-20 IT Finance-Methode + +Erledigt: + +- IT-Methode gemaess Finance-Leiter umgesetzt. +- `CustomerName` enthaelt `Trafag Italia` wird fuer IT ausgeschlossen. +- Doppelte IT-Zeilen mit leerem `Supplier country` werden nur einmal gezaehlt. +- Regel greift im Finance-Vergleich/Testprogramm und in den Finance-Spalten der zentralen Excel. + +Bewusster Entscheid: + +- Die alte 2025-Kombination ist naeher am Soll, aber fachlich nicht zukunftssicher. +- Fuer 2026+ gilt die neue Methode, auch wenn sie 2025 in der aktuellen DB weiter vom Sollwert abweicht. + +Naechster Check: + +- Nach neuem IT-Export pruefen, ob die vollstaendige `Trafag Italia`-Summe aus den neuen Rohdaten sichtbar wird. +- Zentrale Excel fuer `Finance | Country Key = IT`, `Finance | Include = TRUE` filtern und gegen Finance-Vergleich kontrollieren. + +## H91 - Nachtrag 2026-05-19 IIS Deployment / 500 Fehler + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-19 IIS Deployment / 500 Fehler + +Vollstaendige Doku: + +```text +docs/DEPLOYMENT_IIS_HANDOFF_2026-05-19.md +``` + +Aktueller Stand: + +- Publish erfolgt direkt aus `TrafagSalesExporter`. +- Publish-Ausgabe ist an das alte `BiDashboard` angepasst: + - `BiDashboard.dll` + - keine EXE + - `web.config` startet `.\BiDashboard.dll` + - Diagnose aktiv mit `stdoutLogEnabled=true` +- URL mit App-Pfad liefert laut Browser `500`: + +```text +https://trch-webapp-bidashboard.trafagch.local/BiDashboard/ +``` + +Wahrscheinlichstes offenes Thema: + +- App-Pool/IIS hat auf dem Publish-Ordner nur Lesen/Ausfuehren. +- Die App schreibt beim Start in SQLite (`trafag_exporter.db`, `db-shm`, `db-wal`) und in `logs`. +- `icacls`-Versuch von lokal wurde vom Server mit `Zugriff verweigert` abgelehnt. + +Naechster Schritt fuer Server-Spezialist: + +- App-Pool-Identity ermitteln. +- `Modify` auf Publish-Ordner, `logs` und `trafag_exporter.db*` setzen. +- App-Pool neu starten. +- Danach URL neu testen und bei weiterem `500` stdout-Log/Event Viewer lesen. + +## H92 - Nachtrag 2026-05-19 Finance-Cockpit-Login finalisieren + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-19 Finance-Cockpit-Login finalisieren + +Aktueller Stand: + +- Finance Cockpit hat einen separaten Login. +- HR-KPI-Login und Finance-Cockpit-Login sind technisch getrennte Services/Konfigurationen. +- Finance-Konfiguration liegt in `appsettings.json` unter `FinanceCockpitAccess`. +- Aktueller Benutzer: `finance`. +- Finance nutzt ein eigenes Passwort: `Trafag-Finance-Cockpit-2026!`. +- Globale AD-/Rollenpruefung ist fuer den Moment mit `Security.Enabled = false` deaktiviert. +- Die AD-Gruppen sind nicht geloescht und bleiben in `AccessGroups`/`AdminGroups` dokumentiert. + +Wichtig: + +- Finance- und HR-KPI-Sperren laufen weiter ueber eigene Passwortabfragen. +- AD/Rollen koennen spaeter durch `Security.Enabled = true` wieder aktiviert werden. + +Noch offen: + +1. Entscheiden, wann AD-/Rollenpruefung wieder aktiviert wird. +2. Bei Reaktivierung `Security.Enabled` auf `true` setzen und Gruppen pruefen. +3. Pruefen, ob direkte Run-/Export-/FinanceProbe-Endpunkte ebenfalls geschuetzt werden muessen. +4. In Browser testen: + +```text +http://127.0.0.1:5099/finance-cockpit/vergleich +``` + +5. Nach Entsperren pruefen, dass Navigation und `Finance sperren` korrekt funktionieren. + +## H93 - Nachtrag 2026-05-19 Finance-Vergleich / Formeldoku + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-19 Finance-Vergleich / Formeldoku + +Erledigt: + +- `/finance-cockpit/vergleich` nutzt dieselbe `FinanceReconciliationService`-Logik wie die FinanceProbe. +- Leere Ist-Zeilen werden in der Haupt-App ausgefiltert. +- Berechnungslogik pro Land wurde dokumentiert: + +```text +docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md +``` + +Naechster Check: + +- Bei neuer Datenladung `/finance-cockpit/vergleich` und `/finance` gegeneinander vergleichen. +- Besonders ES, AT, UK und IT weiter fachlich klaeren. + +## H94 - Nachtrag 2026-05-19 Zentrale Excel fuer Finance-Filter + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-19 Zentrale Excel fuer Finance-Filter + +Erledigt: + +- Die zentrale Excel `Sales_All_yyyy-MM-dd.xlsx` enthaelt im Blatt `Sales` einen Finance-Spaltenblock: + +```text +Finance | Year +Finance | Country Key +Finance | Date +Finance | Net Sales Actual +Finance | Currency +Finance | Include +Finance | Source Value Field +``` + +- Die zentrale Excel enthaelt ein Hilfsblatt `Finance Filter Hilfe`. +- Das Hilfsblatt erklaert, wie Finance dieselben Ist-Summen wie im Testprogramm erhaelt: + +```text +Finance | Year = 2025 +Finance | Country Key = Land +Finance | Include = TRUE +Summe Finance | Net Sales Actual +``` + +Geprueft: + +- Excel-Finance-Spalten wurden gegen `FinanceReconciliationService` fuer 2025 verglichen. +- AT, CH, ES, FR, IN, IT, UK und US ergaben jeweils `MATCH` mit Differenz `0.00`. + +Naechster praktischer Check: + +- Nach dem naechsten echten Export die SharePoint-Datei `Sales_All_yyyy-MM-dd.xlsx` oeffnen und mit Finance die Filter-/Summenlogik einmal gemeinsam durchgehen. +- Dabei darauf achten, dass nicht versehentlich alte Spalten wie `Land`, `TSC`, `Document Total LC` oder `Sales Price/Value` direkt fuer CFO-Summen verwendet werden. + +## H95 - Nachtrag 2026-05-11 UK_B1 Mapping fertigstellen + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-11 UK_B1 Mapping fertigstellen + +Aktueller Stand: + +- UK/England bleibt auf Quelle `UK_B1`. +- Korrekte Quelle: + +```text +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1 +``` + +- Ursache der grossen UK-Abweichung: + - kein grafisches Mapping fuer `TRUK` + - `Sales Price/Value` wurde als Positionswert gelesen + - in UK_B1 ist es nach aktuellem Befund ein Stueckpreis + - korrekte Formel ist `=[Sales Price/Value]*[Quantity]` + +Bereits im Worktree umgesetzt: + +- `ManualExcelImportService` kann berechnete Mapping-Quellen `=[Header A]*[Header B]`. +- `DatabaseSeedService` seedet/repariert UK_B1-Pfad und `TRUK`-Mapping. +- `DatabaseSeedService` ueberspringt den UK-Mapping-Seed, solange `ManualExcelColumnMappings` noch auf eine alte SQLite-Reparaturtabelle wie `Sites_repair_old` zeigt. +- Unit-Test fuer berechnetes Manual-Excel-Mapping ist vorhanden. +- Doku wurde in `docs/FINANCE_ENTSCHEIDE.md`, `lastchange.md` und `HANDOFF_2026-04-15.md` ergaenzt. +- Tests sind gruen: `59/59`. + +Verifizierter Testlauf: + +```text +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false --verbosity minimal +``` + +Noch offen fuer den praktischen UK-Check: + +1. SharePoint-/Graph-Zugriff reparieren. + - letzter Fehler bei `/run/export/TRUK`: + +```text +ClientSecretCredential authentication failed +127.0.0.1:9 connection refused +``` + +2. UK neu exportieren: + +```text +http://127.0.0.1:5099/run/export/TRUK +``` + +3. Finance pruefen: + +```text +http://127.0.0.1:5099/finance +``` + +4. Ergebnis bewerten: + - wenn UK nahe `3'749'865 GBP` liegt: Mapping war Hauptursache. + - wenn UK bei ca. `3'533'349 GBP` bleibt: Restdifferenz gegen weitere UK-Netto-/Discount-/Frachtspalten pruefen. + +Nicht vergessen: + +- Keine harte Spezialkorrektur fuer genau 2025 einbauen. +- Die Loesung muss ueber Mapping und allgemeine Positionslogik laufen, damit andere Jahre ebenfalls korrekt funktionieren. + +## H96 - Nachtrag 2026-05-08 Manual Excel/CSV SharePoint-Automatik + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-08 Manual Excel/CSV SharePoint-Automatik + +Erledigt: + +- SharePoint-Ordner koennen bei Manual Excel/CSV als Quelle hinterlegt werden. +- Bei Ordnern wird automatisch die neueste passende `.xlsx`/`.csv` ausgewaehlt. +- Dateinamenmuster fuer bevorzugte Auswahl: `ddMMyy_TSC.xlsx` bzw. `ddMMyy_TSC.csv`. +- Manual-Export schreibt die erzeugte Exportdatei in den Quellordner zurueck: + - lokal: gleicher lokaler Ordner + - SharePoint: gleicher SharePoint-Ordner +- England/TRUK ist lokal auf den SharePoint-Ordner `Import/Finance/UK_B1` korrigiert. +- Spanien-Fehler nach erfolgreichem Einlesen der SharePoint-CSV ist behoben. + +Naechste konkrete Schritte: + +1. App neu starten, damit die Seed-/Repair-Logik aktiv ist. +2. England/TRUK exportieren und pruefen, ob die App `010526_TRUK.xlsx` statt `010426_TRUK.xlsx` auswaehlt. +3. Im SharePoint-Ordner `Import/Finance/UK_B1` pruefen, ob die neue Exportdatei dort wieder abgelegt wird. +4. Deutschland/Alphaplan: im Standort den korrekten Alphaplan-Excel- oder SharePoint-Pfad hinterlegen. +5. Deutschland exportieren und Mapping gegen die Alphaplan-Datei validieren. +6. Falls UK-Dateinamen spaeter ein anderes Muster bekommen, Auswahlregel erweitern. + +## H97 - Nachtrag 2026-05-08 FinanceProbe + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-08 FinanceProbe + +Erledigt: + +- FinanceProbe zeigt alle Finance-Referenzen 2025. +- Datenabdeckung je Standort wurde ergaenzt. +- CH/AT-Zuordnung wurde fuer `ZSCHWEIZ` geschaerft. + +Naechste fachliche Schritte: + +1. Nach Export von England, Schweiz/Oesterreich, Spanien und Deutschland die FinanceProbe neu laden. +2. In der Sektion `Datenabdeckung je Standort` pruefen, ob Zeilen 2025 und Periode plausibel sind. +3. Fuer Laender mit `Keine Daten` entscheiden: + - Datenquelle fehlt + - Standort deaktiviert + - Mapping/Export noch nicht gelaufen + - Referenz ist nur zukuenftig relevant +4. Fuer AT/CH nach `ZSCHWEIZ`-Export pruefen, ob `LAND1` korrekt `AT` bzw. `CH` liefert. + +## H98 - Nachtrag 2026-05-11 FinanceProbe KI-Steuerung + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-11 FinanceProbe KI-Steuerung + +Neue Test-Routen: + +- `/run/export/{siteKey}` fuer Einzelstandortexporte +- `/run/export-all` fuer alle aktiven Standorte plus zentrale Datei +- `/run/consolidated` fuer nur zentrale Datei + +Naechster sinnvoller Prueflauf: + +1. FinanceProbe starten. +2. `/run/export/TRUK` fuer England testen. +3. `/run/export/Spanien` testen. +4. `/run/export/Deutschland` testen, sobald Alphaplan-Pfad korrekt ist. +5. `/run/export/ZSCHWEIZ` testen. +6. Danach `/finance` und `docs/finance_status_2025.svg` aktualisieren. + +## H99 - Nachtrag 2026-05-07 nach Mapper-/Finance-Aufraeumung + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-07 nach Mapper-/Finance-Aufraeumung + +Erledigt: + +- SAP-OData- und HANA-Mapping laufen ueber `MappedSalesRecordComposer`. +- Doppelte SAP-Mapping-Normalisierung wurde entfernt. +- Konsolidierter Export liest eindeutig aus `CentralSalesRecords`. +- Manuelle Standortdateien duerfen `.xlsx` oder `.csv` sein. +- Finance-Sollwerte, Budgetkurse und Intercompany-Regeln sind DB-Konfiguration mit Seed. + +Naechste technische Schritte: + +1. App neu starten, damit Schema/Seed fuer `FinanceReferences`, `FinanceIntercompanyRules` und Budgetkurse laeuft. +2. In Settings Konfiguration exportieren und pruefen, ob Finance-Referenzen und IC-Regeln enthalten sind. +3. Fuer produktive Pflege spaeter eine kleine UI fuer `FinanceReferences` und `FinanceIntercompanyRules` bauen. +4. Manual Excel als naechsten Aufraeumpunkt vereinheitlichen: Header-Automatik und grafisches Mapping in eine gemeinsame Mapping-Engine ziehen. +5. Bestehende BI1/SAGE-Standorte mittelfristig auf grafisches HANA-Mapping migrieren; erst danach den alten B1-Spezialpfad entfernen. + +## H100 - Nachtrag 2026-05-07 ZSCHWEIZ ueber SAP OData + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-07 ZSCHWEIZ ueber SAP OData + +Finaler Stand fuer Schweiz/Oesterreich: + +- ABAP-Report `report.abap` fuellt SAP-Tabelle `ZSCHWEIZ`. +- Buchungskreis `1100` = Schweiz, `1200` = Oesterreich. +- `LAND1` in `ZSCHWEIZ` ist Reporting-Land aus Buchungskreis. +- `CUSTOMER_LAND` ist Kundenland aus `KNA1-LAND1`. +- Die App liest `ZSCHWEIZ` ueber SAP OData, nicht ueber direkten HANA-Spezialcode. + +In der App: + +- Quellsystem-Code `SAP` bleibt bestehen, DisplayName jetzt `SAP OData`. +- `SAP_HANA` ist nur fuer direkte HANA-Tabellen/Views und heisst `SAP HANA Tables/Views`. +- Der grafische Mapper funktioniert fuer SAP OData und fuer HANA-Tabellen/Views. +- Vorkonfigurierter Standort: + - `TSC = ZSCHWEIZ` + - `Land = Schweiz/Oesterreich` + - `SourceSystem = SAP` + - Quelle `Z` + - EntitySet `ZSCHWEIZSet` +- Quelle und Feldmapping werden beim App-Start per Seed-/Repair-Logik nachgezogen, auch wenn der Standort bereits existiert. + +Naechste Schritte: + +1. App neu starten, damit die Seed-/Repair-Logik laeuft. +2. In `Settings -> Quellsysteme` pruefen, ob `SAP` als `SAP OData` angezeigt wird. +3. In `Standorte` den Standort `ZSCHWEIZ` oeffnen. +4. Falls die zentrale SAP-Service-URL noch auf `ZPOWERBI_EINKAUF_SRV` zeigt, beim Standort `SAP Service URL Override` auf den finalen OData-Service fuer `ZSCHWEIZ` setzen. +5. `Entity Sets refreshen`. +6. Quelle `Z` auf `ZSCHWEIZSet` kontrollieren. +7. `Felder aus Quellen laden`. +8. Grafisches Mapping kontrollieren; manuell mappen musst du nur, wenn Gateway-Feldnamen vom erwarteten `ZSCHWEIZ`-Layout abweichen. +9. Standort aktivieren und Export testen. + +Keine manuelle Feldliste ist noetig, wenn der Gateway-Service `$metadata` korrekt liefert. + +## H101 - Nachtrag 2026-05-05 Abschlussstand FinanceProbe / Spanien / Deutschland + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-05-05 Abschlussstand FinanceProbe / Spanien / Deutschland + +Aktueller lokaler Testpunkt: + +```text +http://localhost:55417/finance +``` + +FinanceProbe enthaelt jetzt: + +- `Meeting Ampel 2025` fuer alle Laender aus `check.xlsx` +- Ampel: + - Gruen: rechnerisch passend + - Gelb: Differenz oder fachliche Abgrenzung offen + - Grau: keine belastbaren Ist-Daten +- `Detail alle Laender` +- `Spain CSV direct check` +- `Germany Excel sample check` + +Spanien: + +- finale v2-Datei liegt unter `sagespain/v2/Spain_Sales_2025.csv` +- Zeilen: `4'341` +- Ist `SalesPriceValue`: `3'082'320.18` EUR +- Soll aus `check.xlsx`: `3'102'333.61` +- Differenz: `-20'013.43` +- Status: Gelb / Pruefen +- Export technisch lesbar, Differenz fachlich mit Spanien/Finance klaeren + +Deutschland: + +- Beispielfile liegt im Projektordner: + +```text +DE_Beispiel_Export_Daten.xlsx +``` + +- relevante Spalte: `NettoPreisGesamtX` +- Mapping-Ziel: `SalesPriceValue` +- Betragszeilen: `2` +- Summe: `8'290.70` EUR +- das ist nur ein Sample, keine finale DE-Jahreszahl +- Deutschland bleibt fuer die finale Ampel offen/grau, bis ein vollstaendiger DE-Jahresfile 2025 oder ein bestaetigter Importlauf vorliegt + +Offen fuer das Finance-Meeting / danach: + +1. Spanien Differenz `-20'013.43` klaeren: + - Periodendatum + - Serien `REG`, `LAT`, `PRO`, `REC` + - Gutschriften / `REC` + - offizielle Sage-Auswertung mit identischem Filter +2. Deutschland finalen Jahresfile 2025 anfordern oder Importlauf mit finaler Datei ausfuehren. +3. Fuer Laender mit Grau pruefen, ob Exportdaten fehlen oder Standort deaktiviert/ohne Datei ist. +4. Fuer CHF-Aussage beachten: + - CHF nur direkt, wenn Quelle CHF liefert + - sonst Mandanten-/Originalwaehrung und separate FX-Regel noetig + +Letzte Verifikation: + +```text +dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal --no-restore +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal --no-restore +``` + +Ergebnis: + +- FinanceProbe Build erfolgreich +- Tests erfolgreich +- `50/50` Tests gruen +- Web UI `HTTP 200` + +## H102 - Nachtrag 2026-04-29 Dashboard-Referenzcheck + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-04-29 Dashboard-Referenzcheck + +Das Dashboard enthaelt jetzt oben einen `Net Sales Actuals 2025`-Referenzcheck gegen die Zahlen aus `check.xlsx` / Power BI Stand 2026-04-29. + +Technischer Stand: + +- Ist-Wert wird automatisch aus dem besten Kandidaten gegen die Referenz gewaehlt: + - `SalesPriceValue` + - `DocumentTotalForeignCurrency - VatSumForeignCurrency` + - `DocumentTotalLocalCurrency - VatSumLocalCurrency` +- Belegkopfwerte werden per `TSC` + `DocumentType` + `DocumentEntry` dedupliziert; Fallback ist `InvoiceNumber` +- Jahr 2025 ueber `InvoiceDate`, fallback `ExtractionDate` +- Vergleich gegen Power-BI-Wert, falls vorhanden, sonst LC-Referenz +- Dashboard zeigt das verwendete `Summenfeld` + +Noch fachlich zu pruefen: + +- IT bleibt als bekannter `not ok`-Fall offen +- UK/US bleiben offen, bis die richtige Quelle bzw. Config geklaert ist +- bei weiteren Standorten erst Referenzwert und Datenquelle bestaetigen +- bestehende zentrale Altdaten enthalten fuer die neuen B1-Felder noch `0`; fuer den echten Feldvergleich ist ein neuer Export/Rebuild noetig + +Konkreter Ablauf nach Neustart/PC-Absturz: + +1. App starten und Dashboard oeffnen: `http://localhost:55416` +2. `Alle exportieren` ausfuehren oder betroffene Standorte einzeln exportieren. +3. Danach `Zentrale Datei neu erzeugen` ausfuehren. +4. Im oberen Dashboard-Block `Net Sales Actuals 2025 Referenz` die Spalte `Summenfeld` kontrollieren. +5. Wenn `Status = OK`, passt die Summe zur hinterlegten Referenz. +6. Wenn `Status = Pruefen`, zuerst kontrollieren: + - richtige Standortquelle/Config + - richtiges Jahr + - ob nach der Codeaenderung wirklich neu exportiert wurde + - ob das gewaehlte Summenfeld fachlich Sinn macht + +Naechster technischer Schritt fuer neue Jahre: + +- Jahresauswahl im Dashboard einbauen. +- Fuer Jahre ohne Referenz trotzdem Ist-Summen und verwendetes Summenfeld anzeigen. +- Sobald eine neue Referenzdatei fuer 2026/2027 vorliegt, Referenzwerte ergaenzen. + +Export-all-Abbruch am 2026-04-29: + +- Fehler war SQLite-Schema: `ExportLogs`, `AppEventLogs`, `CentralSalesRecords` zeigten noch auf `"Sites_repair_old"` +- Schema-Reparatur wurde erweitert und beim App-Start erfolgreich angewendet +- gepruefter Zustand danach: alle drei Tabellen referenzieren wieder `Sites` +- Export kann jetzt erneut getestet werden +- falls erneut Fehler kommt, sollte die Snackbar die Inner Exception anzeigen und die Logs sollten nicht mehr selbst den Export abbrechen + +Nachtest Export all: + +- HANA-Schema-Fehler fuer Frankreich/Italien/USA wurde auf HANA-Quoting zurueckgefuehrt und korrigiert +- Indien bleibt Auth-/Credential-Thema +- England, Spanien und Deutschland sind aktuell `MANUAL_EXCEL` ohne hinterlegte Datei +- Fuer einen sauberen Export-all-Lauf: + - HANA-Standorte mit korrigierter Query nochmals testen + - Indien Credentials pruefen + - manuelle Standorte entweder Datei hinterlegen oder deaktivieren, falls sie nicht im Export-all laufen sollen + +## H103 - Nachtrag 2026-04-29 B1-Belegwaehrungsfelder + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-04-29 B1-Belegwaehrungsfelder + +Der HANA/B1-Export zieht jetzt zusaetzliche Belegwaehrungsfelder: + +- `DocEntry` +- `DocCur` +- `DocTotalFC` +- `DocTotal` +- `VatSumFC` +- `VatSum` +- `DocRate` +- `OADM.MainCurncy` + +Neue Zielfelder: + +- `DocumentEntry` +- `DocumentCurrency` +- `DocumentTotalForeignCurrency` +- `DocumentTotalLocalCurrency` +- `VatSumForeignCurrency` +- `VatSumLocalCurrency` +- `DocumentRate` +- `CompanyCurrency` + +Zusaetzlich gilt jetzt: + +- `StandardCostCurrency` kommt im HANA-Pfad aus `OADM.MainCurncy` +- `Sales_All_*.xlsx` enthaelt die neuen Spalten +- `CentralSalesRecords` enthaelt die neuen Spalten +- bestehende SQLite-DBs werden beim Start um die Spalten erweitert +- Manual-Excel-Import kann die neuen Spalten lesen + +## H104 - Wichtig fuer Auswertungen + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Wichtig fuer Auswertungen + +Die neuen `DocumentTotal*`- und `VatSum*`-Werte sind Belegkopfwerte und werden in der positionsbasierten Datei pro Position wiederholt. + +Power BI: + +- nicht positionsweise summieren +- zuerst nach Beleg deduplizieren, bevorzugt `TSC` + `DocumentType` + `DocumentEntry` +- danach Belegkopfwerte summieren + +Positionswerte wie `Sales Price/Value`, `Quantity` und `Standard cost` bleiben fuer positionsbasierte Summen geeignet. + +## H105 - Verifikation + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Verifikation + +Geprueft: + +```text +dotnet build .\TrafagSalesExporter.csproj --verbosity minimal +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal +``` + +Ergebnis: + +- Build erfolgreich +- Tests erfolgreich +- `48/48` Tests gruen + +## H106 - Nachtrag 2026-04-29 Clean-Code-/DI-Befund + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-04-29 Clean-Code-/DI-Befund + +Aktueller Architektur- und DI-Zustand nach den letzten Umbauten: + +Gesamturteil: + +- die App ist deutlich besser strukturiert als zu Beginn +- die Grundarchitektur ist brauchbar bis gut und fuer pragmatischen produktiven Einsatz geeignet +- Dependency Injection wird grundsaetzlich sinnvoll genutzt +- Clean Code ist mittel bis gut, aber noch nicht durchgehend konsequent + +Was positiv ist: + +- Kernservices laufen weitgehend ueber Interfaces und DI +- `DataSourceAdapter`-Pattern trennt `HANA`, `SAP_GATEWAY` und `MANUAL_EXCEL` +- `SiteExportService` ist dadurch deutlich schlanker als frueher +- UI-nahe Page-Services wurden eingefuehrt +- viele Razor-Seiten sind nicht mehr direkt `DbContext`-lastig +- `Scoped` fuer Page-Services und `Singleton` fuer gemeinsame Infrastruktur/Orchestrierung ist bewusst gewaehlt +- Tests decken wichtige Fachlogik ab, u. a. Transformationen, ConfigTransfer, DatabaseInitialization und ManagementCockpit + +Was noch nicht ideal ist: + +- `DatabaseInitializationService` bleibt ein produktiver Reparatur-/Migrationsblock und ist kein sauberes versioniertes Migrationssystem +- `Settings.razor` und `Standorte.razor` enthalten weiterhin relativ viel UI-/Workflow-Logik +- `ManagementCockpitService`, `ConfigTransferService` und Teile der Initialisierung sind noch sehr breit +- konsolidierter Export hat historisch noch Semantikreste zwischen Live-Snapshot und `CentralSalesRecords` +- Secrets/Zugangsdaten sind noch nicht ideal geloest +- zentraler Retry-/Resilience-Layer fuer SAP/HANA/SharePoint fehlt +- Auth ist jetzt pragmatisch mit User/Admin geschnitten, aber noch nicht fein nach `Viewer`, `Exporter`, `Admin`, `Finance` + +Sinnvolle spaetere Clean-Code-Schritte: + +1. `ManagementCockpitService` in kleinere Query-, Aggregation- und Currency-Komponenten teilen +2. `Settings.razor` und `Standorte.razor` weiter Richtung Page-/Application-Services entlasten +3. `DatabaseInitializationService` langfristig durch versionierte Migrationen ersetzen +4. Auth-Policies fachlich feiner schneiden, z. B. `Viewer`, `Exporter`, `Admin`, `Finance` +5. Retry/Timeout/Failure-Handling fuer externe Systeme zentralisieren +6. Secret-Store-Konzept umsetzen + +## H107 - Nachtrag 2026-04-29 Authentifizierung / AD + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-04-29 Authentifizierung / AD + +Die App wurde nach IT-Rueckmeldung gegen anonymen Zugriff abgesichert. + +Neuer Stand: + +- globale Authentifizierungspflicht +- produktiv vorgesehen: Windows Authentication / Active Directory +- Zugriff und Adminrechte ueber AD-Gruppen +- kein eigener App-Login +- kein versteckter produktiver Backdoor +- lokaler Development-Bypass nur bei `ASPNETCORE_ENVIRONMENT=Development` + +Neue/angepasste Dateien: + +- `Program.cs` +- `Security/SecurityOptions.cs` +- `Security/SecurityPolicies.cs` +- `Security/DevelopmentAuthenticationHandler.cs` +- `Components/Routes.razor` +- `Components/_Imports.razor` +- `Components/Layout/NavMenu.razor` +- `Components/Layout/MainLayout.razor` +- `Components/Pages/Settings.razor` +- `Components/Pages/Standorte.razor` +- `Components/Pages/Transformations.razor` +- `appsettings.json` +- `appsettings.Development.json` + +Aktuelle Default-Gruppen: + +- `TRAFAG\TrafagSalesExporter-Users` +- `TRAFAG\TrafagSalesExporter-Admins` + +## H108 - Noch mit IT zu klaeren + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Noch mit IT zu klaeren + +1. Exakte AD-Domain-/Gruppennamen bestaetigen +2. AD-Gruppen anlegen oder bestehende Gruppen verwenden +3. IIS-Zielumgebung festlegen +4. Auf IIS Windows Authentication aktivieren +5. Auf IIS Anonymous Authentication deaktivieren +6. Sicherstellen, dass produktiv nicht `ASPNETCORE_ENVIRONMENT=Development` gesetzt ist +7. Test mit einem normalen User und einem Admin-User durchfuehren + +## H109 - Fachliche Rollenentscheidung + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Fachliche Rollenentscheidung + +Aktuell: + +- Admin: + - `Settings` + - `Standorte` + - `Transformations` +- berechtigter User: + - Dashboard + - Management Cockpit + - Logs + +Noch zu entscheiden: + +- ob `Logs` ebenfalls Admin-only sein soll +- ob Export-Buttons im Dashboard nur fuer eine eigene Rolle `Exporter` sichtbar sein sollen +- ob Management Cockpit fuer alle berechtigten User oder nur fuer Management/Finance-Gruppen sichtbar sein soll + +## H110 - Verifikation + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Verifikation + +Geprueft: + +```text +dotnet build .\TrafagSalesExporter.csproj --verbosity minimal +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal +``` + +Ergebnis: + +- Build erfolgreich +- Tests erfolgreich +- `48/48` Tests gruen +- Auth-Policy-Tests fuer AccessGroup, AdminGroup und Development-Admin vorhanden +- lokaler Development-Auth-Start geprueft: `http://localhost:55416` antwortet mit HTTP `200` + +## H111 - Nachtrag 2026-04-29 Management Cockpit + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-04-29 Management Cockpit + +Seit dem 2026-04-17 wurden im `Management Cockpit` weitere Auswertmoeglichkeiten umgesetzt und nachtraeglich aus dem aktuellen Code rekonstruiert. + +Aktueller neuer Stand: + +- Summenfeld ist waehbar statt fest auf Umsatz: + - `Sales Price/Value` + - `Quantity` + - `Standard cost` + - `Quantity * Standard cost` +- Anzeige-Waehrung ist waehbar: + - `EUR` + - `USD` + - `Original` +- betragliche Werte werden ueber `CurrencyExchangeRateService` umgerechnet +- nicht-betragliche Werte wie `Quantity` bleiben ohne Waehrung +- fehlende Wechselkurse werden gezaehlt und in der UI/Hinweisen sichtbar +- zentrale Roh-Auswertung kann weitere Summenfelder als Zusatzspalten in Jahres-, Monats- und Tageswerten anzeigen +- dateibasierte Excel-Analyse nutzt ebenfalls Summenfeld und Anzeige-Waehrung + +Betroffene Dateien: + +- `Components/Pages/ManagementCockpit.razor` +- `Models/ManagementCockpitModels.cs` +- `Services/IManagementCockpitService.cs` +- `Services/ManagementCockpitPageService.cs` +- `Services/ManagementCockpitService.cs` +- `TrafagSalesExporter.Tests/ManagementCockpitServiceTests.cs` + +Neue Tests: + +- Umrechnung zentraler Werte in EUR +- Wechselkurs-Cache pro Waehrung/Ziel/Datum +- Mengen-Auswertung ohne Waehrungsumrechnung +- Zusatzwerte in Zeitreihen + +## H112 - Jetzt sinnvoll zu pruefen + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Jetzt sinnvoll zu pruefen + +1. `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` +2. Management Cockpit in der App oeffnen +3. zentrale Auswertung mit `Sales Price/Value` in `EUR` pruefen +4. zentrale Auswertung mit `Quantity` pruefen und bestaetigen, dass keine Waehrung angezeigt wird +5. Zusatzfelder `Quantity` und `Quantity * Standard cost` in Jahres-/Monatswerten pruefen +6. Dateianalyse einer exportierten Excel mit unterschiedlichen Summenfeldern pruefen +7. fachlich klaeren, ob `CHF` neben `EUR` und `USD` als Anzeige-Waehrung angeboten werden soll +8. fachlich klaeren, ob fehlende Wechselkurse als `0` in Zielwaehrung korrekt sind oder separat ausgewiesen werden sollen + +## H113 - Nachtrag 2026-04-17 Refactoring-Fortschritt + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-04-17 Refactoring-Fortschritt + +Mehrere frueher als hoch priorisiert markierte Architekturpunkte sind inzwischen bereits umgesetzt. + +Erledigt: + +- DataSourceAdapter-Pattern fuer `HANA`, `SAP_GATEWAY`, `MANUAL_EXCEL` +- `SiteExportService` deutlich verschlankt +- Page-Services auf `Scoped` +- `DatabaseInitializationService` in Schema-/Seed-/Orchestrator-Bloecke getrennt +- `Dashboard`, `Logs` und `Transformations` von direktem `DbContext`-Zugriff befreit +- HANA-SQL-Injection-Pfad geschlossen +- blockierende `.GetAwaiter().GetResult()`-Aufrufe im HANA-Pfad entfernt + +Neuer verifizierter Stand: + +- `dotnet build .\TrafagSalesExporter.csproj --verbosity minimal` erfolgreich +- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` +- `36/36` Tests gruen + +## H114 - Neue Top-Prioritaeten ab jetzt + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Neue Top-Prioritaeten ab jetzt + +## H115 - 1. Adapter- und Resolver-Tests nachziehen + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +#### 1. Adapter- und Resolver-Tests nachziehen + +Prio hoch. + +Warum: + +- das neue `DataSourceAdapter`-Pattern ist architektonisch wichtig +- genau dieser neue Schnitt hat aktuell noch keine gezielten Unit-Tests + +Sinnvoll waeren: + +- `DataSourceAdapterResolver`-Tests +- `HanaDataSourceAdapter`-Tests +- `SapGatewayDataSourceAdapter`-Tests +- `ManualExcelDataSourceAdapter`-Tests + +## H116 - 2. Retry-/Robustheitslayer + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +#### 2. Retry-/Robustheitslayer + +Prio hoch. + +Vor allem fuer: + +- SharePoint +- SAP Gateway +- HANA-nahe Netzpfade + +Aktuell brechen diese Integrationen bei transienten Problemen zu direkt ab. + +## H117 - 3. Secret-Store-Konzept + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +#### 3. Secret-Store-Konzept + +Prio hoch bis mittel. + +Aktuell liegen Zugangsdaten weiterhin in der App-/DB-Konfiguration. +Langfristig sollte entschieden werden: + +- Windows Credential Manager +- DPAPI / verschluesselte Ablage +- externer Secret Store + +## H118 - 4. `DatabaseInitializationService` weiter haerten, aber nicht mehr blind gross refactoren + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +#### 4. `DatabaseInitializationService` weiter haerten, aber nicht mehr blind gross refactoren + +Prio mittel. + +Der schlimmste Architekturteil ist deutlich besser als vorher. +Weitere Arbeit dort sollte jetzt nur noch zielgerichtet passieren: + +- Regressionstests fuer konkrete Legacy-/Repair-Zustaende +- spaeter moeglichst versionierte Migrationen + +## H119 - 5. MudBlazor-Analyzer-Warnungen bereinigen + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +#### 5. MudBlazor-Analyzer-Warnungen bereinigen + +Prio mittel. + +Nicht kritisch fuer Produktion, aber sinnvoll fuer sauberen Build: + +- `Logs.razor` +- `Transformations.razor` +- `Standorte.razor` + +## H120 - Was im Vergleich zu frueher nicht mehr Top-Prioritaet ist + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Was im Vergleich zu frueher nicht mehr Top-Prioritaet ist + +Nicht mehr ganz oben: + +- generisches weiteres Page-Service-Refactoring um des Refactorings willen +- noch mehr strukturelles Verschieben ohne Risikoreduktion + +Der wirtschaftlich sinnvolle Fokus liegt jetzt eher auf: + +- Absicherung +- Robustheit +- Integrationsstabilitaet + +## H121 - Nachtrag 2026-04-17 + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-04-17 + +Der Punkt `CHF-Umrechnung / Wechselkurse` ist nicht mehr komplett offen. + +Der aktuelle Ist-Stand ist: + +- `CurrencyExchangeRateService` ist implementiert +- `ExchangeRateImportService` importiert ECB-Kurse +- `NormalizeCurrencyCode` und `ConvertCurrency` sind im Transformationssystem registriert +- fehlende Unit-Tests dafuer wurden am 2026-04-17 ergaenzt + +Neuer Teststand: + +- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` +- erfolgreich +- `31/31` Tests gruen + +Was fuer Waehrungen trotzdem noch offen bleibt: + +- fachlicher Einsatz der `ConvertCurrency`-Regeln in echten Standortkonfigurationen pruefen +- UI-Flow fuer Wechselkurspflege in `Settings.razor` manuell gegenpruefen +- ECB-Import einmal real ueber die UI bzw. App-Funktion pruefen +- bestaetigen, fuer welche Sichten CHF die Zielwaehrung sein soll +- Management-Cockpit-Rohsicht nur dann auf CHF umstellen, wenn fachlich gewuenscht + +## H122 - Architektur-Nachtrag 2026-04-17 + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Architektur-Nachtrag 2026-04-17 + +Nach einer separaten Architekturpruefung wurden die naechsten Schritte neu priorisiert. + +Wichtig: + +- neue Fachfeatures sind aktuell **nicht** der erste Engpass +- zuerst muessen die Architektur-Risiken in Initialisierung, Config-Import und UI-Service-Schnitt bereinigt werden + +## H123 - Neue Top-Prioritaeten + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Neue Top-Prioritaeten + +## H124 - 1. `DatabaseInitializationService` absichern + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +#### 1. `DatabaseInitializationService` absichern + +Prio sehr hoch. + +Gruende: + +- Startlogik enthaelt manuelle Schema-Migrationen +- FK-Reparaturen laufen produktiv beim App-Start +- dort wurde ein konkretes Risiko fuer verschobene Spaltenwerte beim `Sites_old`-Kopierpfad erkannt + +Vor weiterer Fachentwicklung: + +- Initialisierungspfad genau pruefen +- SQL-Kopierlogik validieren +- moeglichst Richtung versionierte Migrationen bewegen + +## H125 - 2. `ConfigTransferService.ImportJsonAsync` neu denken + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +#### 2. `ConfigTransferService.ImportJsonAsync` neu denken + +Prio sehr hoch. + +Aktuelles Problem: + +- Import loescht sehr viel und baut danach stueckweise neu auf +- nicht atomar +- potenziell teilzerstoerter Zustand bei Fehlern +- `CentralSalesRecords` werden mitimportiert/mitgeloescht, obwohl sie eher Laufzeitdaten als Konfiguration sind + +Ziel: + +- atomarer Import +- saubere Trennung zwischen Konfiguration und Betriebsdaten + +## H126 - 3. Razor-Seiten entlasten + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +#### 3. Razor-Seiten entlasten + +Prio hoch. + +Betroffen vor allem: + +- `Components/Pages/Settings.razor` +- `Components/Pages/Standorte.razor` + +Ziel: + +- DB- und Fachlogik aus UI-Code in Services / Application-Layer verschieben +- Seiten nur noch fuer Interaktion und Formularzustand + +## H127 - 4. Konsolidierten Export semantisch klaeren + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +#### 4. Konsolidierten Export semantisch klaeren + +Prio mittel. + +Offene Frage: + +- zentrale Datei aus laufendem Snapshot + oder +- zentrale Datei immer aus `CentralSalesRecords` + +Aktuell ist die Verantwortung unscharf. + +## H128 - 5. Reporting verallgemeinern + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +#### 5. Reporting verallgemeinern + +Prio mittel. + +Erst nach den Infrastrukturthemen: + +- hartcodierte Jahreslogik im Cockpit entfernen +- fachlich entscheiden, ob und wo CHF-Rohsicht gebraucht wird + +## H129 - Praktische Reihenfolge fuer den naechsten Wiedereinstieg + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Praktische Reihenfolge fuer den naechsten Wiedereinstieg + +Wenn nach erneutem Absturz oder Kontextverlust weitergemacht wird: + +1. `HANDOFF_2026-04-15.md` lesen, speziell die Architekturpruefung vom 2026-04-17 +2. `DatabaseInitializationService` als ersten Risikoblock ansehen +3. `ConfigTransferService.ImportJsonAsync` als zweiten Risikoblock ansehen +4. erst danach wieder an Cockpit / CHF / weitere Fachfeatures gehen + +## H130 - Nachtrag HANA-/Standort-Workflow 2026-04-17 + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag HANA-/Standort-Workflow 2026-04-17 + +Der doppelte HANA-Workflow wurde inzwischen bereits bereinigt. + +Neuer Stand: + +- oben zentrale HANA-Konfiguration pro Quellsystem `BI1` / `SAGE` +- unten im Standort keine eigene wirksame Voll-HANA-Konfiguration mehr +- HANA-basierte Standorte ziehen ihre technische Verbindung aus der zentralen Quellsystem-Konfiguration +- Standort bleibt fuer fachliche Daten und optionale Credential-Overrides zustaendig +- die frueher doppelte HANA-UI im Standortdialog ist inzwischen auch sichtbar entfernt +- der Verbindungstest in `Settings.razor` prueft und meldet jetzt die zentrale HANA-Verbindung klar + +## H131 - Was dazu noch praktisch geprueft werden sollte + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Was dazu noch praktisch geprueft werden sollte + +- `Standorte`-Seite im UI manuell durchklicken +- pruefen, ob `BI1`- und `SAGE`-Standort beim Speichern sauber auf die zentrale HANA-Konfiguration zeigen +- pruefen, ob Aenderung oben bei zentraler HANA-Konfiguration in nachfolgenden Exporten wirklich greift + +## H132 - Anschlussarbeiten + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Anschlussarbeiten + +- `ConfigTransferService` spaeter auf das neue zentrale HANA-Modell fachlich nachziehen und kritisch pruefen +- `DatabaseInitializationService` weiter konsolidieren, damit die Zuordnung alter HANA-Daten langfristig robuster wird + +## H133 - Nachtrag Quellsystem-Verwaltung 2026-04-17 + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag Quellsystem-Verwaltung 2026-04-17 + +Die bisher hart codierten Quellsystem-Listen wurden ersetzt. + +Neuer Stand: + +- `SourceSystemDefinition` ist jetzt die zentrale Stammdatenquelle fuer Quellsysteme +- `Settings.razor` hat jetzt eine GUI zur Pflege von Quellsystemen +- `Standorte.razor` zieht seine Quellsystem-Auswahl aus diesen Stammdaten +- `Transformations.razor` zieht die Systemauswahl ebenfalls aus diesen Stammdaten +- zentrale Credentials haengen jetzt am Quellsystem selbst +- HANA-Zentralverbindungen werden nur noch fuer Quellsysteme mit Anschlussart `HANA` gezeigt +- alte zentrale Credential-Felder in `ExportSettings` sind aus dem aktiven Codepfad entfernt +- `ExportSettings` wird beim Start auch schematisch auf das neue Feldset bereinigt +- HANA speichert zentral keine eigenen Credentials mehr; dort bleiben nur technische Verbindungsdaten +- `HanaServer.Username` / `Password` sind nur noch Laufzeitfelder und nicht mehr im EF-Schema gemappt +- SAP Service URL wird jetzt zentral im Quellsystem gepflegt; der Standort haelt nur noch ein optionales Override +- Quellsysteme werden jetzt per Dialog bearbeitet statt nur ueber Inline-Tabellenfelder + +## H134 - Was dazu noch praktisch geprueft werden sollte + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +### Was dazu noch praktisch geprueft werden sollte + +- in `Settings` ein neues Quellsystem per GUI anlegen +- pruefen, ob es danach in `Standorte` und `Transformations` sofort auswählbar ist +- pruefen, ob deaktivierte Quellsysteme in neuen Standort-/Regelanlagen nicht mehr normal angeboten werden +- pruefen, ob Aenderung der Anschlussart von `HANA` auf `SAP_GATEWAY` oder `MANUAL_EXCEL` fachlich sauber wirkt +- pruefen, ob bestehende BI1/SAGE/SAP-Daten nach Startmigration korrekt in `SourceSystemDefinitions` stehen +- pruefen, ob Konfiguration-Export/Import ohne die alten Credential-Felder sauber mit `SourceSystemDefinitions` arbeitet +- pruefen, ob zentrale SAP Service URL ohne Override sauber fuer Refresh, Export und Dashboard greift +- pruefen, ob SAP Service URL Override am Standort die zentrale URL erwartungsgemaess uebersteuert + +## H135 - Nachtrag 2026-04-16 + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## Nachtrag 2026-04-16 + +Seit dem letzten Stand kamen mehrere groessere Erweiterungen dazu. Die offenen Punkte unten muessen deshalb im neuen Kontext gelesen werden. + +## H136 - 0. Neuer Ist-Stand + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 0. Neuer Ist-Stand + +Zusaetzlich zum alten Stand ist jetzt vorhanden: + +- manueller Standort-Import ueber `MANUAL_EXCEL` +- Dashboard mit `Alle exportieren`, `Zentrale Datei neu erzeugen` und zentralem `Excel oeffnen` +- Roh-Auswertung im `Management Cockpit` direkt aus `CentralSalesRecords` +- erweitertes Transformationssystem mit `Value`- und `Record`-Regeln +- HANA-Schema-Lookup im Standortdialog +- Testprojekt mit aktuell 18 gruenden Tests + +## H137 - 1. Status + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 1. Status + +Der Export geht jetzt wieder durch. + +Die zuletzt gefundene Hauptursache war nicht mehr ein reiner SQLite-Lock beim Batch-Insert, sondern ein kaputter FK-Schemazustand in der bestehenden DB: + +- SQLite referenzierte in mindestens einer Tabelle noch `main.Sites_old` +- dadurch scheiterte `SaveChangesAsync()` beim Schreiben z. B. in `AppEventLogs` oder `ExportLogs` +- sichtbarer Effekt: Export blieb nach `Zentrale Tabelle: ... Datensaetze gespeichert.` haengen + +## H138 - 2. Umgesetzter Fix + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 2. Umgesetzter Fix + +Umgesetzt wurde: + +- Dashboard-Live-Status liest waehrend laufendem Export nicht mehr staendig aus `AppEventLogs`, sondern nutzt den In-Memory-Status des `ExportOrchestrationService` +- SQLite `Default Timeout` in `Program.cs` auf `60` erhoeht +- `CentralSalesRecordService` setzt nach den Batches explizit `Zentrale Tabelle aktualisiert` +- `DatabaseInitializationService` repariert beim App-Start automatisch Tabellen, deren FK-SQL noch `Sites_old` referenziert + +Betroffene Dateien: + +- `Program.cs` +- `Components/Pages/Dashboard.razor` +- `Services/CentralSalesRecordService.cs` +- `Services/DatabaseInitializationService.cs` + +## H139 - 3. Was noch getestet werden sollte + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 3. Was noch getestet werden sollte + +Kurz gegenpruefen: + +- Export eines Standorts erneut +- `Excel oeffnen` nach erfolgreichem Export +- `Export erfolgreich` inkl. `Pfad=...` +- Dashboard-Live-Status setzt sich nach Abschluss sauber zurueck +- `Alle exportieren` +- `Zentrale Datei neu erzeugen` +- zentrale Datei im Dashboard oeffnen + +## H140 - 3a. Manuellen Excel-Import pruefen + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 3a. Manuellen Excel-Import pruefen + +Zu testen: + +- Standort auf `MANUAL_EXCEL` stellen +- Excel im Standort hochladen +- Standort exportieren +- pruefen, ob `CentralSalesRecords` fuer diesen Standort ersetzt wurden +- pruefen, ob der zentrale Export den Standort korrekt enthaelt + +Dateien: + +- `Components/Pages/Standorte.razor` +- `Services/ManualExcelImportService.cs` +- `Services/SiteExportService.cs` + +## H141 - 3b. HANA-Schema-Lookup pruefen + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 3b. HANA-Schema-Lookup pruefen + +Zu testen: + +- bei `BI1`-Standort `Schemas laden` +- bei `SAGE`-Standort `Schemas laden` +- wird ein plausibles B1-Schema angeboten? +- funktioniert danach Export ohne manuelle Schema-Eingabe? +- zeigt England / Spezialstandort jetzt schneller, wenn Schema oder Rechte nicht passen? + +Dateien: + +- `Components/Pages/Standorte.razor` +- `Services/HanaQueryService.cs` + +## H142 - 4. Falls wieder ein Fehler auftritt + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 4. Falls wieder ein Fehler auftritt + +In dieser Reihenfolge pruefen: + +1. Exakte Fehlermeldung aus `AppEventLogs` bzw. Console notieren +2. Pruefen, ob die Reparaturlogik beim Start gelaufen ist +3. Pruefen, ob noch weitere Tabellen mit veralteter FK-Referenz existieren +4. Erst danach wieder am Batch-/Commit-Pfad der zentralen Speicherung arbeiten + +## H143 - 5. SAP-Funktionalitaet kurz gegenpruefen + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 5. SAP-Funktionalitaet kurz gegenpruefen + +Zu testen: + +- `Quellen refreshen` +- `Felder aus Quellen laden` +- `Auto-Match` +- SAP-Export eines Standorts + +Dateien: + +- `Components/Pages/Standorte.razor` +- `Services/SapGatewayService.cs` +- `Services/SapCompositionService.cs` + +## H144 - 6. Management Cockpit pruefen + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 6. Management Cockpit pruefen + +Zu testen: + +- vorhandene Excel-Datei auswaehlbar +- Analyse laeuft +- Kennzahlen plausibel +- Roh-Auswertung aus `CentralSalesRecords` laeuft +- Jahr/Monat-Filter funktionieren +- Summen nach Quelle / Land plausibel + +Dateien: + +- `Components/Pages/ManagementCockpit.razor` +- `Services/ManagementCockpitService.cs` + +## H145 - 6a. Fachlich bewusst noch offen + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 6a. Fachlich bewusst noch offen + +Noch nicht final umsetzen ohne Rueckmeldung Fachseite: + +- Intercompany-Filter +- fachliche Nutzung der CHF-Umrechnung in Cockpit / Reports +- Budgetvergleich +- Gruppenlogik +- Spartenlogik +- Margenlogik + +Diese Punkte sollen spaeter moeglichst dynamisch auf dem neuen Transformations-/Mapping-Ansatz aufsetzen, aber aktuell nicht hart geraten werden. + +## H146 - 6b. Naechste sinnvolle Testkandidaten + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 6b. Naechste sinnvolle Testkandidaten + +Wenn weiter in Tests investiert wird, sind die naechsten Kandidaten: + +- `ExportOrchestrationService` +- spaeter End-to-End-Tests fuer den Wechselkurs-/Transformationspfad +- spaeter evtl. SQLite-nahe Integrationstests fuer `DatabaseInitializationService` + +Aktueller Teststatus: + +- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` +- erfolgreich +- `31/31` Tests gruen + +## H147 - 7. Referenzdatei + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 7. Referenzdatei + +Fuer den vollstaendigen Kontext zuerst lesen: + +- `HANDOFF_2026-04-15.md` + +## H148 - 8. Letzte bereinigte UI-Irritation + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 8. Letzte bereinigte UI-Irritation + +Stand 2026-04-17: + +- In `Standorte` wurde die obere Box auf `Zentrale HANA-Technik` geklaert. +- Dort gibt es keinen `Server hinzufuegen`-Pfad mehr. +- Grund: zentrale HANA-Eintraege werden aus `Quellsystemen` mit Anschlussart `HANA` abgeleitet. +- `SAP` gehoert fachlich nicht in diese Box, sondern in `Settings -> Quellsysteme`. + +Wichtig fuer den naechsten Wiedereinstieg: + +- Wenn ein Benutzer fragt `wo ist SAP?`, ist die richtige Antwort: nicht in der HANA-Box, sondern in der zentralen Quellsystem-Verwaltung. +- Wenn ein HANA-System oben fehlt, zuerst `Settings -> Quellsysteme` pruefen und dort Anschlussart `HANA` setzen. + +## H149 - 9. Config-Transfer erneut geprueft + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 9. Config-Transfer erneut geprueft + +Stand 2026-04-17: + +- Der aktuelle Config-Import/-Export passt zum neuen Datenmodell. +- Zentral verwaltete Quellsysteme, SAP-Zentral-URL, HANA-Technik ohne HANA-Credentials und Standort-Overrides werden korrekt im Transferformat abgebildet. +- Die vorhandenen `ConfigTransferServiceTests` bestaetigen den aktuellen Rundlauf. + +Fuer den naechsten Wiedereinstieg wichtig: + +- Das aktuelle Format ist fuer heutige Exporte konsistent. +- `ImportJsonAsync` ist aber weiterhin nicht atomar und loescht zuerst produktive Konfiguration. +- Zusaetzlich gibt es ein Altformat-Risiko: + - aeltere JSONs mit `SourceSystemDefinitions`, aber ohne `ConnectionKind`, koennen wegen DTO-Default falsch als `HANA` interpretiert werden. + +Naechste saubere Haertung fuer dieses Thema: + +- Config-Import transaktional machen +- Legacy-Fallback fuer fehlendes `ConnectionKind` einbauen + +## H150 - 10. Nachtrag 2026-05-20: Finance-Regeln statt harte Laenderlogik + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 10. Nachtrag 2026-05-20: Finance-Regeln statt harte Laenderlogik + +Aktueller Stand: + +- Es gibt jetzt `Admin -> Finance Regeln`. +- Die fachliche Abgrenzung fuer Finance wird dort als Regel gepflegt: + - Land/Scope + - Jahr + - Regeltyp + - Feld + - Vergleich + - Wert + - Notiz + - Sortierung/Aktiv +- Diese Regeln wirken auf: + - zentrales Excel (`Finance | ...` und `Finance Summary`) + - Soll/Ist Vergleich +- Sie veraendern nicht: + - Rohdatenimport + - Mapping in `Admin -> Standorte` + - technische Transformationen in `Admin -> Transformationen` + +UI-Logik fuer Keyuser: + +```text +Admin -> Standorte = Quelle und Spaltenmapping +Admin -> Transformationen = technische Feldnormalisierung/-berechnung +Admin -> Finance Regeln = CFO-/Finance-Abgrenzung +``` + +Wichtige Default-Regeln: + +- DE: + - Alphaplan-Jahresfile -> Finance-Jahr 2025 + - Trafag AG ausschliessen + - Magnetic Sense ausschliessen + - GS2510095 ausschliessen + - GS-Gutschriften negativ +- IT: + - Trafag Italia ausschliessen + - doppelte Blank-Supplier-Country-Zeilen deduplizieren + +Nach jedem Regelwechsel testen: + +1. passenden Standort exportieren +2. zentrale Datei neu erzeugen +3. im Endexcel `Finance Summary` kontrollieren +4. `Soll/Ist Vergleich` kontrollieren + +Letzter DE-Pruefstand: + +```text +DE 2025 im zentralen Excel: 3'652'394.46 +``` + +## H151 - 11. Nachtrag 2026-05-20: Export Dashboard Datenbasis + +Quelle: NEXT_STEPS_2026-04-15.md.raw + +## 11. Nachtrag 2026-05-20: Export Dashboard Datenbasis + +Im Export Dashboard steht direkt nach `Land` die Spalte `Basis`. + +Angezeigt wird: + +- `Excel-Datei` mit Tabellen-Icon +- `CSV-Datei` mit Datei-Icon +- `SAP Service` mit Cloud-Sync-Icon +- `Server` mit Storage-Icon +- `Manuelle Datei`, falls manuelle Quelle ohne erkennbaren Pfad + +Die Spalte kommt aus `DashboardPageService.ResolveDataBasis`. + +## H152 - TrafagSalesExporter Handoff + +Quelle: HANDOFF_2026-04-15.md.raw + +# TrafagSalesExporter Handoff + +Stand: 2026-05-20 + +## H153 - Aktueller Handoff-Zusatz 2026-05-20 + +Quelle: HANDOFF_2026-04-15.md.raw + +## Aktueller Handoff-Zusatz 2026-05-20 + +Seit den aelteren Handoff-Eintraegen wurden folgende Punkte umgesetzt und dokumentiert: + +- `Management Analyse` hat einen fuehrenden Reiter `Finance Summary`. +- Finance Summary nutzt dieselbe `FinanceRuleEngine` wie das zentrale Excel-Blatt `Finance Summary`. +- Filter fuer Jahr, Land und Waehrung wirken auf das Finance-Endergebnis. +- DE 2026 wirft keinen Fehler mehr, sondern zeigt wegen DE/Alphaplan-2025-Zwang einen leeren Zustand mit Hinweis. +- HR KPI Cockpit wurde erweitert: + - Anleitung-Reiter + - Datenordner anpassbar + - Dateifrische / Datenstatus + - Ampeln + - Periodenvergleich + - Datenqualitaet + - Austritte nach Typ/Organisation + - Absenzen nach Organisation / Top-Absenzen + - Managementsicht + - Drucken/PDF +- Anwenderdokus: + - `docs/HR_KPI_ANLEITUNG_HR_2026-05-20.docx` + - `docs/FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx` +- Markdown-Dokumentenstatus: + - `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` + +Validierung: + +- `dotnet test TrafagSalesExporter.sln --verbosity minimal` +- Ergebnis am 2026-05-20: `77/77` Tests gruen. + +Hinweis: + +- Aeltere Abschnitte in diesem Handoff bleiben als Historie erhalten. Fuer aktuellen Status immer zuerst diesen Zusatz, `NEXT_STEPS_2026-04-15.md`, `lastchange.md` und `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` lesen. + +## H154 - Nachtrag 2026-05-11 UK_B1 Mapping / aktueller Arbeitsstand + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-05-11 UK_B1 Mapping / aktueller Arbeitsstand + +Letzter Benutzerwunsch: + +- UK/England soll weiter ueber `UK_B1` laufen. +- Das Mapping soll so angepasst werden, dass die Finance-Zahl plausibel wird. +- Danach soll alles nachvollziehbar dokumentiert sein. + +Wichtiger Befund: + +- FinanceProbe zeigte fuer UK/England: + - `TSC = TRUK` + - `1'881` Zeilen + - Ist `395'605.82 GBP` + - Soll `3'749'865.00 GBP` +- In der lokalen DB waren fuer `TRUK` keine `ManualExcelColumnMappings` vorhanden. +- Der Fallback-Importer hat `Sales Price/Value` direkt als Positionswert importiert. +- Im UK-B1-Export ist `Sales Price/Value` aber ein Stueckpreis. +- Korrekte Positionslogik: + +```text +SalesPriceValue = [Sales Price/Value] * [Quantity] +``` + +Probe auf existierenden Zentraldaten: + +```text +Summe SalesPriceValue bisher: 395'605.82 GBP +Summe SalesPriceValue * Quantity: 3'533'348.89 GBP +check.xlsx Soll: 3'749'865.00 GBP +Restdifferenz: -216'516.11 GBP +``` + +Geaenderte Dateien im aktuellen Worktree: + +- `Services/ManualExcelImportService.cs` + - grafische Manual-Excel-Mappings koennen einfache Multiplikationsausdruecke lesen: + +```text +=[Header A]*[Header B] +``` + + - Konstanten wie `=GBP` funktionieren weiterhin. + +- `Services/DatabaseSeedService.cs` + - repariert England/TRUK auf: + +```text +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1 +``` + + - seedet fuer `TRUK` ein grafisches Mapping, insbesondere: + +```text +SalesPriceValue <- =[Sales Price/Value]*[Quantity] +SalesCurrency <- =GBP +DocumentCurrency<- =GBP +CompanyCurrency <- =GBP +PostingDate <- invoice date +InvoiceDate <- invoice date +``` + +- `TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs` + - neuer Test fuer berechnetes Manual-Excel-Mapping. + +Aktueller Teststand: + +- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false --verbosity minimal` +- Tests erfolgreich: `59/59`. +- Bekannte Warnungen: bestehende MudBlazor-Analyzerwarnungen zu `Dense`. + +Zusatzfix: + +- `DatabaseSeedService` prueft vor `EnsureUkManualExcelMapping(...)`, ob `ManualExcelColumnMappings` sauber auf `Sites` referenziert. +- Falls die Tabelle noch auf `Sites_repair_old` oder eine andere `Sites_*`-Reparaturtabelle zeigt, wird der UK-Mapping-Seed fuer diesen Start uebersprungen. +- Dadurch kann die Schema-Reparatur sauber durchlaufen. + +Naechster praktischer Schritt: + +1. SharePoint-/Graph-Zugriff reparieren. +2. FinanceProbe ist bereits auf `http://127.0.0.1:5099` gestartet. +3. `/run/export/TRUK` erneut ausfuehren. +4. `/finance` erneut pruefen. + +Praktischer Stand: + +- Lokale DB ist aktualisiert: + - `TRUK` Pfad = `UK_B1` + - `18` aktive Manual-Excel-Mapping-Zeilen +- `/finance` antwortet mit HTTP `200`. +- `/run/export/TRUK` scheitert aktuell an Auth/Netzwerk: + +```text +ClientSecretCredential authentication failed +127.0.0.1:9 connection refused +``` + +- Deshalb enthaelt `CentralSalesRecords` fuer UK noch den alten Importstand, bis SharePoint wieder erreichbar ist. + +Wichtig: + +- Das ist keine Sonderlogik, die UK-Zahlen schoenrechnet. +- Der Mapper setzt die allgemeine fachliche Regel "pro Artikel / Belegposition" um. +- Die Formel ist im grafischen Mapping sichtbar und nicht hart als UK-Spezialberechnung im Importcode versteckt. +- Falls nach neuem Export noch eine Restdifferenz bleibt, muss die UK-Datei auf weitere Netto-/Discount-/Frachtspalten geprueft werden. + +## H155 - Nachtrag 2026-05-08 Manual Excel/CSV / SharePoint-Ordner + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-05-08 Manual Excel/CSV / SharePoint-Ordner + +Aktueller Stand fuer manuelle Quellen: + +- `MANUAL_EXCEL` ist fachlich Manual Excel/CSV. +- Unterstuetzt werden `.xlsx` und `.csv`; altes `.xls` ist nicht der Zielpfad. +- Lokale Datei als Quelle: + - App liest die Datei. + - App erzeugt eine neue Exportdatei im selben lokalen Ordner. +- SharePoint-Datei als Quelle: + - App laedt die Datei temporaer herunter. + - App erzeugt eine neue Exportdatei und laedt sie in denselben SharePoint-Ordner hoch. +- SharePoint-Ordner als Quelle: + - App waehlt automatisch die neueste passende `.xlsx`/`.csv` fuer den Standort. + - Primaeres Muster: `ddMMyy_TSC.xlsx` oder `ddMMyy_TSC.csv`. + - Fallback: SharePoint `LastModifiedDateTime`. + +England / UK: + +- Standort `England`, `TSC = TRUK`, `SourceSystem = MANUAL_EXCEL`. +- Quelle ist ein SharePoint-Ordner: + +```text +https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1 +``` + +- Beispielauswahl: + - `010526_TRUK.xlsx` ist neuer als `010426_TRUK.xlsx`. +- Exportdateien werden wieder in `Import/Finance/UK_B1` geschrieben. +- Befund am 2026-05-08: England zeigte lokal faelschlich auf die Deutschland-Alphaplan-Datei; lokale DB wurde korrigiert. +- `DatabaseSeedService` repariert kuenftig einen leeren England/TRUK-Manual-Pfad auf den UK_B1-Ordner. + +Spanien / Sage: + +- Spanien nutzt `MANUAL_EXCEL` als technischen Importpfad fuer den Sage-Export. +- Die Datei `Spain_Sales_2025.csv` konnte gelesen werden (`4'341` Zeilen). +- Fehler war danach der Exportpfad: die SharePoint-URL wurde als lokaler Dateipfad interpretiert. +- Fix: SharePoint-Manual-Quellen liefern keinen `ReferenceFilePath` mehr, sondern erzeugen eine neue Exportdatei im Quellordner. + +Deutschland / Alphaplan: + +- Deutschland nutzt `MANUAL_EXCEL` als technischen Importpfad fuer Alphaplan-Excel. +- Grafisches Mapping ist vorhanden. +- Offener Punkt: konkreter Alphaplan-Datei-/SharePoint-Pfad muss im Standort hinterlegt sein, sonst kommt `Standort 'Deutschland' hat keine manuelle Excel-Datei.` + +Verifikation: + +- Tests `55/55` erfolgreich. + +## H156 - Nachtrag 2026-05-08 FinanceProbe fuer mehr Laender + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-05-08 FinanceProbe fuer mehr Laender + +FinanceProbe wurde erweitert: + +- `FinanceReferences` werden vollstaendig angezeigt, nicht nur bei aktivem Standort oder vorhandenen Ist-Daten. +- Dadurch sind alle Soll-Laender aus der Finance-Konfiguration im Meeting sichtbar. +- Neue Sektion `Datenabdeckung je Standort` zeigt je Standort: + - Quelle/System + - Manual-/SharePoint-Pfad + - Aktivstatus + - Anzahl 2025-Zeilen in `CentralSalesRecords` + - Summe `SalesPriceValue` + - Waehrungen und Datumsbereich + - letzter Exportstatus/Fehler +- CH/AT-Erkennung im Finance-Service wurde geschaerft, damit `ZSCHWEIZ`-Zeilen mit Land `AT` Oesterreich zugeordnet werden koennen. + +Wichtig: + +- `Keine Daten` bedeutet jetzt nicht zwingend fehlende Referenz, sondern oft: Referenz ist vorhanden, aber Ist-Daten wurden noch nicht exportiert/importiert. +- Fuer neue Laender reicht es, `FinanceReferences` zu pflegen und Daten nach `CentralSalesRecords` zu bringen; die Probe zeigt sie dann automatisch. + +## H157 - Nachtrag 2026-05-11 FinanceProbe KI-Steuerung + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-05-11 FinanceProbe KI-Steuerung + +FinanceProbe kann jetzt nicht nur vergleichen, sondern im Testkontext auch Exporte ausloesen: + +- `/run/export/{siteKey}`: einzelner Standort nach `Id`, `TSC` oder `Land` +- `/run/export-all`: alle aktiven Standorte plus zentrale Datei +- `/run/consolidated`: zentrale Datei aus `CentralSalesRecords` + +Die Routen liefern eine HTML-Run-Summary mit Exportlogs, Finance-Abgleich und Datenabdeckung. + +Wichtig: + +- Das ist eine temporaere Test-/KI-Steuerung. +- Nicht als produktive API betrachten. +- Echte SAP/HANA/SharePoint-Zugriffe funktionieren nur mit vorhandenen Credentials und Netzverbindung auf dem Rechner. + +## H158 - Nachtrag 2026-05-07 Mapper-Konsolidierung / Finance-Konfiguration + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-05-07 Mapper-Konsolidierung / Finance-Konfiguration + +Architekturstand: + +- `MappedSalesRecordComposer` ist die gemeinsame Engine fuer grafisches Mapping. +- SAP OData und generisches HANA-Mapping nutzen denselben Composer fuer Joins und Zielfeldmapping. +- SAP OData laedt weiter ueber `SapGatewayService`. +- HANA-Tabellen/Views laden weiter ueber `HanaQueryService`. +- Der alte B1-HANA-Pfad ohne Mapping bleibt als Legacy-Pfad fuer bestehende BI1/SAGE-Standorte erhalten. +- `ConsolidatedExportService.ExportAsync()` erzeugt die zentrale Datei nur noch aus `CentralSalesRecords`; es gibt keinen zweiten Records-Parameter mehr. +- Manual Excel/CSV akzeptiert im Standort-Editor und Upload `.xlsx` und `.csv`. + +Neue Konfigurationstabellen: + +- `FinanceReferences`: Soll-/check.xlsx-Referenzen je Jahr und Land/Key. +- `FinanceIntercompanyRules`: IC-/2nd-party-Regeln nach Scope, Kundennummer oder Namensbestandteil. +- Budgetkurse 2025 liegen als `CurrencyExchangeRates` mit `Notes = Budget 2025`. +- Config-Export/-Import nimmt `FinanceReferences` und `FinanceIntercompanyRules` mit. + +Offen: + +- Manual-Excel-Import hat noch zwei Modi: Header-Automatik und grafisches Mapping. +- Der alte B1-HANA-Spezialpfad ist bewusst noch vorhanden, sollte aber mittelfristig durch gepflegte HANA-Mappings abgeloest werden. + +Verifikation: + +- Hauptprojekt Build erfolgreich. +- Tests `52/52` erfolgreich. + +## H159 - Nachtrag 2026-05-07 SAP OData / ZSCHWEIZ / Schweiz-Oesterreich + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-05-07 SAP OData / ZSCHWEIZ / Schweiz-Oesterreich + +Aktueller Architekturentscheid: + +- `ZSCHWEIZ` wird ueber SAP OData/Gateway gelesen. +- Direkter HANA-Spezialcode fuer `ZSCHWEIZ` wurde vermieden. +- Der grafische Quellen- und Feldmapper wird fuer SAP OData verwendet. +- Fuer direkte HANA-Tabellen/Views gibt es ebenfalls grafisches Mapping; das ist aber nicht der geplante Pfad fuer `ZSCHWEIZ`. + +Quellsysteme: + +- `SAP` = `SAP OData`, Anschlussart `SAP_GATEWAY`. +- `SAP_HANA` = `SAP HANA Tables/Views`, Anschlussart `HANA`. +- `BI1` und `SAGE` bleiben HANA-basierte Quellsysteme. +- `MANUAL_EXCEL` bleibt Excel/CSV. + +ABAP/SAP: + +- Datei `report.abap` enthaelt Report `ZTRAFAG_SCHWEIZ_EXPORT`. +- Ziel-Tabelle in SAP: `ZSCHWEIZ`. +- `BUKRS 1100` wird als Schweiz (`TRCH`, `CH`) geschrieben. +- `BUKRS 1200` wird als Oesterreich (`TRAT`, `AT`) geschrieben. +- `CUSTOMER_LAND` enthaelt das urspruengliche Kundenland. +- Der Report schreibt paketweise per Upsert. + +App-Seed: + +- Standort `ZSCHWEIZ` / `Schweiz/Oesterreich` wird inaktiv angelegt bzw. repariert. +- `SourceSystem = SAP`. +- Quelle `Z`, EntitySet `ZSCHWEIZSet`. +- Quelle und Feldmapping werden beim App-Start per Upsert nachgezogen; eine teilweise vorhandene ZSCHWEIZ-Konfiguration bleibt dadurch nicht leer. +- Initiales Mapping: + - `Tsc <- Z.TSC` + - `Land <- Z.LAND1` + - `InvoiceNumber <- Z.VBELN` + - `PositionOnInvoice <- Z.POSNR` + - `SalesPriceValue <- Z.NETWR_HC` + - `SalesCurrency <- Z.HWAER` + - `CustomerCountry <- Z.CUSTOMER_LAND` + +Wichtig fuer naechsten Einstieg: + +- Wenn die zentrale SAP-Service-URL noch auf `ZPOWERBI_EINKAUF_SRV` zeigt, muss beim Standort `ZSCHWEIZ` ein Service-URL-Override fuer den `ZSCHWEIZ`-OData-Service gesetzt werden. +- Feldinfos kommen ueber `$metadata`; manuelle Feldliste ist nur noetig, wenn Gateway/Metadata nicht funktioniert. +- Nach URL-Setzung: `Entity Sets refreshen`, `Felder aus Quellen laden`, Mapping kontrollieren, Standort aktivieren, Export testen. + +Verifikation: + +- Hauptprojekt Build erfolgreich. +- Tests `52/52` erfolgreich. + +## H160 - Nachtrag 2026-05-05 Aktueller Handoff FinanceProbe / Laenderabgleich + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-05-05 Aktueller Handoff FinanceProbe / Laenderabgleich + +Der aktuelle Arbeitsstand fuer den naechsten Einstieg ist der lokale FinanceProbe: + +```text +http://localhost:55417/finance +``` + +Der FinanceProbe wurde als Meeting-Ansicht erweitert: + +- `Meeting Ampel 2025` +- `Detail alle Laender` +- `Germany Excel sample check` +- `Spain CSV direct check` + +Ampel-Bedeutung: + +- Gruen: Ist/Soll passt rechnerisch gegen Referenz. +- Gelb: technische Daten vorhanden, aber Differenz oder fachliche Abgrenzung offen. +- Grau: keine belastbaren Ist-Daten im aktuellen Import. + +Wichtige Waehrungsregel fuer Management-Aussage: + +- Wenn die Quelle CHF liefert, kann CHF direkt als CHF gezeigt werden. +- Wenn die Quelle EUR/USD/GBP/INR usw. liefert, ist es Mandanten- bzw. Originalwaehrung. +- CHF-Ausweis braucht dann eine separate FX-Regel oder einen offiziell bestaetigten Kurs. + +## H161 - Spanien + +Quelle: HANDOFF_2026-04-15.md.raw + +### Spanien + +Vorhandene finale Kandidatendatei: + +```text +sagespain/v2/Spain_Sales_2025.csv +``` + +FinanceProbe liest diese Datei direkt. + +Aktueller Stand: + +- Zeilen: `4'341` +- Ist `SalesPriceValue`: `3'082'320.18` EUR +- Soll aus `check.xlsx`: `3'102'333.61` +- Differenz: `-20'013.43` +- Status: Gelb / Pruefen + +Technisch: + +- `ManualExcelImportService` kann jetzt semikolongetrennte CSV-Dateien lesen. +- Spanien-v2-CSV kann damit als `MANUAL_EXCEL` importiert werden. +- In der Detailtabelle wird Spanien nicht mehr als `Keine Daten` gezeigt, sondern als `Pruefen` mit dem v2-CSV-Wert. + +Offen fachlich: + +- Periodenlogik: `FechaFactura` vs. andere Datumsfelder +- Serien: `REG`, `LAT`, `PRO`, `REC` +- Behandlung von Gutschriften / `REC` +- offizielle Sage-Auswertung mit identischem Filter zur Sollzahl + +## H162 - Deutschland + +Quelle: HANDOFF_2026-04-15.md.raw + +### Deutschland + +Vorhandenes Beispielfile: + +```text +DE_Beispiel_Export_Daten.xlsx +``` + +Wichtig: + +- Das File ist ein Beispielfile, keine finale DE-Jahresdatei. +- Es darf nicht als finale Ist-Zahl gegen die Jahresreferenz verwendet werden. + +Technischer Check: + +- relevante Spalte: `NettoPreisGesamtX` +- Mapping-Ziel: `SalesPriceValue` +- Betragszeilen: `2` +- Summe: `8'290.70` EUR +- Waehrung: `EUR` + +Interpretation: + +- Deutschland-Format ist technisch verstanden. +- Mapping funktioniert. +- Finale DE-Zahl fehlt noch. +- Fuer Abschluss/Meeting wird ein vollstaendiger DE-Jahresfile 2025 oder ein bestaetigter Importlauf benoetigt. + +## H163 - Geaenderte wichtige Dateien + +Quelle: HANDOFF_2026-04-15.md.raw + +### Geaenderte wichtige Dateien + +- `Tools/FinanceProbe/Program.cs` + - Management-Ampel + - Spanien-v2-CSV-Direktcheck + - Deutschland-Beispielfile-Check +- `Services/ManualExcelImportService.cs` + - CSV-Support fuer manuelle Quellen +- `Services/DatabaseSeedService.cs` + - deaktivierter Spanien-Standort als Seed/Fallback +- `TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs` + - Tests fuer CSV/Mapping +- `SAGE_SPAIN_EXPORT_2026-05-05.md` + - Spanien-Doku +- `lastchange.md` + - chronologischer Abschlussstand + +## H164 - Letzte Verifikation + +Quelle: HANDOFF_2026-04-15.md.raw + +### Letzte Verifikation + +```text +dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal --no-restore +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal --no-restore +``` + +Ergebnis: + +- FinanceProbe Build erfolgreich +- Tests erfolgreich +- `50/50` Tests gruen +- FinanceProbe liefert `HTTP 200` + +## H165 - Nachtrag 2026-04-29 Dashboard-Referenzcheck Net Sales 2025 + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-04-29 Dashboard-Referenzcheck Net Sales 2025 + +Das Dashboard zeigt jetzt oberhalb der Exportaktionen einen Referenzcheck fuer `Net Sales Actuals 2025`. + +Zweck: + +- schnelle Gegenpruefung, ob die gezogenen Werte gegen `check.xlsx` / Power-BI-Referenz plausibel sind +- automatische Ermittlung des Summenfelds, das am besten zum Referenzwert passt +- sichtbar machen, ob aktuell `SalesPriceValue`, `DocTotalFC - VatSumFC` oder `DocTotal - VatSum` als Vergleichsbasis genutzt wird +- `DocumentTotal*` wird nur dedupliziert pro Beleg verwendet, weil es ein Belegkopfwert ist und in der positionsbasierten Datei pro Position wiederholt wird + +Logik: + +- Ist-Wert = bester Kandidat aus: + - Summe `CentralSalesRecords.SalesPriceValue` + - Summe `DocumentTotalForeignCurrency - VatSumForeignCurrency` + - Summe `DocumentTotalLocalCurrency - VatSumLocalCurrency` +- Belegkopfwerte werden vor dem Summieren per `TSC` + `DocumentType` + `DocumentEntry` dedupliziert; falls `DocumentEntry` fehlt, per `InvoiceNumber` +- Jahr = `InvoiceDate`, falls vorhanden, sonst `ExtractionDate` +- Vergleichsjahr = `2025` +- Referenzwerte sind aus `check.xlsx` / Power BI Stand 2026-04-29 im Code hinterlegt +- wenn ein Power-BI-Referenzwert vorhanden ist, wird dieser als Vergleich verwendet +- sonst wird der LC-Referenzwert verwendet + +Angezeigt werden: + +- Firma +- Ist 2025 +- Referenz +- Summenfeld +- Referenzquelle (`Power BI` oder `LC`) +- Differenz +- Waehrungen +- Zeilen +- Status `OK`, `Pruefen` oder `Keine Daten` + +Verifikation: + +- `dotnet build .\TrafagSalesExporter.csproj --verbosity minimal` erfolgreich +- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` erfolgreich +- lokaler Dashboard-Start geprueft: `http://localhost:55416` antwortet mit HTTP `200` + +Naechster Bedienablauf, damit die korrekten Summen kommen: + +1. App starten bzw. offen lassen: `http://localhost:55416` +2. Im Dashboard neue Daten ziehen: + - entweder `Alle exportieren` + - oder einzelne Standorte per `Export` +3. Danach `Zentrale Datei neu erzeugen` ausfuehren. +4. Oben im Dashboard den Block `Net Sales Actuals 2025 Referenz` pruefen. +5. Entscheidend ist die Spalte `Summenfeld`: + - `Sales Price/Value` = Positionssumme + - `DocTotalFC - VatSumFC` = Netto-Belegsumme in Belegwaehrung, dedupliziert pro Beleg + - `DocTotal - VatSum` = Netto-Belegsumme in Hauswaehrung, dedupliziert pro Beleg +6. `Status = OK` bedeutet: Abweichung zur Referenz maximal 1. +7. `Status = Pruefen` bedeutet: Feld, Datenquelle, Zeitraum oder Standortkonfiguration fachlich kontrollieren. + +Wichtig: + +- Mit alten zentralen Daten bleiben die neuen B1-Felder leer bzw. `0`. +- Fuer die echte Pruefung von `DocEntry`, `DocTotal*`, `VatSum*`, `DocRate` und `OADM.MainCurncy` muss zuerst neu exportiert werden. +- Fuer neue Jahre ist aktuell noch kein dynamischer Referenzjahres-Schalter eingebaut; der harte Referenzcheck ist Stand jetzt auf `2025`, weil `check.xlsx` die 2025-Referenzen enthaelt. + +## H166 - Nachtrag 2026-04-29 Export-all-Abbruch / SQLite-FK-Reparatur + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-04-29 Export-all-Abbruch / SQLite-FK-Reparatur + +Beim Klick auf `Export all` kam: + +- `An error occurred while saving the entity changes. See the inner exception for details.` + +Ursache: + +- die bestehende SQLite-DB hatte in `ExportLogs`, `AppEventLogs` und `CentralSalesRecords` noch Foreign Keys auf `"Sites_repair_old"` +- diese Reparatur-Zwischentabelle existiert nicht mehr +- beim Speichern neuer Logs oder zentraler Datensaetze konnte SQLite deshalb nicht mehr korrekt speichern + +Korrektur: + +- `DatabaseSchemaMaintenanceService` erkennt jetzt nicht nur `Sites_old`, sondern auch alte Reparaturtabellen wie `Sites_repair_old` +- betroffene Tabellen werden beim App-Start automatisch neu aufgebaut +- `AppEventLogService` und `ExportLogService` fangen eigene Log-Speicherfehler ab, damit Logging-Probleme nicht den ganzen Export abbrechen +- Dashboard-Fehlerausgaben zeigen jetzt auch die Inner Exception, falls vorhanden + +Verifikation: + +- App neu gestartet +- DB-Schema direkt geprueft: + - `AppEventLogs` -> `FOREIGN KEY (SiteId) REFERENCES Sites (Id)` + - `ExportLogs` -> `FOREIGN KEY (SiteId) REFERENCES Sites (Id)` + - `CentralSalesRecords` -> `FOREIGN KEY (SiteId) REFERENCES Sites (Id)` +- `dotnet build .\TrafagSalesExporter.csproj --verbosity minimal` erfolgreich +- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` erfolgreich + +Direkt danach beobachtete Exportfehler: + +- Frankreich/Italien/USA: `invalid schema name ... line 40` durch HANA-Query-Quoting + - Ursache: Query nutzte `"schema"."Tabelle"` + - Korrektur: wieder `schema."Tabelle"` wie im alten funktionierenden Stand +- Indien: `authentication failed` + - Konfiguration/Credentials pruefen, kein Codefehler aus dieser Aenderung +- England/Spanien/Deutschland: `MANUAL_EXCEL`, aber keine manuelle Excel-Datei hinterlegt + - entweder Datei hinterlegen oder Standort deaktivieren/Quellsystem korrigieren + +## H167 - Nachtrag 2026-04-29 B1-Belegwaehrungsfelder aus HANA + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-04-29 B1-Belegwaehrungsfelder aus HANA + +Der HANA/B1-Export wurde um Beleg- und Hauswaehrungsfelder erweitert. + +Grund: + +- `p.StockPrice` muss fachlich in der B1-Hauswaehrung bewertet werden +- die Hauswaehrung kommt aus `OADM.MainCurncy` +- bisher wurde `StandardCostCurrency` aus `p.Currency` bzw. `h.DocCur` abgeleitet +- fuer Power-BI-/Cockpit-Gegenpruefung muessen Belegwaehrung, Hauswaehrung, Netto-/Steuerbetraege und Kurs sichtbar sein + +Neue Felder in `SalesRecord` und `CentralSalesRecord`: + +- `DocumentEntry` +- `DocumentCurrency` +- `DocumentTotalForeignCurrency` +- `DocumentTotalLocalCurrency` +- `VatSumForeignCurrency` +- `VatSumLocalCurrency` +- `DocumentRate` +- `CompanyCurrency` + +B1-Feldmapping: + +- `DocumentEntry` = `OINV/ORIN.DocEntry` +- `DocumentCurrency` = `OINV/ORIN.DocCur` +- `DocumentTotalForeignCurrency` = `OINV/ORIN.DocTotalFC` +- `DocumentTotalLocalCurrency` = `OINV/ORIN.DocTotal` +- `VatSumForeignCurrency` = `OINV/ORIN.VatSumFC` +- `VatSumLocalCurrency` = `OINV/ORIN.VatSum` +- `DocumentRate` = `OINV/ORIN.DocRate` +- `CompanyCurrency` = `OADM.MainCurncy` +- `StandardCostCurrency` = `OADM.MainCurncy` + +Technische Umsetzung: + +- `HanaQueryService` liest `OADM` jetzt per `CROSS JOIN` +- Invoice- und Credit-Note-Query liefern die neuen Felder +- bei Gutschriften werden Dokument- und Steuerbetraege mit negativem Vorzeichen uebernommen +- `CentralSalesRecords`-Schema wurde erweitert +- bestehende SQLite-DBs erhalten die neuen Spalten per `DatabaseSchemaMaintenanceService` +- `CentralSalesRecordService` persistiert und liest die neuen Felder +- `ExcelExportService` schreibt die neuen Spalten in Standort- und `Sales_All_*.xlsx`-Dateien +- `ManualExcelImportService` kann die neuen Spalten wieder einlesen +- `ConfigTransferService` erhaelt die neuen Felder beim Remapping zentraler Laufzeitdaten + +Wichtig fuer Power BI: + +- die neuen `DocumentTotal*`- und `VatSum*`-Felder sind Belegkopfwerte +- sie werden in der positionsbasierten Excel pro Positionszeile wiederholt +- diese Felder duerfen daher nicht blind positionsweise summiert werden +- fuer Belegkopfsummen in Power BI zuerst nach `DocumentType`, `Invoice Number`, `TSC` und ggf. `Land` deduplizieren +- besser: nach `TSC` + `DocumentType` + `DocumentEntry` deduplizieren, weil `DocEntry` aus B1 jetzt mitgezogen wird +- positionsbasierte Auswertungen sollen weiterhin mit positionsbezogenen Feldern wie `Sales Price/Value`, `Quantity` oder `Standard cost` arbeiten + +Wichtig zum aktuellen Datenbestand: + +- alte zentrale Daten wurden vor der Erweiterung exportiert und haben fuer die neuen B1-Felder noch `0` +- nach einem neuen Export/Rebuild der zentralen Daten koennen `DocEntry`, `DocTotal*`, `VatSum*`, `DocRate` und `OADM.MainCurncy` fachlich verglichen werden + +Verifikation: + +- `dotnet build .\TrafagSalesExporter.csproj --verbosity minimal` erfolgreich +- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal` erfolgreich +- `48/48` Tests gruen +- `ManualExcelImportServiceTests` pruefen die neuen Excel-Spalten +- `CentralSalesRecordServiceTests` pruefen Persistenz und Ruecklesen der neuen B1-Felder + +## H168 - Nachtrag 2026-04-29 Clean-Code-/DI-Befund + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-04-29 Clean-Code-/DI-Befund + +Der aktuelle Code ist DI-orientiert und deutlich besser strukturiert als zu Beginn des Refactorings, aber noch nicht durchgehend ein Clean-Code-Ideal. + +Positiv: + +- Services werden weitgehend ueber Interfaces und DI verdrahtet +- `DataSourceAdapter` trennt die Quellsysteme +- Page-Services reduzieren direkte DB-Logik in mehreren Razor-Seiten +- `Scoped` fuer UI-nahe Services und `Singleton` fuer gemeinsame Infrastruktur/Orchestrierung ist bewusst gewaehlt +- Testabdeckung fuer zentrale Fachlogik ist vorhanden und waechst + +Weiterhin offene Clean-Code-Risiken: + +- `DatabaseInitializationService` ist weiterhin produktiver Reparatur-/Migrationspfad +- `Settings.razor` und `Standorte.razor` enthalten noch viel Workflow-/UI-Logik +- `ManagementCockpitService` und `ConfigTransferService` sind breit und sollten spaeter weiter aufgeteilt werden +- Retry-/Robustheitslayer fuer externe Systeme fehlt +- Secret-Store fehlt +- Auth-Rollenmodell ist aktuell pragmatisch, aber noch grob + +Bewertung: + +- Architektur: brauchbar bis gut +- DI: grundsaetzlich sauber +- Clean Code: mittel bis gut, mit klaren Altlasten + +Dieser Befund wurde bewusst nur dokumentiert. Die strukturelle Bereinigung wird spaeter priorisiert. + +## H169 - Nachtrag 2026-04-29 Authentifizierung / AD-Zugriffsschutz + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-04-29 Authentifizierung / AD-Zugriffsschutz + +Nach Rueckmeldung der IT wurde ein Zugriffsschutz fuer die Blazor-App eingebaut. + +Vorher konnte jeder Benutzer mit Netzwerkzugriff auf die App-URL die Anwendung oeffnen. Das war kritisch, weil die App Verkaufsdaten, Standort-/Quellsystemkonfiguration, SharePoint-Konfiguration, Config Import/Export und Secrets bzw. Zugangsdatenfelder beruehrt. + +Neuer Stand: + +- die App ist grundsaetzlich authentifizierungspflichtig +- produktives Ziel ist Windows Authentication / Active Directory +- Berechtigungen laufen ueber AD-Gruppen +- es gibt keine eigene Benutzer-/Passwortverwaltung in der App +- es gibt keinen versteckten produktiven Backdoor + +Neue Security-Dateien: + +- `Security/SecurityOptions.cs` +- `Security/SecurityPolicies.cs` +- `Security/DevelopmentAuthenticationHandler.cs` + +Geaenderte zentrale Dateien: + +- `Program.cs` +- `Components/Routes.razor` +- `Components/_Imports.razor` +- `Components/Layout/NavMenu.razor` +- `Components/Layout/MainLayout.razor` +- `appsettings.json` +- `appsettings.Development.json` + +Aktuelles Rollenmodell: + +- `Security:AccessGroups` steuert Zugriff auf die App +- `Security:AdminGroups` steuert Admin-Berechtigung +- Default-Gruppen sind `TRAFAG\\TrafagSalesExporter-Users` und `TRAFAG\\TrafagSalesExporter-Admins` +- echte Gruppennamen muessen von der IT bestaetigt oder angepasst werden + +Admin-geschuetzte Seiten: + +- `Settings` +- `Standorte` +- `Transformations` + +Dashboard, Management Cockpit und Logs bleiben fuer berechtigte angemeldete Benutzer sichtbar. + +Development: + +- `appsettings.Development.json` aktiviert bei `ASPNETCORE_ENVIRONMENT=Development` einen lokalen Development-Auth-Handler +- Default-User: `DEV\\TrafagDeveloper` +- `DevelopmentUserIsAdmin=true`, damit lokal weiter programmiert werden kann +- produktiv darf die App nicht mit `Development` laufen + +IIS-/IT-Hinweise: + +1. Windows Authentication aktivieren +2. Anonymous Authentication deaktivieren +3. `ASPNETCORE_ENVIRONMENT` produktiv nicht auf `Development` setzen +4. AD-Gruppen fuer Benutzer und Admins anlegen oder bestehende Gruppen eintragen +5. `Security:AccessGroups` und `Security:AdminGroups` in produktiver Konfiguration korrekt setzen + +Aktueller IIS-Deployment-Nachtrag 2026-05-20: + +- Vollstaendige Detaildoku: `docs/DEPLOYMENT_IIS_HANDOFF_2026-05-19.md` +- Fuehrendes Projekt bleibt `TrafagSalesExporter`. +- Publish-Ausgabe heisst fuer IIS weiterhin `BiDashboard.dll`, ohne EXE/AppHost. +- Publish-Ziel: `\\trch-webapp-bidashboard.trafagch.local\BiDashboard$\` +- Browser-URL: `https://trch-webapp-bidashboard.trafagch.local/BiDashboard/` +- `diag.txt` unter `/BiDashboard/diag.txt` ist erreichbar und beweist, dass IIS auf den richtigen Publish-Ordner zeigt. +- Der verbleibende `500` entsteht beim ASP.NET-Core-Start oder im ASP.NET-Core-IIS-Modul. +- `web.config` steht aktuell auf `hostingModel="outofprocess"`, `stdoutLogEnabled="true"` und `ASPNETCORE_DETAILEDERRORS=true`. +- Wenn `logs` leer bleibt, muss der Serveradmin im Event Viewer pruefen: `IIS AspNetCore Module V2`, `.NET Runtime`, `Application Error`. +- Server muss kein Microsoft Excel installiert haben; XLSX wird ueber ClosedXML/OpenXML gelesen. + +Verifikation: + +```text +dotnet build .\TrafagSalesExporter.csproj --verbosity minimal +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal +``` + +Ergebnis: + +- Build erfolgreich +- Tests erfolgreich +- `48/48` Tests gruen +- Auth-Policy-Tests fuer AccessGroup, AdminGroup und Development-Admin vorhanden +- lokaler Development-Auth-Start geprueft: `http://localhost:55416` antwortet mit HTTP `200` +- bekannte MudBlazor-Analyzer-Warnungen zu `Dense` bleiben + +## H170 - Nachtrag 2026-04-29 Management-Cockpit-Auswertung + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-04-29 Management-Cockpit-Auswertung + +Seit dem letzten dokumentierten Stand vom 2026-04-17 wurde das `Management Cockpit` weiter ausgebaut. Dieser Abschnitt rekonstruiert den aktuellen Stand aus dem Code, weil die Aenderungen nach einem PC-Absturz nicht direkt nachdokumentiert wurden. + +## H171 - Neue Auswertlogik + +Quelle: HANDOFF_2026-04-15.md.raw + +### Neue Auswertlogik + +Das Cockpit ist nicht mehr nur auf Umsatz als feste Kennzahl beschraenkt. + +Neu gibt es auswählbare Summenfelder: + +- `Sales Price/Value` +- `Quantity` +- `Standard cost` +- `Quantity * Standard cost` + +Diese Auswahl gilt fuer: + +- dateibasierte Analyse vorhandener Excel-Exporte +- zentrale Roh-Auswertung aus `CentralSalesRecords` + +## H172 - Anzeige-Waehrung und Wechselkurse + +Quelle: HANDOFF_2026-04-15.md.raw + +### Anzeige-Waehrung und Wechselkurse + +Fuer betragliche Summenfelder kann jetzt eine Anzeige-Waehrung gewaehlt werden: + +- `EUR` +- `USD` +- `Original` + +Die Umrechnung nutzt `CurrencyExchangeRateService`. + +Wichtig: + +- nicht-betragliche Werte wie `Quantity` werden nicht umgerechnet +- bei `Original` bleiben Werte in der jeweiligen Quellwaehrung +- bei fehlendem Wechselkurs wird der betroffene Wert mit `0` in die Zielwaehrung eingerechnet +- fehlende Kurse werden als Anzahl `Nicht umgerechnet` bzw. in Hinweisen/Finding sichtbar gemacht +- Wechselkurse werden pro Quellwaehrung, Zielwaehrung und Datum gecacht, damit grosse Auswertungen nicht unnoetig oft die gleiche Rate aufloesen + +## H173 - Zusätzliche Summenfelder in der zentralen Sicht + +Quelle: HANDOFF_2026-04-15.md.raw + +### Zusätzliche Summenfelder in der zentralen Sicht + +Die zentrale Roh-Auswertung kann neben dem Haupt-Summenfeld weitere Summenfelder anzeigen. + +Diese Zusatzwerte werden aktuell in den Zeitreihen ausgegeben: + +- Jahreswerte +- Monatswerte +- Tageswerte im gewaehlten Monat + +Beispiel: + +- Hauptwert: `Sales Price/Value` +- Zusatzwerte: `Quantity`, `Quantity * Standard cost` + +Damit kann die zentrale Sicht Umsatz, Mengen und Kostennaeherung nebeneinander darstellen. + +## H174 - UI-Stand + +Quelle: HANDOFF_2026-04-15.md.raw + +### UI-Stand + +`Components/Pages/ManagementCockpit.razor` hat neue Controls: + +- Summenfeld fuer Excel-Dateianalyse +- Anzeige-Waehrung fuer Excel-Dateianalyse +- Summenfeld fuer zentrale Roh-Auswertung +- weitere Summenfelder fuer zentrale Roh-Auswertung per Mehrfachauswahl +- Anzeige-Waehrung fuer zentrale Roh-Auswertung + +Die Tabellen wurden von festem Text `Umsatz` auf generische `Werte` / `Jahreswerte` / `Monatswerte` umgestellt. + +Die vorher dokumentierte Manometer-/Gauge-Sicht ist im aktuellen Arbeitsstand nicht mehr aktiv sichtbar. Stattdessen liegt der Fokus wieder auf Kennzahlen, Hinweisen und tabellarischen Auswertungen. + +## H175 - Technische Umsetzung + +Quelle: HANDOFF_2026-04-15.md.raw + +### Technische Umsetzung + +Betroffene Dateien: + +- `Components/Pages/ManagementCockpit.razor` +- `Models/ManagementCockpitModels.cs` +- `Services/IManagementCockpitService.cs` +- `Services/ManagementCockpitPageService.cs` +- `Services/ManagementCockpitService.cs` +- `TrafagSalesExporter.Tests/ManagementCockpitServiceTests.cs` + +Neue bzw. erweiterte Modelle: + +- `ManagementCockpitValueFieldKeys` +- `ManagementCockpitCurrencyOptions` +- `ManagementCockpitValueFieldOption` +- `ManagementCockpitAnalysisOptions` +- `ManagementCockpitAggregatedFieldValue` + +Neue Felder in Ergebnissen: + +- gewaehltes Summenfeld +- Anzeige-Waehrung +- Anzahl fehlender Wechselkurse +- Zusatzwerte pro Zeitreihe + +## H176 - Testabdeckung + +Quelle: HANDOFF_2026-04-15.md.raw + +### Testabdeckung + +Die `ManagementCockpitServiceTests` wurden erweitert um Tests fuer: + +- Umrechnung zentraler Werte in EUR +- Caching von Wechselkursauflösungen +- Mengen-Summe ohne Waehrungsumrechnung +- Zusatz-Summenfelder in Jahres- und Monatswerten + +Noch offen: + +- UI manuell pruefen +- genaue fachliche Zielwaehrung fuer Standardberichte bestaetigen +- entscheiden, ob `CHF` ebenfalls als direkte Anzeige-Waehrung angeboten werden soll +- klaeren, ob fehlende Wechselkurse langfristig mit `0`, Originalwert oder separater Fehlergruppe dargestellt werden sollen + +## H177 - Nachtrag 2026-04-17 Refactoring- und HANA-Stand + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-04-17 Refactoring- und HANA-Stand + +Der Stand aus den frueheren Nachtraegen ist fuer Architektur und HANA-Zugriff nicht mehr vollstaendig. + +Inzwischen gilt zusaetzlich: + +## H178 - 1. DataSourceAdapter-Pattern ist eingefuehrt + +Quelle: HANDOFF_2026-04-15.md.raw + +### 1. DataSourceAdapter-Pattern ist eingefuehrt + +Die Quellsysteme `HANA`, `SAP_GATEWAY` und `MANUAL_EXCEL` laufen nicht mehr ueber einen grossen `if/else`-Block im `SiteExportService`. + +Neu: + +- `Services/DataSources/IDataSourceAdapter.cs` +- `Services/DataSources/IDataSourceAdapterResolver.cs` +- `Services/DataSources/DataSourceAdapterResolver.cs` +- `Services/DataSources/DataSourceFetchContext.cs` +- `Services/DataSources/DataSourceFetchResult.cs` +- `Services/DataSources/DataSourceCredentials.cs` +- `Services/DataSources/HanaDataSourceAdapter.cs` +- `Services/DataSources/SapGatewayDataSourceAdapter.cs` +- `Services/DataSources/ManualExcelDataSourceAdapter.cs` + +Neuer Zuschnitt: + +- `SiteExportService` ist jetzt deutlich schlanker und nur noch Export-Pipeline +- Adapter loesen Quellsystem-spezifisches Laden auf +- fuer ein weiteres Quellsystem ist kein Umbau im `SiteExportService` mehr noetig + +## H179 - 2. Page-Services sind nicht mehr Singleton + +Quelle: HANDOFF_2026-04-15.md.raw + +### 2. Page-Services sind nicht mehr Singleton + +UI-nahe Services laufen jetzt pro Blazor-Circuit als `Scoped`. + +Betroffen: + +- `ISettingsPageService` +- `IStandortePageService` +- `IStandorteSapEditorService` +- `IManagementCockpitPageService` +- `IDashboardPageService` +- `ILogsPageService` +- `ITransformationsPageService` + +Wichtig: + +- `ExportOrchestrationService` bleibt bewusst `Singleton`, weil Exportstatus ueber Circuits geteilt werden muss +- stateless Infrastruktur-Services bleiben weiter `Singleton` + +## H180 - 3. Datenbank-Initialisierung ist aufgeteilt + +Quelle: HANDOFF_2026-04-15.md.raw + +### 3. Datenbank-Initialisierung ist aufgeteilt + +Der fruehere monolithische `DatabaseInitializationService` ist inzwischen in grobe Verantwortungsbloecke getrennt: + +- `DatabaseInitializationService` als Orchestrator +- `DatabaseSchemaMaintenanceService` fuer Schema-/Repair-Logik +- `DatabaseSeedService` fuer Defaultdaten und Stammdaten-Seeding +- `DatabaseInitializationService.SchemaSql.cs` als SQL-Definitionsblock + +Das reduziert das groesste Architektur-Risiko deutlich, auch wenn die Startmigrationen weiterhin ein sensibler Teil des Systems bleiben. + +## H181 - 4. Weitere Razor-Seiten sind entlastet + +Quelle: HANDOFF_2026-04-15.md.raw + +### 4. Weitere Razor-Seiten sind entlastet + +Neben den frueher bereits entlasteten Seiten laufen jetzt auch diese Seiten ueber Page-Services statt direkten `DbContext`-Zugriffen: + +- `Dashboard.razor` ueber `DashboardPageService` +- `Logs.razor` ueber `LogsPageService` +- `Transformations.razor` ueber `TransformationsPageService` + +Der Rest an direkter Persistenzlogik in Razor ist damit deutlich kleiner geworden. + +## H182 - 5. Kritische HANA-Risiken wurden entschärft + +Quelle: HANDOFF_2026-04-15.md.raw + +### 5. Kritische HANA-Risiken wurden entschärft + +## H183 - SQL-Injection-Schutz + +Quelle: HANDOFF_2026-04-15.md.raw + +#### SQL-Injection-Schutz + +Im `HanaQueryService` wurden die kritischen interpolierten SQL-Stellen bereinigt: + +- `tsc` und `dateFilter` laufen jetzt parametriert in `HanaCommand` +- `schema` wird als Identifier streng validiert und gequotet + +Damit ist der akute Injection-Pfad in den HANA-Verkaufsabfragen geschlossen. + +## H184 - Async statt `.GetAwaiter().GetResult()` + +Quelle: HANDOFF_2026-04-15.md.raw + +#### Async statt `.GetAwaiter().GetResult()` + +Die blockierenden HANA-Aufrufe wurden auf echte Async-Methoden umgestellt: + +- `IHanaQueryService` ist jetzt async-basiert +- `HanaQueryService` nutzt `OpenAsync`, `ExecuteReaderAsync`, `ReadAsync`, `ExecuteScalarAsync` +- Aufrufer wie `HanaDataSourceAdapter`, `StandortePageService` und `SettingsPageService` verwenden keine `Task.Run`-Workarounds mehr fuer HANA + +Damit ist das fruehere Deadlock-/Blocking-Risiko in diesem Pfad deutlich reduziert. + +## H185 - 6. Test- und Build-Stand + +Quelle: HANDOFF_2026-04-15.md.raw + +### 6. Test- und Build-Stand + +Verifiziert wurde zuletzt mit: + +```text +dotnet build .\TrafagSalesExporter.csproj --verbosity minimal +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal +``` + +Ergebnis: + +- Projekt-Build erfolgreich +- `36/36` Tests gruen + +Bekannt: + +- `dotnet build .\TrafagSalesExporter.sln` endet in dieser Umgebung weiterhin mit Exitcode `1` ohne konkrete Compilerfehler +- das Hauptprojekt und das Testprojekt bauen aber erfolgreich +- bekannte Warnungen bleiben: + - `MSB3270` wegen HANA-Assembly-Architektur + - MudBlazor-Analyzer zu `Dense` + +## H186 - 7. Aktuelles Architektururteil + +Quelle: HANDOFF_2026-04-15.md.raw + +### 7. Aktuelles Architektururteil + +Der Zustand ist jetzt deutlich professioneller als zu Beginn des Refactorings: + +- Datenquellen sauberer getrennt +- UI konsistenter ueber Page-Services geschnitten +- groesster Start-/Schema-Block zerlegt +- HANA-Pfad sicherer und sauberer asynchron + +Aber noch nicht vollendet: + +- keine gezielten Adapter-/Resolver-Unit-Tests +- keine Retry-Strategie fuer SharePoint / SAP / HANA-Netzpfade +- kein Secret-Store +- `DatabaseInitializationService` bleibt trotz Zerlegung ein sensibler produktiver Migrationspfad + +## H187 - Nachtrag 2026-04-17 + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-04-17 + +Der dokumentierte Stand in diesem Handoff war bei der Waehrungslogik nicht mehr aktuell. + +Inzwischen gilt: + +- Kurstabellen fuer `CurrencyExchangeRates` sind im System vorhanden +- `Settings` enthaelt bereits eine Pflegeoberflaeche fuer Wechselkurse +- `ExchangeRateImportService` importiert ECB-Tageskurse nach `CurrencyExchangeRates` +- `NormalizeCurrencyCode` ist als Value-Transformation vorhanden +- `ConvertCurrency` ist als Record-Transformation vorhanden +- `Program.cs` registriert beide Strategien sowie `CurrencyExchangeRateService` und `ExchangeRateImportService` + +Wichtig: + +- die Roh-Auswertung im `Management Cockpit` rechnet Stand heute weiterhin bewusst **nicht** in CHF um +- dort bleibt der Umsatz weiterhin in `Sales Currency` +- die Waehrungsumrechnung ist aktuell Teil des allgemeinen Transformations-/Mapping-Systems, nicht der Cockpit-Rohsicht + +Zusatzlich wurden am 2026-04-17 fehlende Unit-Tests fuer die Waehrungslogik nachgezogen: + +- `CurrencyExchangeRateServiceTests` +- `ExchangeRateImportServiceTests` +- Erweiterungen in + - `TransformationStrategiesTests` + - `RecordTransformationServiceTests` + - `TransformationCatalogTests` + +Aktueller Teststatus nach diesem Nachtrag: + +```text +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal +``` + +Ergebnis: + +- erfolgreich +- `31/31` Tests gruen +- bekannte Warnung bleibt: + - SAP HANA Architekturwarnung `MSB3270` + +## H188 - Architekturpruefung 2026-04-17 + +Quelle: HANDOFF_2026-04-15.md.raw + +## Architekturpruefung 2026-04-17 + +Es wurde eine erneute Gesamtpruefung der Architektur gemacht, ausdruecklich ohne neue Implementierung. + +## H189 - Gesamturteil + +Quelle: HANDOFF_2026-04-15.md.raw + +### Gesamturteil + +Die Grundrichtung ist weiterhin sinnvoll: + +- klare Trennung der Quellsysteme `SAP`, `BI1`, `SAGE`, `MANUAL_EXCEL` +- zentrales fachliches Zielschema ueber `SalesRecord` +- zentrale technische Ablage ueber `CentralSalesRecords` +- separater Orchestrator fuer Standort- und Konsolidierungsexport +- Transformationssystem als eigener Layer + +Aber: + +- die Architektur ist **noch nicht stabil genug**, um sie als "fertig sauber" zu betrachten +- die groessten Risiken liegen aktuell nicht in SAP oder Waehrungen, sondern in + - Start-/Schema-Initialisierung + - Config-Import + - Verteilung von Logik zwischen Razor-Seiten und Services + +## H190 - Wichtigste Architektur-Risiken + +Quelle: HANDOFF_2026-04-15.md.raw + +### Wichtigste Architektur-Risiken + +## H191 - 1. Start-/Schema-Initialisierung ist fragil + +Quelle: HANDOFF_2026-04-15.md.raw + +#### 1. Start-/Schema-Initialisierung ist fragil + +`DatabaseInitializationService` mischt derzeit: + +- `EnsureCreated` +- manuelle `ALTER TABLE`-Pflege +- FK-Reparaturlogik +- Seeding +- empfohlenes Regel-Seeding + +Das ist funktional hilfreich, aber architektonisch gefaehrlich, weil: + +- die App-Initialisierung dadurch viel implizite Datenmigration enthaelt +- Verhalten schwer vorhersehbar wird +- Fehler im Migrationspfad sofort produktive Daten treffen + +Wichtiger konkreter Befund aus der Pruefung: + +- beim Kopieren von `Sites_old` nach `Sites` ist die Spaltenreihenfolge im SQL inkonsistent +- dadurch koennen Werte wie `ManualImportFilePath`, `SapServiceUrl`, `SapEntitySet` verschoben gespeichert werden +- das ist eine reale Datenkorruptionsgefahr und kein reines Architekturthema + +## H192 - 2. Config-Import ist destruktiv und nicht atomar + +Quelle: HANDOFF_2026-04-15.md.raw + +### 2. Config-Import ist destruktiv und nicht atomar + +`ConfigTransferService.ImportJsonAsync` loescht aktuell zuerst grosse Teile der Konfiguration und Daten: + +- Sites +- HanaServers +- Transformation Rules +- SAP-Konfiguration +- Wechselkurse +- sogar `CentralSalesRecords` + +und baut danach mit mehreren `SaveChangesAsync()`-Zwischenschritten neu auf. + +Risiko: + +- wenn der Import in der Mitte scheitert, bleibt das System teilweise geloescht zurueck +- `CentralSalesRecords` gehoeren fachlich ohnehin nicht sauber in einen normalen Config-Import + +## H193 - 3. Zu viel Fach- und Persistenzlogik in Razor-Seiten + +Quelle: HANDOFF_2026-04-15.md.raw + +### 3. Zu viel Fach- und Persistenzlogik in Razor-Seiten + +`Settings.razor` und `Standorte.razor` machen aktuell sehr viel direkt: + +- `DbContext` oeffnen +- Daten laden und speichern +- Konfigurationsimport/-export anstossen +- SAP-Refresh +- Upload-Handling +- Teile der Validierung / Persistenzlogik + +Das funktioniert momentan, fuehrt aber langfristig zu: + +- schwer testbarer UI-Logik +- verstreuten Regeln +- hoeherem Seiteneffekt-Risiko bei Erweiterungen + +## H194 - 4. Vertrag zwischen Orchestrator und konsolidiertem Export ist unscharf + +Quelle: HANDOFF_2026-04-15.md.raw + +### 4. Vertrag zwischen Orchestrator und konsolidiertem Export ist unscharf + +`ExportOrchestrationService` sammelt bei `ExportAllAsync` bereits `consolidatedRecords`, uebergibt sie weiter, aber `ConsolidatedExportService` ignoriert diesen Parameter und liest erneut aus `CentralSalesRecords`. + +Das zeigt ein offenes Architekturthema: + +- Soll die zentrale Datei aus dem Live-Exportlauf gebaut werden? +- oder immer nur aus dem persistenten Read Model `CentralSalesRecords`? + +Aktuell ist beides halb vorhanden. + +## H195 - 5. Reporting-/Cockpit-Logik ist noch nicht voll verallgemeinert + +Quelle: HANDOFF_2026-04-15.md.raw + +### 5. Reporting-/Cockpit-Logik ist noch nicht voll verallgemeinert + +Bei der Pruefung wurde gesehen: + +- `ManagementCockpitService` enthaelt noch hartcodierte Jahreslogik fuer `2025` und `2026` +- die Rohsicht bleibt bewusst ohne CHF-Umrechnung + +Das ist fuer den aktuellen Stand akzeptabel, zeigt aber: + +- Reporting ist noch kein voll abstrahierter fachlicher Layer + +## H196 - Empfohlenes Sollbild + +Quelle: HANDOFF_2026-04-15.md.raw + +## Empfohlenes Sollbild + +Die naechste Architektur-Stufe sollte in diese Richtung gehen: + +## H197 - 1. Klare Schichten + +Quelle: HANDOFF_2026-04-15.md.raw + +### 1. Klare Schichten + +- UI: + - Razor nur fuer Interaktion, Anzeige, Formularzustand +- Application: + - Use Cases / Commands / Queries fuer Export, Config, SAP-Refresh, Wechselkurse, Standortpflege +- Domain / Fachlogik: + - Transformationen, Mappingregeln, Waehrungsumrechnung, Cockpit-Berechnungen +- Infrastructure: + - HANA, SAP Gateway, SQLite, SharePoint, Dateisystem + +## H198 - 2. Versionierte Migrationen statt manueller Start-Reparaturen + +Quelle: HANDOFF_2026-04-15.md.raw + +### 2. Versionierte Migrationen statt manueller Start-Reparaturen + +Statt immer mehr Reparaturlogik beim App-Start: + +- Schema-Aenderungen versionieren +- Migrationspfade testbar machen +- Startlogik nur noch fuer minimale Bootstrap-Aufgaben behalten + +## H199 - 3. Config-Import als atomarer Vorgang + +Quelle: HANDOFF_2026-04-15.md.raw + +### 3. Config-Import als atomarer Vorgang + +Ziel: + +- alles in einer Transaktion oder bewusst in klar getrennten Phasen +- kein halb geloeschter Zustand bei Fehlern +- `CentralSalesRecords` aus normalem Config-Import eher herausnehmen + +## H200 - 4. Zentrale Export-Semantik entscheiden + +Quelle: HANDOFF_2026-04-15.md.raw + +### 4. Zentrale Export-Semantik entscheiden + +Explizit festlegen: + +- zentrale Datei immer aus `CentralSalesRecords` + oder +- zentrale Datei aus dem aktuellen Export-Snapshot + +Danach die doppelte Semantik entfernen. + +## H201 - Priorisierung aus Architektursicht + +Quelle: HANDOFF_2026-04-15.md.raw + +## Priorisierung aus Architektursicht + +Wenn nach Stabilitaet priorisiert wird, dann in dieser Reihenfolge: + +1. `DatabaseInitializationService` / Migrationspfad absichern +2. `ConfigTransferService.ImportJsonAsync` atomar und weniger destruktiv machen +3. Logik aus `Settings.razor` und `Standorte.razor` in Anwendungsservices verschieben +4. Export-Semantik fuer Konsolidierung vereinheitlichen +5. erst danach weitere Fachfeatures wie Cockpit-CHF, Budget, Gruppenlogik + +## H202 - Kurzfazit + +Quelle: HANDOFF_2026-04-15.md.raw + +## Kurzfazit + +Die Architektur ist nicht schlecht. Das Grundmodell traegt. + +Aber: + +- sie ist noch nicht robust genug fuer ruhigen weiteren Ausbau ohne technische Konsolidierung +- die aktuelle Hauptgefahr liegt in Infrastruktur- und Persistenzlogik, nicht in den Fachfeatures + +Fuer den naechsten Einstieg nach Absturz gilt daher: + +1. zuerst diesen Architektur-Nachtrag lesen +2. dann `DatabaseInitializationService` und `ConfigTransferService` als Risikobloecke ansehen +3. neue Fachfeatures erst nach dieser technischen Konsolidierung beginnen + +## H203 - Nachtrag HANA-/Standort-Workflow 2026-04-17 + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag HANA-/Standort-Workflow 2026-04-17 + +Nach der Architekturpruefung wurde der doppelte HANA-Workflow bereinigt. + +## H204 - Altes Problem + +Quelle: HANDOFF_2026-04-15.md.raw + +### Altes Problem + +Vorher gab es zwei konkurrierende Stellen fuer HANA-Konfiguration: + +- oben eine eigene `HANA Server`-Verwaltung +- unten im Standortdialog noch einmal eine fast vollstaendige HANA-Verbindung + +Dadurch war unklar: + +- was die zentrale Wahrheit ist +- wann ein zentraler Server geaendert wird +- wann still ein separater Server pro Standort entsteht + +## H205 - Neue Logik + +Quelle: HANDOFF_2026-04-15.md.raw + +### Neue Logik + +Oben gilt jetzt: + +- `HANA Server` ist zentrale HANA-Konfiguration pro Quellsystem +- aktuell relevant fuer: + - `BI1` + - `SAGE` + +Unten im Standort gilt jetzt: + +- Standort pflegt nur noch standortspezifische Daten + - `Schema` + - `TSC` + - `Land` + - `SourceSystem` + - optionale Username-/Password-Overrides +- die technische HANA-Verbindung kommt aus der zentralen Konfiguration des Quellsystems + +## H206 - Technische Umsetzung + +Quelle: HANDOFF_2026-04-15.md.raw + +### Technische Umsetzung + +- `HanaServer` hat jetzt zusaetzlich `SourceSystem` +- `DatabaseInitializationService` stellt zentrale Eintraege fuer `BI1` und `SAGE` sicher +- bestehende verknuepfte HANA-Server werden dabei moeglichst auf `BI1` / `SAGE` gemappt +- `SiteExportService` baut HANA-Verbindungen jetzt aus der zentralen HANA-Konfiguration des Quellsystems +- `Settings.razor` testet BI1/SAGE nicht mehr ueber einen Beispiel-Standort, sondern ueber die zentrale HANA-Konfiguration +- `Standorte.razor` speichert im Standort fuer HANA-basierte Systeme keine eigene Vollverbindung mehr + +## H207 - Wichtige Konsequenz + +Quelle: HANDOFF_2026-04-15.md.raw + +### Wichtige Konsequenz + +Fachlich gilt jetzt: + +- oben = Standardkonfiguration pro Quellsystem +- unten = Standort + optionale Credential-Overrides + +Das entspricht der gewuenschten Logik: + +- gleiche BI1-/SAGE-Standorte koennen zentrale Verbindungswerte teilen +- Ausnahmen koennen weiter ueber Username-/Password-Overrides reagieren + +## H208 - UI-Nachtrag + +Quelle: HANDOFF_2026-04-15.md.raw + +### UI-Nachtrag + +Die frueher doppelte und dadurch verwirrende UI wurde danach auch sichtbar bereinigt. + +Aktueller UI-Stand: + +- oben heisst der Bereich jetzt klar `Zentrale HANA-Konfiguration` +- im Standortdialog gibt es fuer HANA keine zweite technische Eingabestrecke mehr +- dort wird nur noch die aktive Zentralverbindung angezeigt +- Host, Port, SSL und technische Parameter werden explizit nach oben verwiesen +- der zentrale Verbindungstest in `Settings.razor` meldet jetzt sauber die zentrale HANA-Verbindung + +## H209 - Nachtrag Quellsystem-Verwaltung 2026-04-17 + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag Quellsystem-Verwaltung 2026-04-17 + +Die bisher noch hart codierten Quellsystem-Listen wurden entfernt und durch echte Stammdaten ersetzt. + +## H210 - Neuer Stand + +Quelle: HANDOFF_2026-04-15.md.raw + +### Neuer Stand + +- neues Modell `SourceSystemDefinition` +- Quellsysteme werden jetzt zentral in der DB gehalten statt in Razor-Arrays +- pro Quellsystem werden gepflegt: + - `Code` + - `DisplayName` + - `ConnectionKind` + - `IsActive` + - `CentralUsername` + - `CentralPassword` + +## H211 - Neue GUI-Logik + +Quelle: HANDOFF_2026-04-15.md.raw + +### Neue GUI-Logik + +- `Settings.razor` enthaelt jetzt eine pflegbare Quellsystem-Tabelle +- dort koennen Quellsysteme per GUI angelegt, bearbeitet und gespeichert werden +- Anschlussart ist nicht mehr implizit im Code, sondern pro Quellsystem konfigurierbar +- zentrale Zugangsdaten haengen jetzt am Quellsystem selbst + +## H212 - Anschlussarten + +Quelle: HANDOFF_2026-04-15.md.raw + +### Anschlussarten + +Aktuell technisch vorgesehen: + +- `HANA` +- `SAP_GATEWAY` +- `MANUAL_EXCEL` + +Damit gilt: + +- HANA-Konfiguration oben in `Standorte.razor` nur noch fuer Quellsysteme mit Anschlussart `HANA` +- Standort-Dropdown zieht seine Quellsysteme jetzt aus `SourceSystemDefinitions` +- Transformationsregeln ziehen ihre Quellsystem-Auswahl ebenfalls aus `SourceSystemDefinitions` + +## H213 - Technische Umsetzung + +Quelle: HANDOFF_2026-04-15.md.raw + +### Technische Umsetzung + +- `AppDbContext` hat jetzt `DbSet` +- `DatabaseInitializationService` erzeugt und seedet `SourceSystemDefinitions` +- `SiteExportService` loest zentrale Credentials jetzt ueber `SourceSystemDefinition` +- `ConfigTransferService` exportiert/importiert jetzt auch `SourceSystemDefinitions` + +## H214 - Verifikation + +Quelle: HANDOFF_2026-04-15.md.raw + +### Verifikation + +Nach dieser Umstellung geprueft: + +```text +dotnet build .\TrafagSalesExporter.csproj -v minimal +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal +``` + +Ergebnis: + +- Build erfolgreich +- Tests erfolgreich +- `31/31` Tests gruen + +## H215 - Bereinigung der Legacy-Credentials + +Quelle: HANDOFF_2026-04-15.md.raw + +### Bereinigung der Legacy-Credentials + +Danach wurden auch die alten zentralen Credential-Felder technisch bereinigt. + +Aktueller Stand: + +- `ExportSettings` enthaelt keine alten Felder mehr fuer `SapUsername`, `Bi1Username`, `SageUsername` usw. +- der Config-Export schreibt zentrale Zugangsdaten nur noch ueber `SourceSystemDefinitions` +- `ConfigTransferService` hat keinen aktiven Legacy-Credential-Pfad mehr +- die fruehere Temp-Datei `standorte_numbered.tmp` wurde entfernt + +Wichtig: + +- bestehende DB-Spalten koennen physisch noch vorhanden sein, sind aber kein aktiver Codepfad mehr +- fuehrende Wahrheit fuer zentrale Zugangsdaten ist jetzt ausschliesslich `SourceSystemDefinition` + +## H216 - Schema-Bereinigung + +Quelle: HANDOFF_2026-04-15.md.raw + +### Schema-Bereinigung + +Danach wurde auch die SQLite-Schemabereinigung nachgezogen. + +Aktueller Stand: + +- `DatabaseInitializationService` erkennt alte Credential-Spalten in `ExportSettings` +- wenn diese Legacy-Spalten noch existieren, wird `ExportSettings` beim Start auf das neue Schema rekonstruiert +- erhalten bleiben nur die noch gueltigen Felder: + - `DateFilter` + - `TimerHour` + - `TimerMinute` + - `TimerEnabled` + - `DebugLoggingEnabled` + - `LocalSiteExportFolder` + - `LocalConsolidatedExportFolder` + +Damit gilt jetzt: + +- alte zentrale SAP/BI1/SAGE-Credentials sind nicht nur logisch entfernt +- sie werden bei bestehender DB auch aktiv aus dem `ExportSettings`-Schema entfernt + +## H217 - Letzte Bereinigung HANA-Credentials + +Quelle: HANDOFF_2026-04-15.md.raw + +### Letzte Bereinigung HANA-Credentials + +Danach wurde auch die letzte doppelte Credential-Stelle in der HANA-Verwaltung entfernt. + +Aktueller Stand: + +- zentrale HANA-Konfiguration speichert nur noch technische Verbindungsdaten + - `Host` + - `Port` + - `DatabaseName` + - `UseSsl` + - `ValidateCertificate` + - `AdditionalParams` +- Username/Password werden nicht mehr in der zentralen HANA-UI gepflegt +- HANA-Verbindungstests in `Standorte.razor` verwenden jetzt die zentralen Credentials aus `SourceSystemDefinition` +- `SiteExportService` faellt bei HANA nicht mehr auf in `HanaServer` gespeicherte Credentials zurueck +- `ConfigTransferService` exportiert/importiert fuer `HanaServer` keine Username-/Password-Werte mehr +- `DatabaseInitializationService` bereinigt bei bestehender DB auch das `HanaServers`-Schema und entfernt die Altspalten `Username` / `Password` + +Die fachliche Reihenfolge ist jetzt eindeutig: + +1. zentrale Credentials aus `SourceSystemDefinition` +2. optionale Override-Credentials am `Site` +3. technische HANA-Verbindung aus der zentralen HANA-Konfiguration + +## H218 - EF-/SQLite-Fix + +Quelle: HANDOFF_2026-04-15.md.raw + +### EF-/SQLite-Fix + +Beim ersten Lauf nach der Schema-Bereinigung trat noch ein Mapping-Fehler auf: + +- `SQLite Error 1: 'no such column: h.Password'` + +Ursache: + +- `HanaServers`-Schema war bereits ohne `Username` / `Password` +- das EF-Modell `HanaServer` hat diese Properties aber noch als normale Spalten behandelt + +Fix: + +- `HanaServer.Username` und `HanaServer.Password` sind jetzt `[NotMapped]` +- damit bleiben sie fuer Laufzeit-Verbindungsaufbau und Tests nutzbar +- EF erwartet sie aber nicht mehr als Datenbankspalten + +## H219 - Nachtrag Zentrale SAP-Steuerung 2026-04-17 + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag Zentrale SAP-Steuerung 2026-04-17 + +Der verbleibende Architekturbruch bei SAP wurde ebenfalls bereinigt. + +## H220 - Neuer Stand + +Quelle: HANDOFF_2026-04-15.md.raw + +### Neuer Stand + +- `SourceSystemDefinition` enthaelt jetzt auch `CentralServiceUrl` +- zentrale SAP-Service-URL wird damit am Quellsystem gepflegt, nicht mehr primaer am Standort +- `Standorte.razor` behandelt `SapServiceUrl` jetzt als Override +- wenn kein Override gesetzt ist, zieht SAP die URL zentral aus dem Quellsystem + +## H221 - UI + +Quelle: HANDOFF_2026-04-15.md.raw + +### UI + +- `Settings.razor` hat fuer Quellsysteme jetzt eine Dialogbearbeitung statt nur Inline-Tabellenfelder +- dadurch ist das Quellsystem sauber editierbar +- fuer `SAP_GATEWAY` wird dort die zentrale SAP-Service-URL gepflegt +- `Standorte.razor` zeigt bei SAP jetzt: + - zentrale SAP Service URL + - optionales `SAP Service URL Override` + +## H222 - Laufzeitlogik + +Quelle: HANDOFF_2026-04-15.md.raw + +### Laufzeitlogik + +- `SiteExportService` verwendet bei SAP die effektive URL aus + - Standort-Override + - sonst `SourceSystemDefinition.CentralServiceUrl` +- SAP-Verbindungstest in `Settings.razor` testet die zentrale URL direkt aus dem Quellsystem +- Dashboard zeigt fuer SAP jetzt ebenfalls die effektive zentrale bzw. ueberschriebene URL + +## H223 - Verifikation + +Quelle: HANDOFF_2026-04-15.md.raw + +### Verifikation + +Nach der Umstellung geprueft: + +```text +dotnet build .\TrafagSalesExporter.csproj -v minimal +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal +``` + +Ergebnis: + +- Build erfolgreich +- Tests erfolgreich +- `31/31` Tests gruen + +## H224 - Nachtrag 2026-04-16 + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-04-16 + +Seit dem letzten Handoff wurden weitere Funktionen umgesetzt, die unten im alten Stand noch nicht voll enthalten sind. + +## H225 - Zielbild + +Quelle: HANDOFF_2026-04-15.md.raw + +## Zielbild + +Die App wurde von einem reinen BI1/HANA-Exporter zu einer kombinierten Plattform erweitert: + +- `BI1` und `SAGE` bleiben auf direktem HANA-Zugriff +- `SAP` laeuft separat ueber SAP Gateway / OData +- SAP-Quellen koennen gelesen, gejoint und auf das zentrale `SalesRecord`-Schema gemappt werden +- Standort-Exporte werden lokal als Excel geschrieben +- zusaetzlich werden Datensaetze in eine zentrale SQLite-Tabelle geschrieben +- ein konsolidierter Export liest aus dieser zentralen Tabelle + +## H226 - Wichtigste umgesetzte Funktionen + +Quelle: HANDOFF_2026-04-15.md.raw + +## Wichtigste umgesetzte Funktionen + +## H227 - 1. Zentrale Credentials pro Quellsystem + +Quelle: HANDOFF_2026-04-15.md.raw + +### 1. Zentrale Credentials pro Quellsystem + +Es gibt zentrale Zugangsdaten in `ExportSettings` fuer: + +- `SAP` +- `BI1` +- `SAGE` + +Zusaetzlich gibt es pro Standort optionale Overrides: + +- `UsernameOverride` +- `PasswordOverride` + +Aufloesungsreihenfolge: + +1. Standort-Override +2. zentrale Credentials des Quellsystems +3. bei HANA zusaetzlich Fallback auf alten `HanaServer.Username/Password` + +## H228 - 2. SAP von BI1/HANA getrennt + +Quelle: HANDOFF_2026-04-15.md.raw + +### 2. SAP von BI1/HANA getrennt + +`SAP` nutzt nicht mehr den HANA-Pfad, sondern eine eigene Gateway/OData-Strecke. + +Pro SAP-Standort gibt es: + +- `SapServiceUrl` +- `SapEntitySet` +- `SapEntitySetsCache` +- `SapEntitySetsRefreshedAtUtc` + +Refresh der SAP-Quellen erfolgt nur auf Knopfdruck. + +Beispiel Service URL: + +```text +http://travt762.sap.trafag.com:8000/sap/opu/odata/sap/ZPOWERBI_EINKAUF_SRV/ +``` + +Wichtig: + +- Service URL immer nur bis zum Service +- Entity Set separat auswaehlen + +## H229 - 3. SAP-Quellen, Joins und Feldmappings + +Quelle: HANDOFF_2026-04-15.md.raw + +### 3. SAP-Quellen, Joins und Feldmappings + +Fuer SAP gibt es mehrere neue Modelle: + +- `SapSourceDefinition` +- `SapJoinDefinition` +- `SapFieldMapping` + +Unterstuetzt wird: + +- mehrere SAP-Quellen pro Standort +- Alias pro Quelle +- Primaerquelle +- Join-Definitionen +- Mapping von `Alias.Feldname` auf zentrales Schema + +UI-Erweiterungen: + +- `Quellen refreshen` +- `Felder aus Quellen laden` +- Join-Key-Auswahl aus Metadaten +- `Auto-Match` fuer gleiche Feldnamen zwischen Primaerquelle und anderen Quellen + +## H230 - 4. Zentrale Datenspeicherung + +Quelle: HANDOFF_2026-04-15.md.raw + +### 4. Zentrale Datenspeicherung + +Neue Tabelle: + +- `CentralSalesRecords` + +Verwendung: + +- pro Standort werden alte zentrale Saetze dieses Standorts ersetzt +- konsolidierte Excel liest aus `CentralSalesRecords` + +Wichtig: + +- zentrale Excel wird nicht appendet +- sie wird aus dem aktuellen Zustand der zentralen Tabelle neu erstellt + +## H231 - 5. Exportpfade + +Quelle: HANDOFF_2026-04-15.md.raw + +### 5. Exportpfade + +Neue Konfigurationsmoeglichkeiten: + +Zentral in `Settings`: + +- `LocalSiteExportFolder` +- `LocalConsolidatedExportFolder` + +Pro Standort: + +- `LocalExportFolderOverride` + +Fallback wenn leer: + +```text +./output +``` + +relativ zum App-Verzeichnis. + +## H232 - 6. SharePoint + +Quelle: HANDOFF_2026-04-15.md.raw + +### 6. SharePoint + +SharePoint-Upload ist optional. + +Wenn keine vollstaendige SharePoint-Konfiguration vorhanden ist: + +- Excel wird trotzdem lokal erzeugt +- kein Upload nach SharePoint + +Benoetigte SharePoint-Werte: + +- `Tenant ID` +- `Client ID` +- `Client Secret` + +Das sind Entra App Registration Werte, nicht normale Benutzer-Credentials. + +## H233 - 7. Config Import/Export + +Quelle: HANDOFF_2026-04-15.md.raw + +### 7. Config Import/Export + +Es gibt JSON-Import/Export der Konfiguration mit Checkbox: + +- mit Secrets +- ohne Secrets + +Enthalten sind u. a.: + +- SharePoint Config +- ExportSettings +- HanaServers +- Sites +- Transformation Rules +- SAP-Quellen +- SAP-Joins +- SAP-Mappings + +## H234 - 8. Logging und Live-Status + +Quelle: HANDOFF_2026-04-15.md.raw + +### 8. Logging und Live-Status + +Neue technische Logs ueber `AppEventLogs`. + +Sichtbar: + +- auf `/logs` +- im Dashboard als `Live-Status` + +Geloggt werden u. a.: + +- HANA-Query Start +- SAP Refresh +- SAP Reads +- Transformationen +- Excel-Erstellung +- zentrale Tabellenspeicherung +- Export erfolgreich / fehlgeschlagen + +## H235 - 9. Excel oeffnen + +Quelle: HANDOFF_2026-04-15.md.raw + +### 9. Excel oeffnen + +Im Dashboard gibt es neben `Export` den Button: + +- `Excel oeffnen` + +Dieser nutzt `ExportLogs.FilePath`. + +Voraussetzungen: + +- letzter Export erfolgreich +- `FilePath` gespeichert +- Datei existiert lokal + +## H236 - 10. Management Cockpit + +Quelle: HANDOFF_2026-04-15.md.raw + +### 10. Management Cockpit + +Es gibt einen neuen Menuepunkt: + +- `Management Cockpit` + +Funktion: + +- Auswahl vorhandener Excel-Dateien +- Analyse einer exportierten Standort-Datei +- Kennzahlen fuer Geschaeftsinhaber / Management + +Aktuell enthalten: + +- Umsatz +- geschaetzte Kosten +- geschaetzte Marge +- Rechnungsanzahl +- Kundenanzahl +- Top Kunden +- Top Produktgruppen +- Top Sales Owner +- Datenqualitaetshinweise +- automatische Management-Aussagen + +## H237 - 11. Manueller Excel-Import pro Standort + +Quelle: HANDOFF_2026-04-15.md.raw + +### 11. Manueller Excel-Import pro Standort + +Es gibt jetzt einen vierten `SourceSystem`-Typ: + +- `MANUAL_EXCEL` + +Gedanke: + +- Standort ohne Netz-/Systemanbindung liefert nur Excel +- Datei wird im Standort hochgeladen +- Export liest diese Datei statt SAP/HANA +- Daten werden in `CentralSalesRecords` fuer diesen Standort ersetzt +- der zentrale Export liest weiter nur aus `CentralSalesRecords` + +Neue Site-Felder: + +- `ManualImportFilePath` +- `ManualImportLastUploadedAtUtc` + +Wichtig: + +- das ist kein Excel-zu-Excel-Merge +- die App importiert ins zentrale Schema und erzeugt danach die zentrale Datei neu + +## H238 - 12. Dashboard erweitert + +Quelle: HANDOFF_2026-04-15.md.raw + +### 12. Dashboard erweitert + +Im Dashboard gibt es jetzt zusaetzlich: + +- separaten Bereich `Zentrale Datei` +- `Excel oeffnen` fuer die neueste zentrale Datei `Sales_All_*.xlsx` +- Button `Alle exportieren` +- Button `Zentrale Datei neu erzeugen` + +Bedeutung: + +- `Alle exportieren` liest alle Quellen neu und erzeugt danach die zentrale Datei +- `Zentrale Datei neu erzeugen` schreibt nur aus `CentralSalesRecords` eine neue zentrale Excel + +## H239 - 13. Management Cockpit Roh-Auswertung aus Zentraldaten + +Quelle: HANDOFF_2026-04-15.md.raw + +### 13. Management Cockpit Roh-Auswertung aus Zentraldaten + +Zusaetzlich zur dateibasierten Cockpit-Analyse gibt es jetzt eine Roh-Auswertung direkt aus `CentralSalesRecords`. + +Aktuell umgesetzt: + +- Auswahl Jahr +- optional Auswahl Monat +- Jahresumsatz +- Monatsumsatz +- Tagesumsatz im gewaehlten Monat +- Umsatz nach Quelle +- Umsatz nach Land +- Periodenabdeckung / Zeilen / Rechnungen / Standorte / Laender / Waehrungen + +Bewusst noch nicht enthalten: + +- kein Intercompany-Filter +- keine CHF-Umrechnung +- kein Budgetvergleich +- keine Spartenlogik +- keine Gruppenlogik +- keine Margenlogik + +## H240 - 14. Transformationssystem erweitert + +Quelle: HANDOFF_2026-04-15.md.raw + +### 14. Transformationssystem erweitert + +Das Transformationssystem kann jetzt zwei Ebenen: + +- `Value` fuer einfache feldweise Regeln aus der GUI +- `Record` fuer komplexere C#-Strategien per Strategy Pattern + +Umgesetzt: + +- neues Feld `RuleScope` auf `FieldTransformationRule` +- dynamischer Strategiekatalog +- GUI liest verfuegbare Typen aus dem Katalog +- erste `Record`-Strategie: `FirstNonEmpty` + +Beispiel: + +- `TargetField = CustomerName` +- `TransformationType = FirstNonEmpty` +- `Argument = CustomerName|SupplierName|Name` + +## H241 - 15. Schema-Lookup fuer HANA-Standorte + +Quelle: HANDOFF_2026-04-15.md.raw + +### 15. Schema-Lookup fuer HANA-Standorte + +Im Standortdialog fuer HANA-basierte Standorte gibt es jetzt: + +- Button `Schemas laden` +- Lookup mit gueltigen Schemas aus HANA + +Die Liste wird nicht blind aus allen Schemas gelesen, sondern auf typische B1-Schemas eingeschraenkt, in denen z. B. Tabellen wie + +- `OINV` +- `INV1` +- `ORIN` +- `RIN1` +- `OCRD` +- `OITM` + +vorhanden sind. + +Wichtig: + +- manuelle Eingabe bleibt moeglich +- fuer `BI1` und `SAGE` werden beim Lookup die effektiven Credentials inkl. zentraler Zugangsdaten / Overrides verwendet +- das reduziert Fehler wie `invalid schema name` + +## H242 - 16. Testabdeckung ausgebaut + +Quelle: HANDOFF_2026-04-15.md.raw + +### 16. Testabdeckung ausgebaut + +Es gibt jetzt ein separates Testprojekt: + +- `TrafagSalesExporter.Tests` + +Automatisiert getestet werden aktuell: + +- Transformationsstrategien +- `RecordTransformationService` +- `TransformationCatalog` +- `ManualExcelImportService` +- `ManagementCockpitService` +- `ConfigTransferService` + +Wichtiger bereits gefundener Bug: + +- deutsches Dezimalformat wie `1,50` wurde im manuellen Excel-Import falsch interpretiert +- Parsing wurde korrigiert + +## H243 - Wichtige Dateien + +Quelle: HANDOFF_2026-04-15.md.raw + +## Wichtige Dateien + +## H244 - Modelle + +Quelle: HANDOFF_2026-04-15.md.raw + +### Modelle + +- `Models/Site.cs` +- `Models/ExportSettings.cs` +- `Models/ExportLog.cs` +- `Models/CentralSalesRecord.cs` +- `Models/SapSourceDefinition.cs` +- `Models/SapJoinDefinition.cs` +- `Models/SapFieldMapping.cs` +- `Models/ManagementCockpitModels.cs` +- `Models/ConfigTransferPackage.cs` +- `Models/FieldTransformationRule.cs` + +## H245 - Services + +Quelle: HANDOFF_2026-04-15.md.raw + +### Services + +- `Services/SiteExportService.cs` +- `Services/ConsolidatedExportService.cs` +- `Services/CentralSalesRecordService.cs` +- `Services/SapGatewayService.cs` +- `Services/SapCompositionService.cs` +- `Services/ConfigTransferService.cs` +- `Services/AppEventLogService.cs` +- `Services/ManagementCockpitService.cs` +- `Services/DatabaseInitializationService.cs` +- `Services/ExportOrchestrationService.cs` +- `Services/ManualExcelImportService.cs` +- `Services/TransformationCatalog.cs` +- `Services/RecordTransformationService.cs` +- `Services/TransformationStrategies.cs` + +## H246 - UI + +Quelle: HANDOFF_2026-04-15.md.raw + +### UI + +- `Components/Pages/Standorte.razor` +- `Components/Pages/Settings.razor` +- `Components/Pages/Dashboard.razor` +- `Components/Pages/Logs.razor` +- `Components/Pages/ManagementCockpit.razor` +- `Components/Pages/Transformations.razor` +- `Components/Layout/NavMenu.razor` + +## H247 - Tests + +Quelle: HANDOFF_2026-04-15.md.raw + +### Tests + +- `TrafagSalesExporter.Tests/TransformationStrategiesTests.cs` +- `TrafagSalesExporter.Tests/RecordTransformationServiceTests.cs` +- `TrafagSalesExporter.Tests/TransformationCatalogTests.cs` +- `TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs` +- `TrafagSalesExporter.Tests/ManagementCockpitServiceTests.cs` +- `TrafagSalesExporter.Tests/ConfigTransferServiceTests.cs` + +## H248 - Datenbank / Migrationen + +Quelle: HANDOFF_2026-04-15.md.raw + +## Datenbank / Migrationen + +Viele Aenderungen laufen ueber `DatabaseInitializationService`. + +Wichtige neue oder erweiterte Tabellen/Felder: + +- `Sites` + - `UsernameOverride` + - `PasswordOverride` + - `SapServiceUrl` + - `SapEntitySet` + - `SapEntitySetsCache` + - `SapEntitySetsRefreshedAtUtc` + - `LocalExportFolderOverride` + - `ManualImportFilePath` + - `ManualImportLastUploadedAtUtc` +- `ExportSettings` + - zentrale SAP/BI1/SAGE Credentials + - `LocalSiteExportFolder` + - `LocalConsolidatedExportFolder` + - `DebugLoggingEnabled` +- `FieldTransformationRules` + - `RuleScope` +- `ExportLogs` + - `FilePath` +- neue Tabellen: + - `AppEventLogs` + - `CentralSalesRecords` + - SAP-Konfigtabellen + +## H249 - Letztes Hauptproblem und Loesung + +Quelle: HANDOFF_2026-04-15.md.raw + +## Letztes Hauptproblem und Loesung + +## H250 - Export hing nach zentraler Speicherung + +Quelle: HANDOFF_2026-04-15.md.raw + +### Export hing nach zentraler Speicherung + +Der Export blieb zuletzt nach + +- `Zentrale Tabelle: 20106 Datensaetze gespeichert.` + +haengen. + +Die eigentliche Ursache war am Ende nicht mehr der Batch-Insert selbst, sondern ein kaputter SQLite-Schemazustand: + +- mindestens eine Tabelle referenzierte per FK noch `main.Sites_old` +- dadurch scheiterte `SaveChangesAsync()` spaeter beim Schreiben in `AppEventLogs` oder `ExportLogs` +- die alte Tabelle `Sites_old` existierte nicht mehr + +Beobachteter Fehler: + +- `SQLite Error 1: 'no such table: main.Sites_old'` + +## H251 - Umgesetzte Korrekturen + +Quelle: HANDOFF_2026-04-15.md.raw + +## Umgesetzte Korrekturen + +- `Components/Pages/Dashboard.razor` + - Live-Status pollt waehrend laufendem Export nicht mehr permanent `AppEventLogs` + - stattdessen Anzeige ueber den In-Memory-Status aus `ExportOrchestrationService` +- `Program.cs` + - SQLite `Default Timeout` von `10` auf `60` erhoeht +- `Services/CentralSalesRecordService.cs` + - nach abgeschlossenem Batch-Insert wird explizit `Zentrale Tabelle aktualisiert` gesetzt +- `Services/DatabaseInitializationService.cs` + - automatische Reparaturlogik fuer Tabellen, deren `CREATE TABLE`-SQL noch `Sites_old` referenziert + - betroffene Tabellen werden beim Start neu aufgebaut und Daten rueberkopiert + +Danach wurde der Export erfolgreich getestet und geht jetzt wieder durch. + +## H252 - Was bei einer naechsten Stoerung zuerst zu pruefen ist + +Quelle: HANDOFF_2026-04-15.md.raw + +## Was bei einer naechsten Stoerung zuerst zu pruefen ist + +1. Tritt beim App-Start die Schema-Reparatur sauber durch? +2. Gibt es noch weitere Tabellen mit FK-Referenz auf `Sites_old`? +3. Erst danach wieder Insert-/Commit-Batches der zentralen Speicherung untersuchen + +## H253 - Build-Status + +Quelle: HANDOFF_2026-04-15.md.raw + +## Build-Status + +Letzter Build: + +```text +dotnet build TrafagSalesExporter.sln +``` + +Ergebnis: + +- erfolgreich +- bekannte Warnungen bleiben: + - SAP HANA Architekturwarnung `MSB3270` + - MudBlazor Analyzer `Dense` + +## H254 - Nachtrag 2026-04-17 UI-Klarstellung HANA vs. SAP + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-04-17 UI-Klarstellung HANA vs. SAP + +- `Components/Pages/Standorte.razor` + - Bereich oben heisst jetzt bewusst `Zentrale HANA-Technik` + - Hinweistext stellt klar: dort erscheinen nur Quellsysteme mit Anschlussart `HANA` + - `SAP` wird zentral unter `Settings -> Quellsysteme` gepflegt und gehoert nicht in diese Box + - der irrefuehrende Button `Server hinzufuegen` wurde entfernt + - neue HANA-Zeilen entstehen aus den Quellsystem-Stammdaten, nicht mehr aus einer zweiten UI-Erfassung + - Dialogtitel fuer HANA wurde auf reine Bearbeitung der zentralen Technik reduziert + +Fachliche Regel jetzt: + +- `Quellsysteme` verwalten die zentralen Systeme und deren Anschlussart +- `Standorte` zeigen fuer HANA nur noch die technische Zentralverbindung +- `SAP` wird nicht mehr implizit in der HANA-Box erwartet + +## H255 - Nachtrag 2026-04-17 Pruefung Config-Import/Export + +Quelle: HANDOFF_2026-04-15.md.raw + +## Nachtrag 2026-04-17 Pruefung Config-Import/Export + +Der aktuelle Config-Transfer wurde nach den Umbauten nochmals geprueft. + +Status: + +- Das aktuelle Import-/Exportformat passt zum neuen Modell. +- `SourceSystemDefinitions` werden mit `ConnectionKind`, `CentralServiceUrl`, `CentralUsername`, `CentralPassword` importiert/exportiert. +- `HanaServers` enthalten nur noch technische HANA-Verbindungsdaten und keine Credentials mehr. +- Standort-Overrides fuer Username/Password sowie SAP Service URL gehen weiterhin mit. +- Die vorhandenen `ConfigTransferServiceTests` laufen grün. + +Weiterhin offene Architekturpunkte: + +- `ConfigTransferService.ImportJsonAsync` ist weiterhin destruktiv und nicht atomar. + - Erst werden bestehende Daten geloescht, danach wird in mehreren Schritten neu aufgebaut. + - Wenn der Import in der Mitte scheitert, bleibt ein teilweiser Zustand zurueck. +- Altformat-Risiko bei `ConnectionKind`: + - Wenn ein aelteres JSON bereits `SourceSystemDefinitions` enthaelt, aber noch ohne `ConnectionKind`, faellt der DTO-Default auf `HANA`. + - Dadurch koennte ein altes `SAP` beim Import falsch als `HANA` landen. + +Fazit: + +- Fuer Exporte aus dem aktuellen Stand ist der Config-Transfer konsistent. +- Fuer aeltere JSON-Staende braucht der Import noch eine explizite Migrations-/Fallback-Logik. + +## H256 - TrafagSalesExporter LLM System Guide + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +# TrafagSalesExporter LLM System Guide + +Stand: 2026-05-05 + +RAG-Hinweis: Fuer minimale Kontextladung zuerst `docs/RAG_ROUTER.md` lesen. Danach standardmaessig nur die passende Kurzdatei unter `docs/rag/` laden; Original-MDs nur bei Detail-/Auditbedarf. + +## H257 - Aktueller Projektstand 2026-05-05 + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Aktueller Projektstand 2026-05-05 + +Fuer den aktuellen Finance-/Laenderabgleich zuerst diese Dateien lesen: + +- [HANDOFF_2026-04-15.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/HANDOFF_2026-04-15.md) +- [NEXT_STEPS_2026-04-15.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/NEXT_STEPS_2026-04-15.md) +- [lastchange.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/lastchange.md) +- [SAGE_SPAIN_EXPORT_2026-05-05.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/SAGE_SPAIN_EXPORT_2026-05-05.md) + +Lokaler FinanceProbe: + +```text +http://localhost:55417/finance +``` + +## H258 - Aktueller Zusatzstand 2026-05-07 SAP OData / ZSCHWEIZ + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Aktueller Zusatzstand 2026-05-07 SAP OData / ZSCHWEIZ + +Schweiz/Oesterreich werden ueber eine neue SAP-Tabelle `ZSCHWEIZ` bereitgestellt. + +Wichtige Punkte: + +- ABAP-Report: `report.abap` +- SAP-Tabelle: `ZSCHWEIZ` +- OData EntitySet: `ZSCHWEIZSet` +- App-Standort: `ZSCHWEIZ` / `Schweiz/Oesterreich` +- Geplanter App-Pfad: `SAP` = `SAP OData`, nicht direkter HANA-Spezialcode + +Quellsystem-Codes: + +- `SAP`: SAP OData/Gateway, DisplayName `SAP OData` +- `SAP_HANA`: direkte HANA-Tabellen/Views, DisplayName `SAP HANA Tables/Views` +- `BI1`: HANA +- `SAGE`: HANA +- `MANUAL_EXCEL`: Excel/CSV + +Mapper: + +- SAP OData nutzt `SapSourceDefinition`, `SapJoinDefinition`, `SapFieldMapping`. +- Direkte HANA-Tabellen/Views koennen dieselben Mapping-Tabellen ebenfalls nutzen. +- Gemeinsame Mapping-Engine ist `MappedSalesRecordComposer`. +- `SapCompositionService` und `HanaQueryService.GetMappedSalesRecordsAsync` unterscheiden sich nur noch in der Quellenbeschaffung; Join und `SalesRecord`-Mapping sind zentral. +- Bei HANA mit gepflegten Quellen/Mappings nutzt `HanaDataSourceAdapter` den generischen Mapping-Pfad. +- Ohne HANA-Mapping bleibt der alte B1-HANA-Standardpfad fuer `OINV/INV1/ORIN/RIN1` aktiv. + +Finance-Konfiguration: + +- `FinanceReferences` enthaelt Soll-/check.xlsx-Referenzen. +- `FinanceIntercompanyRules` enthaelt 2nd-party/IC-Regeln. +- Budgetkurse werden als `CurrencyExchangeRates` mit `Notes = Budget 2025` gepflegt. +- Config-Export/-Import umfasst Finance-Referenzen und IC-Regeln. + +ZSCHWEIZ-Seed: + +- Quelle Alias `Z` +- EntitySet `ZSCHWEIZSet` +- Mapping auf `SalesRecord` ist vorbefuellt und grafisch editierbar. +- Beim App-Start wird die ZSCHWEIZ-Quelle samt Feldmapping per Upsert angelegt oder repariert. +- Wenn Gateway `$metadata` liefert, koennen Felder in der UI per `Felder aus Quellen laden` gelesen werden. + +ABAP-Fachlogik: + +- `BUKRS 1100` = Schweiz, `TSC TRCH`, `LAND1 CH` +- `BUKRS 1200` = Oesterreich, `TSC TRAT`, `LAND1 AT` +- `CUSTOMER_LAND` = Kundenland aus `KNA1-LAND1` +- Netto-/Steuerwerte werden in Belegwaehrung und Hauswaehrung geschrieben. + +Aktuelle FinanceProbe-Funktionen: + +- `Meeting Ampel 2025` fuer alle Laender aus `check.xlsx` +- `Detail alle Laender` +- `Spain CSV direct check` +- `Germany Excel sample check` + +Spanien: + +- Datei: `sagespain/v2/Spain_Sales_2025.csv` +- Ist: `3'082'320.18` EUR +- Soll: `3'102'333.61` +- Differenz: `-20'013.43` +- Status: Gelb / Pruefen +- Technisch lesbar, fachliche Differenz noch offen + +Deutschland: + +- Datei: `DE_Beispiel_Export_Daten.xlsx` +- Sample-Summe `NettoPreisGesamtX`: `8'290.70` EUR +- Nur Beispielfile, keine finale Jahreszahl +- Mapping technisch verstanden, finaler DE-Jahresfile fehlt + +Letzte Verifikation: + +- `dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal --no-restore` +- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal --no-restore` +- Ergebnis: Build OK, Tests `50/50`, FinanceProbe `HTTP 200` + +Diese Datei ist fuer andere LLMs gedacht, die das Projekt schnell verstehen und daraus Architekturtexte, Visualisierungen, Ablaufdiagramme oder UI-/Datenflussgrafiken erzeugen sollen. + +## H259 - Zweck des Systems + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Zweck des Systems + +`TrafagSalesExporter` ist eine Blazor Server App auf `.NET 8`, die Verkaufsdaten aus mehreren Quellsystemen in ein gemeinsames Zielschema ueberfuehrt. + +Quellsysteme: + +- `HANA`-basierte Systeme wie `BI1` und `SAGE` +- `SAP_GATEWAY` ueber OData +- `MANUAL_EXCEL` aus hochgeladenen oder referenzierten Excel-Dateien + +Zielbild: + +- jede Quelle wird in `SalesRecord` normalisiert +- Standortdaten koennen lokal als Excel exportiert werden +- alle Datensaetze werden in `CentralSalesRecords` gespeichert +- eine zentrale konsolidierte Datei wird aus dem zentralen Datenbestand erzeugt +- ein `Management Cockpit` analysiert sowohl exportierte Dateien als auch zentrale Rohdaten + +## H260 - Technologie-Stack + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Technologie-Stack + +- UI: Blazor Server + MudBlazor +- Authentifizierung: ASP.NET Core Authentication/Authorization, produktiv Windows Authentication / Active Directory +- Datenbank: SQLite (`trafag_exporter.db`) +- Excel lesen/schreiben: ClosedXML +- SAP HANA Zugriff: `Sap.Data.Hana.Core.v2.1.dll` +- SAP Gateway / OData: eigener Service ueber HTTP +- SharePoint Upload/Download: Microsoft Graph + Azure Identity +- Tests: xUnit + +## H261 - Einstiegspunkte + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Einstiegspunkte + +Wichtige Dateien: + +- [Program.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Program.cs) +- [Data/AppDbContext.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Data/AppDbContext.cs) +- [Components/Layout/NavMenu.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Layout/NavMenu.razor) + +`Program.cs` registriert fast die komplette Architektur ueber DI und fuehrt beim Start `DatabaseInitializationService.InitializeAsync()` aus. + +Zusaetzlich registriert `Program.cs` den Zugriffsschutz: + +- `AddCascadingAuthenticationState` +- Windows Authentication fuer produktive Umgebungen +- Development-Authentication-Handler nur bei `ASPNETCORE_ENVIRONMENT=Development` und `Security:DevelopmentBypass=true` +- globale Fallback-Policy fuer authentifizierte/berechtigte User +- Policy `AdminOnly` fuer administrative Seiten + +## H262 - Hauptseiten + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Hauptseiten + +Navigation: + +- `/` Dashboard +- `/standorte` +- `/transformations` +- `/management-cockpit` +- `/settings` +- `/logs` + +Dateien: + +- [Components/Pages/Dashboard.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/Dashboard.razor) +- [Components/Pages/Standorte.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/Standorte.razor) +- [Components/Pages/Transformations.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/Transformations.razor) +- [Components/Pages/ManagementCockpit.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/ManagementCockpit.razor) +- [Components/Pages/Settings.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/Settings.razor) +- [Components/Pages/Logs.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Pages/Logs.razor) + +Kurzrollen: + +- `Dashboard`: Einzel-Export, Alle exportieren, zentrale Datei neu erzeugen, Live-Status +- `Standorte`: Standortpflege, zentrale HANA-Technik, SAP-Konfiguration pro Standort, manueller Excel-Import +- `Transformations`: feldweise und record-basierte Regeln +- `Management Cockpit`: Dateianalyse und Rohanalyse aus `CentralSalesRecords` +- `Settings`: SharePoint, Exportpfade, Quellsysteme, Wechselkurse, Config Import/Export +- `Logs`: technische Ereignisprotokolle + +Security: + +- alle Routen erfordern Authentifizierung +- `Settings`, `Standorte` und `Transformations` sind `AdminOnly` +- Admin-Navigation wird nur fuer Admins angezeigt +- eingeloggter Benutzer wird im App-Bar angezeigt + +## H263 - Kernmodelle + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Kernmodelle + +Wichtige Entity-Klassen: + +- [Models/Site.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/Site.cs) +- [Models/SourceSystemDefinition.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SourceSystemDefinition.cs) +- [Models/HanaServer.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/HanaServer.cs) +- [Models/SalesRecord.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SalesRecord.cs) +- [Models/CentralSalesRecord.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/CentralSalesRecord.cs) +- [Models/FieldTransformationRule.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/FieldTransformationRule.cs) +- [Models/SapSourceDefinition.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SapSourceDefinition.cs) +- [Models/SapJoinDefinition.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SapJoinDefinition.cs) +- [Models/SapFieldMapping.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SapFieldMapping.cs) +- [Models/SharePointConfig.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/SharePointConfig.cs) +- [Models/ExportSettings.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/ExportSettings.cs) +- [Models/ExportLog.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/ExportLog.cs) +- [Models/AppEventLog.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/AppEventLog.cs) +- [Models/CurrencyExchangeRate.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/CurrencyExchangeRate.cs) + +`SalesRecord` / `CentralSalesRecord` enthalten neben den positionsnahen Feldern auch B1-Belegwaehrungsfelder: + +- `DocumentCurrency` aus `DocCur` +- `DocumentTotalForeignCurrency` aus `DocTotalFC` +- `DocumentTotalLocalCurrency` aus `DocTotal` +- `VatSumForeignCurrency` aus `VatSumFC` +- `VatSumLocalCurrency` aus `VatSum` +- `DocumentRate` aus `DocRate` +- `CompanyCurrency` aus `OADM.MainCurncy` + +Wichtig: diese Dokumentwerte sind Belegkopfwerte und werden in der positionsbasierten Excel pro Position wiederholt. Fuer Belegkopfsummen muessen Auswertungen nach Beleg deduplizieren. + +Wichtige Relationen: + +- `Site -> HanaServer` optional +- `Site -> SapSourceDefinitions` +- `Site -> SapJoinDefinitions` +- `Site -> SapFieldMappings` +- `Site -> CentralSalesRecords` +- `SourceSystemDefinition` ist zentrale Stammdatenquelle fuer Quellsysteme + +## H264 - Datenbanktabellen + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Datenbanktabellen + +`AppDbContext` enthaelt: + +- `HanaServers` +- `SourceSystemDefinitions` +- `Sites` +- `SharePointConfigs` +- `ExportSettings` +- `ExportLogs` +- `AppEventLogs` +- `FieldTransformationRules` +- `CurrencyExchangeRates` +- `SapSourceDefinitions` +- `SapJoinDefinitions` +- `SapFieldMappings` +- `CentralSalesRecords` + +## H265 - Architekturrollen der Services + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Architekturrollen der Services + +## H266 - Export / Orchestrierung + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### Export / Orchestrierung + +- [Services/ExportOrchestrationService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ExportOrchestrationService.cs) +- [Services/SiteExportService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/SiteExportService.cs) +- [Services/ConsolidatedExportService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ConsolidatedExportService.cs) +- [Services/CentralSalesRecordService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/CentralSalesRecordService.cs) +- [Services/ExportLogService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ExportLogService.cs) + +Rollen: + +- `ExportOrchestrationService` steuert UI-nahe Exportlaeufe und Live-Status +- `SiteExportService` entscheidet anhand des Quellsystems, wie ein Standort gelesen wird +- `CentralSalesRecordService` ersetzt zentrale Saetze pro Standort +- `ConsolidatedExportService` erzeugt die zentrale Datei + +## H267 - Datenquellen + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### Datenquellen + +- [Services/HanaQueryService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/HanaQueryService.cs) +- [Services/SapGatewayService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/SapGatewayService.cs) +- [Services/SapCompositionService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/SapCompositionService.cs) +- [Services/ManualExcelImportService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ManualExcelImportService.cs) +- [Services/SharePointUploadService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/SharePointUploadService.cs) + +Rollen: + +- `HanaQueryService`: SQL gegen SAP B1/HANA-nahe Schemata +- `SapGatewayService`: OData-Metadaten und Reads +- `SapCompositionService`: Mehrquellen-/Join-/Mapping-Aufbau fuer SAP +- `ManualExcelImportService`: Import im Exportformat aus `.xlsx` +- `SharePointUploadService`: Upload fuer Exportdateien und Download fuer manuelle Excel-Dateien + +## H268 - Transformation / Mapping + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### Transformation / Mapping + +- [Services/TransformationCatalog.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/TransformationCatalog.cs) +- [Services/TransformationStrategies.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/TransformationStrategies.cs) +- [Services/RecordTransformationService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/RecordTransformationService.cs) +- [Services/CurrencyExchangeRateService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/CurrencyExchangeRateService.cs) +- [Services/ExchangeRateImportService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ExchangeRateImportService.cs) + +Rollen: + +- `Value`-Transformationen fuer einzelne Felder +- `Record`-Transformationen fuer zeilenweite Regeln +- Wechselkursimport und -umrechnung + +## H269 - Reporting / Monitoring / Infrastruktur + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### Reporting / Monitoring / Infrastruktur + +- [Services/ManagementCockpitService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ManagementCockpitService.cs) +- [Services/AppEventLogService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/AppEventLogService.cs) +- [Services/ConfigTransferService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ConfigTransferService.cs) +- [Services/DatabaseInitializationService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/DatabaseInitializationService.cs) +- [Services/TimerBackgroundService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/TimerBackgroundService.cs) + +## H270 - Der wichtigste technische Ablauf + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Der wichtigste technische Ablauf + +## H271 - 1. Standort-Export + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### 1. Standort-Export + +Pfad: + +`Dashboard/Standorte -> ExportOrchestrationService -> SiteExportService` + +`SiteExportService` unterscheidet drei Modi: + +1. `SAP_GATEWAY` + - SAP-Quellen lesen + - SAP-Joins anwenden + - SAP-Feldmappings auf `SalesRecord` + - Transformationen anwenden + - Standort-Excel erzeugen + - `CentralSalesRecords` ersetzen + - optional SharePoint-Upload + +2. `HANA` + - effektive zentrale HANA-Konfiguration laden + - optionale Standort-Credential-Overrides anwenden + - SQL in HANA ausfuehren + - `SalesRecord` erzeugen + - Transformationen anwenden + - Standort-Excel erzeugen + - `CentralSalesRecords` ersetzen + - optional SharePoint-Upload + +3. `MANUAL_EXCEL` + - `ManualImportFilePath` auswerten + - wenn lokal/UNC vorhanden: lokal lesen + - wenn SharePoint-Referenz: via Graph temp herunterladen + - Excel in `SalesRecord` lesen + - Transformationen anwenden + - keine neue Standortdatei erzeugen, bestehende Excel dient als Eingabe + - `CentralSalesRecords` ersetzen + +## H272 - 2. Konsolidierter Export + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### 2. Konsolidierter Export + +Pfad: + +`Dashboard -> ExportOrchestrationService -> ConsolidatedExportService` + +Semantik aktuell: + +- die zentrale Datei basiert fachlich auf `CentralSalesRecords` +- `ExportAllAsync()` sammelt zwar auch `consolidatedRecords`, aber die zentrale Exportsemantik ist historisch noch nicht vollkommen bereinigt + +## H273 - 3. Management Cockpit + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### 3. Management Cockpit + +Zwei Betriebsarten: + +1. Dateibasiert + - vorhandene `.xlsx` waehlen + - Datei mit ClosedXML lesen + - Summenfeld waehlen + - Anzeige-Waehrung waehlen + - Kennzahlen, Top-Listen, Datenqualitaet, Findings erzeugen + +2. Zentraldatenbasiert + - direkt aus `CentralSalesRecords` + - Jahr/Monat Filter + - Summenfeld waehlen + - optionale weitere Summenfelder fuer Zeitreihen waehlen + - Anzeige-Waehrung waehlen + - Rohsicht ohne Intercompany-, Budget- oder Spartelogik + +Aktuelle Summenfelder: + +- `Sales Price/Value` +- `Quantity` +- `Standard cost` +- `Quantity * Standard cost` + +Aktuelle Anzeige-Waehrungen: + +- `EUR` +- `USD` +- `Original` + +Die Waehrungsumrechnung nutzt `CurrencyExchangeRateService`. Bei `Original` bleiben Werte in Quellwaehrungen gruppiert. Nicht-betragliche Summenfelder wie `Quantity` haben keine Waehrung. Fehlende Wechselkurse werden gezaehlt und in Hinweisen bzw. Findings sichtbar; betroffene Werte werden in der Zielwaehrung mit `0` einbezogen. + +## H274 - Quellsystemlogik + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Quellsystemlogik + +## H275 - SourceSystemDefinition + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### SourceSystemDefinition + +`SourceSystemDefinition` ist die fuehrende Wahrheit fuer: + +- `Code` +- `DisplayName` +- `ConnectionKind` +- `IsActive` +- `CentralUsername` +- `CentralPassword` +- `CentralServiceUrl` fuer SAP + +Anschlussarten: + +- `HANA` +- `SAP_GATEWAY` +- `MANUAL_EXCEL` + +## H276 - HANA + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### HANA + +Fachliche Logik: + +- zentrale technische HANA-Konfiguration pro Quellsystem +- keine separaten Vollverbindungen pro Standort +- Standort speichert nur Fachdaten plus optionale Username-/Password-Overrides + +Schema-Lookup: + +- in `Standorte` gibt es jetzt `Schemas laden` +- Lookup fragt `sys.tables` in HANA ab +- eingeschraenkt auf typische B1-Schemas mit Tabellen wie `OINV`, `INV1`, `ORIN`, `RIN1`, `OCRD`, `OITM` + +## H277 - SAP + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### SAP + +Fachliche Logik: + +- zentrale SAP Service URL in `SourceSystemDefinition.CentralServiceUrl` +- Standort kann `SapServiceUrl` als Override pflegen +- pro Standort gibt es SAP-Quellen, Joins und Feldmappings + +## H278 - Manual Excel + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### Manual Excel + +Fachliche Logik: + +- `Site.ManualImportFilePath` kann sein: + - lokaler Windows-Pfad + - UNC-Pfad + - SharePoint-URL + - SharePoint-Pfad unterhalb der konfigurierten Site +- Standortdaten werden aus der Excel eingelesen und in `CentralSalesRecords` uebernommen +- SharePoint dient hier als Eingangsquelle, nicht nur als Exportziel + +## H279 - Transformationen + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Transformationen + +Das System unterscheidet: + +- `Value`-Transformationen +- `Record`-Transformationen + +Beispiele: + +- `Copy` +- `Uppercase` +- `Lowercase` +- `Prefix` +- `Suffix` +- `Replace` +- `Constant` +- `NormalizeCurrencyCode` +- `FirstNonEmpty` +- `ConvertCurrency` + +Technischer Ablauf: + +- Regeln liegen in `FieldTransformationRules` +- `TransformationCatalog` meldet verfuegbare Strategien an die UI +- `RecordTransformationService` wendet record-basierte Strategien an + +## H280 - Wechselkurse + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Wechselkurse + +Vorhanden: + +- `CurrencyExchangeRates` +- `ExchangeRateImportService` fuer ECB-Tageskurse +- `NormalizeCurrencyCode` +- `ConvertCurrency` +- `ManagementCockpitService` kann betragliche Cockpit-Kennzahlen in `EUR` oder `USD` umrechnen + +Wichtig: + +- die Rohsicht im `Management Cockpit` kann jetzt Anzeige-Waehrungen nutzen +- `CHF` ist im Cockpit aktuell nicht als direkte Anzeige-Waehrung in der UI angeboten +- CHF bleibt weiterhin Teil des allgemeinen Transformationssystems +- fachlich ist noch zu klaeren, ob CHF als Standard- oder zusaetzliche Cockpit-Anzeige-Waehrung gebraucht wird + +## H281 - SharePoint-Rolle im Gesamtsystem + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## SharePoint-Rolle im Gesamtsystem + +`SharePointConfig` enthaelt: + +- `SiteUrl` +- `ExportFolder` +- `CentralExportFolder` +- `TenantId` +- `ClientId` +- `ClientSecret` + +Verwendung: + +- Upload von Standort-Exporten +- Upload der zentralen Datei +- Download von manuellen Excel-Dateien fuer `MANUAL_EXCEL` + +Wichtig: + +- die App arbeitet gegen dieselbe SharePoint-Site, die in `Settings` konfiguriert ist +- fuer `MANUAL_EXCEL` muessen Referenzen auf derselben Site aufloesbar sein + +## H282 - Startinitialisierung / Migrationen + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Startinitialisierung / Migrationen + +Kritische Datei: + +- [Services/DatabaseInitializationService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/DatabaseInitializationService.cs) + +Aktuelle Rolle: + +- `EnsureCreated` +- Schema-Ergaenzungen per `ALTER TABLE` +- Tabellen-Rebuilds bei Legacy-Schemas +- FK-Reparaturen +- Stammdaten-Seeding +- empfohlene Transformationsregeln + +Bekannte Architekturrealitaet: + +- das ist funktional hilfreich, aber kein sauberes Migrationssystem +- die Startlogik traegt produktive Schema-Reparaturverantwortung +- das ist einer der wichtigsten technischen Risikobloecke + +Bereits gehaertete Fehlerbilder: + +- kaputte FK-Referenzen auf `Sites_old` +- kaputte FK-Referenzen auf `HanaServers_repair_old` +- Legacy-Credential-Spalten in `ExportSettings` +- Legacy-Credential-Spalten in `HanaServers` +- verschobene Spalten im `Sites_old -> Sites`-Kopierpfad + +## H283 - Authentifizierung / Autorisierung + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Authentifizierung / Autorisierung + +Dateien: + +- [Security/SecurityOptions.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Security/SecurityOptions.cs) +- [Security/SecurityPolicies.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Security/SecurityPolicies.cs) +- [Security/DevelopmentAuthenticationHandler.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Security/DevelopmentAuthenticationHandler.cs) +- [Components/Routes.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Routes.razor) +- [Components/Layout/NavMenu.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Layout/NavMenu.razor) +- [Components/Layout/MainLayout.razor](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Components/Layout/MainLayout.razor) + +Produktives Ziel: + +- Windows Authentication / Active Directory +- keine eigene Benutzerverwaltung +- Zugriff ueber AD-Gruppen +- Adminrechte ueber separate AD-Gruppe + +Konfiguration in `appsettings.json`: + +- `Security:AccessGroups` +- `Security:AdminGroups` +- `Security:DevelopmentBypass` +- `Security:DevelopmentUserIsAdmin` +- `Security:DevelopmentUserName` + +Default-Gruppen: + +- `TRAFAG\\TrafagSalesExporter-Users` +- `TRAFAG\\TrafagSalesExporter-Admins` + +Development: + +- `appsettings.Development.json` aktiviert einen lokalen Development-Auth-Handler +- dieser ist nur fuer lokale Entwicklung gedacht +- produktiv darf `ASPNETCORE_ENVIRONMENT` nicht `Development` sein + +IIS-Betrieb: + +- Windows Authentication aktivieren +- Anonymous Authentication deaktivieren +- AD-Gruppennamen in produktiver Konfiguration setzen + +## H284 - Config Import / Export + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Config Import / Export + +Dateien: + +- [Services/ConfigTransferService.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Services/ConfigTransferService.cs) +- [Models/ConfigTransferPackage.cs](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/Models/ConfigTransferPackage.cs) + +Aktueller Stand: + +- JSON Export/Import fuer Konfiguration +- Secrets optional +- `SourceSystemDefinitions` im aktuellen Modell enthalten +- HANA-Technik ohne HANA-Credentials +- Standort-Overrides bleiben erhalten + +Wichtige Punkte: + +- Import laeuft jetzt transaktional +- alte `ConnectionKind`-lose Formate bekommen Fallbacks +- `CentralSalesRecords` werden nicht mehr blind geloescht +- bestehende zentrale Laufzeitdaten werden fuer weiterhin vorhandene Standorte remappt + +## H285 - Logging + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Logging + +Es gibt zwei Log-Ebenen: + +- `ExportLogs` fuer fachliche Exporthistorie +- `AppEventLogs` fuer technische und UI-nahe Ereignisse + +Die `Logs`-Seite liest vor allem `AppEventLogs`. + +## H286 - Tests + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Tests + +Testprojekt: + +- [TrafagSalesExporter.Tests](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/TrafagSalesExporter.Tests) + +Aktuell vorhandene Schwerpunkte: + +- Transformationen +- Record-Transformationen +- TransformationCatalog +- CurrencyExchangeRateService +- ExchangeRateImportService +- ManualExcelImportService +- ManagementCockpitService +- ConfigTransferService +- DatabaseInitializationService + +`ManagementCockpitServiceTests` decken inzwischen auch ab: + +- zentrale Analyse nach Jahr/Monat +- Tages-, Monats-, Jahres-, Quellen- und Laenderwerte +- waehlbare Summenfelder +- Waehrungsumrechnung in EUR +- Wechselkurs-Caching +- Mengen-Auswertung ohne Waehrungsumrechnung +- Zusatz-Summenfelder in Zeitreihen + +`SecurityPolicyFactoryTests` decken inzwischen ab: + +- App-Zugriff fuer User in `AccessGroups` +- Ablehnung fuer User ausserhalb der Access-Gruppen +- Development-Auth-Zugriff im lokalen Modus +- Admin-Zugriff fuer User in `AdminGroups` +- Ablehnung normaler User fuer `AdminOnly` +- Development-Admin-Claim + +`CentralSalesRecordServiceTests` decken inzwischen ab: + +- Persistenz und Ruecklesen der B1-Belegwaehrungsfelder in `CentralSalesRecords` + +Wichtig: + +- es gibt aktuell keine echten UI-Komponententests mit `bUnit` +- es gibt keine Browser-E2E-Tests mit `Playwright` +- viele Button-Aktionen sind nur indirekt ueber Services und Persistenz getestet + +## H287 - Bekannte offene Architekturfragen + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Bekannte offene Architekturfragen + +Fuer andere LLMs wichtig, damit Visualisierungen nicht zu glatt oder zu idealisiert werden: + +1. `DatabaseInitializationService` ist ein produktiver Reparatur-/Migrationslayer, nicht nur Bootstrap. +2. `Settings.razor` und `Standorte.razor` enthalten weiterhin relativ viel Anwendungslogik. +3. Die Semantik der konsolidierten Datei ist historisch teilweise doppelt angelegt. +4. Das `Management Cockpit` ist noch kein voll generalisierter Reporting-Layer. +5. SharePoint ist sowohl Exportziel als auch bei `MANUAL_EXCEL` mittlerweile moegliche Eingangsquelle. + +## H288 - Empfohlene Diagramme fuer andere LLMs + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Empfohlene Diagramme fuer andere LLMs + +## H289 - 1. Kontextdiagramm + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### 1. Kontextdiagramm + +Zeige: + +- Benutzer +- Blazor App +- SQLite +- SAP HANA +- SAP Gateway +- lokale Dateisystempfade +- SharePoint + +## H290 - 2. Komponenten-/Service-Diagramm + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### 2. Komponenten-/Service-Diagramm + +Gruppiere: + +- UI +- Orchestrierung +- Quelladapter +- Transformation +- Persistenz +- Reporting + +## H291 - 3. Datenflussdiagramm pro Quelltyp + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### 3. Datenflussdiagramm pro Quelltyp + +Je ein separater Flow fuer: + +- HANA +- SAP Gateway +- Manual Excel lokal +- Manual Excel SharePoint + +## H292 - 4. ER-Diagramm + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### 4. ER-Diagramm + +Fokussiere auf: + +- `SourceSystemDefinition` +- `HanaServer` +- `Site` +- `SapSourceDefinition` +- `SapJoinDefinition` +- `SapFieldMapping` +- `CentralSalesRecord` +- `FieldTransformationRule` + +## H293 - 5. Sequenzdiagramm fuer Export + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +### 5. Sequenzdiagramm fuer Export + +Wichtige Stationen: + +- Dashboard +- ExportOrchestrationService +- SiteExportService +- spezifischer Quellservice +- Transformation +- CentralSalesRecordService +- Excel/SharePoint +- ExportLog/AppEventLog + +## H294 - Prompt-Vorlage fuer ein anderes LLM + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Prompt-Vorlage fuer ein anderes LLM + +Wenn ein anderes LLM daraus Visualisierungen erzeugen soll, funktioniert diese Anweisung gut: + +> Lies `LLM_SYSTEM_GUIDE.md` als primaeren Systemkontext. Erzeuge daraus ein Architekturdiagramm, ein Datenflussdiagramm fuer HANA/SAP/MANUAL_EXCEL, ein ER-Diagramm der wichtigsten Tabellen und ein Sequenzdiagramm fuer `ExportAsync`. Achte darauf, dass `DatabaseInitializationService` produktive Reparaturlogik enthaelt und dass `MANUAL_EXCEL` sowohl lokal als auch ueber SharePoint gelesen werden kann. + +## H295 - Weitere Kontextdateien + +Quelle: LLM_SYSTEM_GUIDE.md.raw + +## Weitere Kontextdateien + +Zusatzkontext fuer Verlauf und Risiken: + +- [HANDOFF_2026-04-15.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/HANDOFF_2026-04-15.md) +- [NEXT_STEPS_2026-04-15.md](C:/Users/koi/source/repos/Ai/TrafagSalesExporter/NEXT_STEPS_2026-04-15.md) + +Diese beiden Dateien sind wichtig, wenn ein anderes LLM nicht nur Struktur, sondern auch historische Umbauten, Risiken und Prioritaeten verstehen soll. + +## H296 - Finance Handoff 2026-05-18 + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +# Finance Handoff 2026-05-18 + +Dieses Dokument fasst den aktuellen Stand der Finance-Abstimmung zusammen, damit die Arbeit ohne Wissensverlust fortgesetzt werden kann. + +## H297 - Aktueller Stand + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## Aktueller Stand + +Testprogramm: + +```text +http://127.0.0.1:5099/finance +``` + +Die App laeuft lokal auf `127.0.0.1:5099`. Der letzte Check der Seite ergab HTTP `200`. + +Aktuelle Excel: + +```text +docs/FINANCE_AMPEL_LAENDER_2026-05-18_21-27.xlsx +``` + +Aktuelle Cache-Dateien: + +```text +docs/it_cache_2025.csv +docs/spain_cache_2025.csv +``` + +## H298 - Nachtrag 2026-05-19 + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## Nachtrag 2026-05-19 + +Nach diesem Handoff wurden noch vier relevante Schritte umgesetzt und committed: + +1. Haupt-App-Finance-Vergleich an FinanceProbe angeglichen. +2. Leere Ist-Zeilen ohne belastbaren Ist-Wert aus dem Finance-Vergleich gefiltert. +3. Berechnungsformeln je Land dokumentiert. +4. Finance Cockpit mit separatem Login technisch geschuetzt; fachliche/produktive Abnahme noch offen. + +Wichtige neue Doku: + +```text +docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md +``` + +Diese Datei beschreibt die aktuell verwendete Soll/Ist-Logik fuer `/finance-cockpit/vergleich` und `/finance`, inklusive Jahresfilter, Kandidatenberechnung, Deduplizierung, bevorzugter Ist-Variante und landesspezifischer Quellen/Formeln. + +Neue Finance-Cockpit-Sperre, Stand technisch: + +- `FinanceCockpitAccessService` +- `FinanceCockpitAccessOptions` +- `FinanceCockpitUnlockPanel` +- Konfiguration in `appsettings.json` unter `FinanceCockpitAccess` +- DI-Registrierung in `Program.cs` +- Route-/Navigation-Schutz in `Routes.razor` und `NavMenu.razor` + +Wichtig: Der HR-KPI-Login bleibt separat. Die neue Sperre betrifft das Finance Cockpit und laeuft wie HR-KPI ueber Benutzername plus SHA-256-Passwort-Hash. Finance hat ein eigenes Passwort: + +```text +Benutzer: finance +Passwort: Trafag-Finance-Cockpit-2026! +``` + +AD-/Rollenpruefung ist fuer den Moment nicht geloescht, sondern in `appsettings.json` mit `Security.Enabled = false` deaktiviert. Die vorhandenen `AccessGroups` und `AdminGroups` bleiben in der Konfiguration stehen und koennen spaeter wieder aktiviert werden. Die Finance-Sperre bleibt davon unabhaengig aktiv. + +## H299 - Zentrale Excel fuer CFO-/Finance-Filter + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +### Zentrale Excel fuer CFO-/Finance-Filter + +Die zentrale Datei `Sales_All_yyyy-MM-dd.xlsx` enthaelt am rechten Ende einen zusammengehoerigen Finance-Spaltenblock: + +```text +Finance | Year +Finance | Country Key +Finance | Date +Finance | Net Sales Actual +Finance | Currency +Finance | Include +Finance | Source Value Field +``` + +Zusaetzlich wird nur in der zentralen Datei ein Hilfsblatt erzeugt: + +```text +Finance Filter Hilfe +``` + +Damit soll Finance dieselben Ist-Summen aus Excel filtern koennen wie im Testprogramm bzw. auf `/finance-cockpit/vergleich`. + +Vorgehen im Excel: + +1. `Finance | Year` auf das gewuenschte Jahr filtern, z. B. `2025`. +2. `Finance | Country Key` auf Land filtern, z. B. `IT`, `UK`, `ES`, `AT`. +3. `Finance | Include = TRUE` filtern. +4. `Finance | Net Sales Actual` summieren. + +Gepruefter Vergleich gegen `FinanceReconciliationService` fuer 2025: + +| Key | Finance-Service | Excel-Finance-Spalten | Differenz | +| --- | ---: | ---: | ---: | +| AT | `3'438'121.37` | `3'438'121.37` | `0.00` | +| CH | `43'521'390.82` | `43'521'390.82` | `0.00` | +| ES | `3'082'320.18` | `3'082'320.18` | `0.00` | +| FR | `1'471'218.44` | `1'471'218.44` | `0.00` | +| IN | `750'936'591.38` | `750'936'591.38` | `0.00` | +| IT | `7'669'641.47` | `7'669'641.47` | `0.00` | +| UK | `3'533'710.09` | `3'533'710.09` | `0.00` | +| US | `3'749'865.33` | `3'749'865.33` | `0.00` | + +Hinweis: Fuer AT/CH waehlt der Finance-Service intern `Nettofakturawert Hauswaehrung pro Position`; in den aktuellen Daten ist dieser Wert identisch mit `SalesPriceValue`, daher stimmen die Excel-Finance-Spalten exakt. + +## H300 - Aktuelle Soll/Ist-Werte + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## Aktuelle Soll/Ist-Werte + +| Land | Ist | Soll | Differenz | Waehrung | Status | +| --- | ---: | ---: | ---: | --- | --- | +| FR | `1'471'218.44` | `1'471'218.00` | `0.44` | EUR | OK | +| IN | `750'936'591.38` | `750'936'591.00` | `0.38` | INR | OK | +| US | `3'749'865.33` | `3'749'865.00` | `0.33` | USD | OK | +| IT | `7'669'641.47` | `7'669'840.00` | `-198.53` | EUR | Fast passend, Filter fachlich bestaetigen | +| UK | `3'533'710.09` | `3'538'972.00` | `-5'261.91` | GBP | Kleine Restdifferenz | +| AT | `3'438'121.37` | `3'443'863.00` | `-5'741.63` | EUR | Kleine Restdifferenz | +| ES | `3'082'320.18` | `3'102'333.61` | `-20'013.43` | EUR | Groesste Restdifferenz | + +Prioritaet fuer Folgearbeit: + +1. ES pruefen: vermutlich Zuschlaege/Fracht/Nebenkosten/Rhino-Auswertungslogik. +2. AT und UK Restdifferenzen klaeren. +3. IT fachlich bestaetigen, weil der aktuelle Filter noch provisorisch ist. + +## H301 - Grundregeln + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## Grundregeln + +- Net Sales Actuals werden in der Hauswaehrung des Landes verglichen. +- CHF ist nur Kontroll-/Reporting-Sicht ueber Budgetkurse, nicht Standardvergleich. +- Fuehrend ist Netto ohne VAT/MwSt. +- Gutschriften/Credit Notes muessen negativ in die Summe laufen. +- Standard-Ist bleibt inklusive Intercompany; IC/2nd-party wird separat gezeigt, ausser ein Land hat fachlich bestaetigte Ausschluesse. +- Jahresabgrenzung: bevorzugt Buchungsdatum/PostingDate. Wenn Quelle kein PostingDate liefert: InvoiceDate, danach ExtractionDate. + +## H302 - Italien + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## Italien + +Quelle: + +- `BI1` / SAP B1 via HANA +- TSC `TRIT` +- Schema `it01_p` + +Wichtige Erkenntnisse: + +- Italien ist B1, nicht Sage. +- Frankreich und Italien kommen beide aus BI1/B1; FR passt mit `SalesPriceValue`. +- Screenshot `italien.png` zeigte fuer Italien die relevante B1-/Finance-Sicht auf Konto: + +```text +47005 - Ricavi vendite e prestazioni +``` + +Aktueller technischer Arbeitsfilter in `Services/HanaQueryService.cs` fuer `it01_p`: + +```sql +AcctCode LIKE '47005%' +AcctCode NOT LIKE '4700504%' +CardCode NOT IN ( + 'C_IT01_0022987', + 'C_IT01_0306928', + 'C_IT01_0306138', + 'C_IT01_0309653', + 'C_IT01_0304885', + 'C_IT01_0306475' +) +``` + +Aus Cache berechnete Herleitung: + +```text +10'603'550.59 - 2'933'909.12 = 7'669'641.47 EUR +Soll/Rhino = 7'669'840.00 EUR +Differenz = -198.53 EUR +``` + +Die sechs provisorisch ausgeschlossenen Kunden: + +| Kunde | Betrag | +| --- | ---: | +| FAIVELEY TRANSPORT ITALIA S.P.A. | `1'689'857.70` | +| SYSTEM CERAMICS S.P.A. | `323'409.00` | +| WABTEC MZT | `282'647.40` | +| FINCANTIERI NEXTECH S.P.A | `268'166.37` | +| METAL WORK SERVICE S.R.L. | `203'425.15` | +| ELEMASTER S.P.A. | `166'403.50` | + +Wichtig: Dieser IT-Filter ist ein Arbeits-/Prueffilter, noch nicht fachlich final bestaetigt. + +Nachtrag 2026-05-20: + +- Finance-Leiter bestaetigt als fachliche Methode: `Trafag Italia` aus dem externen IT-Finance-Ist ausschliessen. +- Identische IT-Zeilen mit leerem `Supplier country` nur einmal zaehlen. +- Die alte Kundenausschluss-Kombination bleibt als 2025-Analyse dokumentiert, ist aber nicht die fuehrende Methode fuer Folgejahre. + +Detaildokument: + +```text +docs/FINANCE_IT_VORGEHEN_2026-05-18.md +``` + +## H303 - UK + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## UK + +Quelle: + +- Fachlich Sage, nicht SAP B1. +- TSC `TRUK`. +- App-Anschluss: `MANUAL_EXCEL`. +- SharePoint-Ordner heisst technisch `Import/Finance/UK_B1`, aber das bedeutet nicht B1. + +Aktuelle Berechnung: + +```text +SageNetSales([Sales Price/Value], [Quantity], [Document Type], [DocumentType], [Type]) +``` + +Bedeutung: + +- `Sales Price/Value * Quantity` +- Credit Notes werden bei erkennbarem Sage-Typ negativ erzwungen. +- Waehrung ist GBP. + +Wichtige Korrektur: + +- UK wird gegen Local Currency/GBP geprueft. +- Der fruehere `CheckValue 3'749'865.00` war fuer UK falsch und wurde entfernt. +- Korrektes Soll fuer UK ist `LocalCurrencyValue = 3'538'972.00 GBP`. + +Aktueller Stand: + +```text +Ist = 3'533'710.09 GBP +Soll = 3'538'972.00 GBP +Differenz = -5'261.91 GBP +``` + +Detaildokument: + +```text +docs/FINANCE_UK_QUELLE_KORREKTUR_2026-05-18.md +``` + +## H304 - Spanien + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## Spanien + +Quelle: + +- Sage CSV +- TSC `TRES` +- Datei: `sageSpain/v2/Spain_Sales_2025.csv` +- Cache: `docs/spain_cache_2025.csv` + +Berechnung: + +- `SalesPriceValue` aus `LineasAlbaranCliente.ImporteNeto` +- Credit Notes/REC negativ +- Datumsbasis: `FechaFactura` +- Waehrung: EUR + +Aktuelle Zerlegung: + +```text +Zeilen = 4'341 +Invoice = 3'140'921.50 EUR +Credit Notes = -58'601.32 EUR +Ist = 3'082'320.18 EUR +Soll/Rhino = 3'102'333.61 EUR +Differenz = -20'013.43 EUR +``` + +Nach Serie: + +| Serie | Zeilen | Betrag | +| --- | ---: | ---: | +| REG | `3'079` | `2'407'451.30` | +| LAT | `1'118` | `480'199.20` | +| PRO | `43` | `253'271.00` | +| REC | `101` | `-58'601.32` | + +Bewertung: + +- Differenz ist ca. `0.65%`. +- Gutschriften sind nicht das Problem, sie sind bereits negativ. +- Wahrscheinlich fehlen oder unterscheiden sich kleinere Sage-/Rhino-Bestandteile: Fracht, Portes, Zuschlaege, Rundungen, Versicherung, Finanzierung, nicht-artikelbezogene Belegpositionen oder eine andere Sage-Auswertung. +- Nicht einfach auf Belegkopf `DocumentNetAmount` wechseln: deduplizierter Belegkopf liegt bei `2'907'901.79` und passt schlechter. + +## H305 - Geaenderte Programmteile + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## Geaenderte Programmteile + +Wichtige Dateien: + +```text +Services/HanaQueryService.cs +Services/ManualExcelImportService.cs +Services/DatabaseSeedService.cs +scripts/Export-SageSpainSalesCsv.ps1 +SageSpainFinalExportPackage/Export-SageSpainSalesCsv.ps1 +TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs +``` + +Wichtige technische Aenderungen: + +- IT: provisorischer B1-Konto-/Kundenausschlussfilter fuer `it01_p`. +- UK: `SageNetSales(...)` im Manual-Excel-Importer. +- UK: `FinanceReference` nutzt fuer UK nur `LocalCurrencyValue = 3'538'972`, kein `CheckValue`. +- ES: Sage-Spain-SQL erzwingt Credit Notes mit `-ABS(...)`. +- Test ergaenzt, der positive Credit-Note-Rohbetraege negativ macht. + +## H306 - Validierung + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## Validierung + +Build: + +```text +dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_uk_reference\ --verbosity minimal +``` + +Ergebnis: erfolgreich. + +Tests: + +```text +dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false --verbosity minimal +``` + +Ergebnis: + +```text +71/71 Tests gruen +``` + +FinanceProbe: + +```text +http://127.0.0.1:5099/finance +``` + +Ergebnis: HTTP `200`. + +## H307 - Commits + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## Commits + +Relevante Commits: + +| Commit | Inhalt | +| --- | --- | +| `fb85e2e` | Sage-Berechnungen korrigiert, IT/UK-Doku und Ampel ergaenzt | +| `3d40d76` | UK auf GBP Local Currency als Referenz umgestellt | +| `f721d95` | Aktuelle Excel und Spanien-Cache ergaenzt | +| `bc6bfdf` | Finance-Handoff dokumentiert | +| `8f1b1b8` | Haupt-Finance-Vergleich an Probe angeglichen | +| `f855e06` | Leere Ist-Zeilen im Finance-Vergleich gefiltert | +| `5c654ad` | Finance-Berechnungsformeln je Land dokumentiert | +| `9c544af` | Finance Cockpit mit Login technisch geschuetzt | +| `ebbc5a1` | Finance-Filterspalten in zentrale Excel ergaenzt | +| `b23f73e` | Finance-Hilfsblatt in zentrale Excel ergaenzt | + +Dieses Handoff wurde danach als weiterer Commit hinzugefuegt. + +## H308 - Nicht aufraeumen ohne Ruecksprache + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## Nicht aufraeumen ohne Ruecksprache + +Es gibt noch untracked/temporaere Arbeitsdateien und alte Word-/Excel-Backups. Diese wurden bewusst nicht committed, weil sie entweder temporär, defekt, Logdateien oder Zwischenstaende sind. + +Bekannt uncommitted: + +```text +.tmp_tools/ +Tools/FinanceProbe/.tmp_tools/ +verify_probe_out*/ +financeprobe.*.log +docs/CFO_Kurzbericht_270515.docx +docs/CFO_Kurzbericht_270515*.bak.docx +docs/CFO_Kurzbericht_270515_NEU*.docx +docs/FINANCE_AMPEL_LAENDER_2026-05-18.xlsx +docs/FINANCE_AMPEL_LAENDER_2026-05-18_20-32.xlsx +docs/FINANCE_AMPEL_LAENDER_2026-05-19.xlsx +docs/it_cache_2025.csv +italien.png +financeprobe.*.log +mainapp.*.log +``` + +Wenn weitergearbeitet wird, zuerst `git status --short` pruefen und keine fremden/alten Dateien blind loeschen. + +## H309 - Naechste sinnvolle Schritte + +Quelle: FINANCE_HANDOFF_2026-05-18.md.raw + +## Naechste sinnvolle Schritte + +1. ES: Sage-/Rhino-Unterschied von `20'013.43 EUR` gegen Fracht/Zuschlaege/Nebenkosten pruefen. +2. AT: Differenz `-5'741.63 EUR` analysieren. +3. UK: Restdifferenz `-5'261.91 GBP` klaeren, aber UK ist jetzt nahe am LC-Soll. +4. IT: provisorischen Kundenausschluss fachlich bestaetigen oder durch offizielle B1/Rhino-Filterregel ersetzen. +5. AD-/Rollenpruefung spaeter wieder aktivieren, sobald geklaert ist, welche Gruppen produktiv gelten. Dazu `Security.Enabled` wieder auf `true` setzen; Gruppen sind nicht geloescht. +6. `/finance-cockpit/vergleich` und `/finance` nebeneinander pruefen, wenn neue Daten geladen wurden; beide sollen dieselbe `FinanceReconciliationService`-Logik nutzen. + +## H310 - Finance Dashboard Todo + +Quelle: FINANCE_DASHBOARD_TODO_2026-05-15.md.raw + +# Finance Dashboard Todo + +Stand: 2026-05-20 + +Hinweis: + +Dieses Dokument ist eine historische Todo-Liste vom 2026-05-15 und wurde am 2026-05-20 nachgezogen. Fuer den aktuell fuehrenden Dokumentenstatus siehe: + +```text +docs/MD_DOKUMENTENSTATUS_2026-05-20.md +``` + +Ziel: Aufbau eines modernen, uebersichtlichen Intranet-Dashboards fuer das Group Sales Reporting, zugaenglich fuer alle freigegebenen Benutzer. + +## H311 - Todo + +Quelle: FINANCE_DASHBOARD_TODO_2026-05-15.md.raw + +## Todo + +| Prio | Aufgabe | Status | +| --- | --- | --- | +| 1 | Fuehrendes CFO-Dokument verwenden: `FINANCE_CHEF_SUMMARY_2026-05-15.docx` | Historisch; neue Anwenderdoku `FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx` ergaenzt | +| 1 | Offene Finance-Entscheide mit Andreas/Finance durchgehen | Offen | +| 1 | Italien-Abweichung klaeren: Berechnungsart, Deduplizierung, Intercompany | Teilweise geklaert; Finance-Leiter bestaetigte Methode, Restdifferenz dokumentiert | +| 1 | Italien IC-Diagnose besprechen: Trafag, Magnetic Sense/Magnets Sense und Gesellschaft fuer Sensorik erklaeren einen grossen Teil, aber nicht die ganze Abweichung | Historisch; neue IT-Methode verwendet `CustomerName` Trafag Italia und Dublettenregel | +| 1 | Deutschland: finalen Jahresfile 2025 beschaffen | Erledigt technisch; DE Alphaplan ist eingebaut, Fachabgrenzung Kundenlaender bleibt offen | +| 2 | UK/England: Jahresvollstaendigkeit und Restdifferenz pruefen | Teilweise erledigt; UK ist Sage/Manual Excel, Mapping korrigiert, Restdifferenz klein/offen | +| 2 | CH/AT: Sollzuordnung und Trennung final bestaetigen | Offen | +| 2 | Spanien und Oesterreich: kleinere Differenzen klaeren | Offen | +| 2 | Intercompany-/2nd-party-Kundenliste final definieren | Offen | +| 3 | Budgetkurse je Jahr als Quelle festlegen | Offen | +| 3 | Dashboard-Sicht fuer CFO: nur Laender mit Abweichung und Handlungsbedarf anzeigen | In Arbeit; Finance Summary und Soll/Ist Sicht vorhanden | +| 3 | Detailansicht je Land mit Berechnungsart und Pruefspur behalten | In Arbeit; Rohdaten-/Diagnosereiter bleibt erhalten | +| 3 | Freigabe-/Berechtigungskonzept fuer Intranet-Dashboard klaeren | Offen | + +## H312 - Naechster Termin + +Quelle: FINANCE_DASHBOARD_TODO_2026-05-15.md.raw + +## Naechster Termin + +Ziel im Termin: +- Deutschland und Spanien muss finales Excel schicken (Rohali 2 mal nachgehakt warte auf finales File) +- Grundlogik bestaetigen: Hauswaehrung, Nettofakturawert, Buchungsdatum, Berechnung pro Belegposition. +- Offene Laenderabweichungen priorisieren. +- Pro Land festlegen, welche Datenquelle und Berechnungslogik final gilt. + +## H313 - IT / Intercompany Diagnose + +Quelle: FINANCE_DASHBOARD_TODO_2026-05-15.md.raw + +## IT / Intercompany Diagnose + +Aktuelle Diagnose fuer Italien: + +| Kennzahl | Wert | +| --- | ---: | +| IT Ist vor IC-Abzug | 14.704.336,29 EUR | +| Rhino/check.xlsx Soll | 7.669.840,00 EUR | +| Abweichung vor IC | +7.034.496,29 EUR | +| Erkannter IC-/2nd-party-Abzug | 4.397.746,90 EUR | +| IT Ist exkl. IC | 10.306.589,39 EUR | +| Restabweichung nach IC | +2.636.749,39 EUR | + +Verwendete IC-/2nd-party-Marker: + +- `TRAFAG` +- `MAGNETIC SENSE` +- `MAGNETS SENSE` +- `GESELLSCHAFT FUER SENSORIK` +- `GESELLSCHAFT FUR SENSORIK` + +Bewertung: + +- Intercompany/2nd-party erklaert einen grossen Teil der IT-Abweichung. +- Die Summe passt dadurch deutlich besser, aber noch nicht vollstaendig. +- Restabweichung weiter pruefen: Summenlogik, Beleg/Position-Deduplizierung, Gutschriften/Storno und weitere lokale IC-Kunden oder Schreibweisen. + +## H314 - Finance: Welches Dokument gilt? + +Quelle: FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md.raw + +# Finance: Welches Dokument gilt? + +Stand: 2026-05-20 + +## H315 - Aktueller Nachtrag 2026-05-20 + +Quelle: FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md.raw + +## Aktueller Nachtrag 2026-05-20 + +Zum alten CFO-/Finance-Termin-Dokument ist eine neue Anwenderdoku fuer das Cockpit hinzugekommen: + +```text +docs/FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx +``` + +Diese neue Word-Datei ist die bessere Anleitung fuer Finance-Anwender im Cockpit. Das CFO-Dokument vom 2026-05-15 bleibt historische Termin-/Entscheidgrundlage. + +Technisch/fachlich aktuell fuehrend: + +- `Management Analyse` Reiter `Finance Summary` +- zentrale Excel `Finance Summary` +- `FinanceRuleEngine` +- `docs/FINANCE_ENTSCHEIDE.md` +- `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` + +## H316 - Fuehrendes Dokument + +Quelle: FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md.raw + +## Fuehrendes Dokument + +Fuer den CFO-/Finance-Termin vom 2026-05-15 galt: + +```text +docs/FINANCE_CHEF_SUMMARY_2026-05-15.docx +``` + +Dieses Dokument ist die aktuellste CFO-Kurzfassung mit Ampel, Laendertabelle, Pruefquellen, Prioritaeten und empfohlenen Massnahmen. + +## H317 - Geloeschte alte Fassung + +Quelle: FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md.raw + +## Geloeschte alte Fassung + +Die alte Fassung `docs/FINANCE_CHEF_SUMMARY_2026-05-13.docx` wurde entfernt, weil sie durch die Version vom 2026-05-15 ersetzt ist. + +## H318 - Entscheidbasis + +Quelle: FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md.raw + +## Entscheidbasis + +Die fachlichen Entscheide stehen separat hier: + +```text +entscheide.md +docs/FINANCE_ENTSCHEIDE.md +``` + +Kurzfassung der wichtigsten Entscheide: + +| Thema | Entscheid | +| --- | --- | +| Fuehrende Waehrung | Hauswaehrung je Land | +| CHF-Sicht | Nur separat mit Budgetkursen | +| Aggregation | Pro Artikel bzw. Belegposition | +| Wertbasis | Nettofakturawert | +| Jahresabgrenzung 2025 | Buchungsdatum | +| Gutschriften / Storno | Separat ausweisen, positionsbasiert behandeln | +| Intercompany / 2nd-party | Separat klassifizieren und als Auswahl/Sicht fuehren | +| Indien | INR ist fuehrend | +| Italien | Hauswaehrung, Intercompany separat pruefen | + +## H319 - Wichtig fuer Rueckfragen + +Quelle: FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md.raw + +## Wichtig fuer Rueckfragen + +Falls im Termin gefragt wird, ob die Berechnungslogik schon entschieden ist: + +> Ja. Die Grundlogik ist entschieden: Hauswaehrung, Nettofakturawert, Buchungsdatum und Berechnung pro Belegposition. Offen sind vor allem Datenvollstaendigkeit, Intercompany-Abgrenzung, Budgetkursquelle und die fachliche Freigabe einzelner Laenderabweichungen. + +## H320 - Was noch nicht final ist + +Quelle: FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md.raw + +## Was noch nicht final ist + +| Thema | Status | +| --- | --- | +| IT | Kritisch; grosse Abweichung, Berechnungsart/IC/Deduplizierung pruefen | +| UK / EN | Hoch; Restdifferenz und Jahresvollstaendigkeit pruefen | +| DE | Hoch; finaler Jahresfile fehlt, Sample nicht verwenden | +| CH / AT | Hoch; Sollzuordnung und Trennung finalisieren | +| ES / AT | Mittel; kleinere Differenzen klaeren | +| FR / IN / US | Rechnerisch freigabefaehig | + +## H321 - Email an Spanien: Abweichung Net Sales 2025 + +Quelle: FINANCE_ES_MAIL_ABWEICHUNG_2026-05-15.md.raw + +# Email an Spanien: Abweichung Net Sales 2025 + +**Asunto:** Revision diferencia Net Sales 2025 - Espana + +Hola, + +En la reconciliacion de Net Sales 2025 para Espana hemos identificado una diferencia pendiente de aclarar contra el valor de referencia de Rhino / `check.xlsx`. + +Resumen: + +- Actual Espana: `3.082.320,18 EUR` +- Referencia Rhino: `3.102.333,61 EUR` +- Diferencia: `-20.013,43 EUR` + +La diferencia no parece muy grande, pero antes de cerrar el dato necesitamos confirmar la causa. + +Por favor, podeis revisar los siguientes puntos? + +1. Periodo incluido en el fichero + Confirmar que el fichero `Spain_Sales_2025.csv` contiene todo el ano 2025 completo. + +2. Series incluidas + Confirmar que las series `REG`, `LAT`, `PRO` y `REC` deben incluirse en el calculo de Net Sales 2025. + +3. Abonos / Credit Notes + Confirmar que los abonos estan incluidos correctamente y con signo negativo. + +4. Criterio de fecha + Confirmar que fecha debe utilizarse para la delimitacion del ano 2025: fecha de factura, fecha contable u otra fecha. + +5. Importe correcto + Confirmar si el campo utilizado como importe neto de ventas es el correcto para comparar contra Rhino / `check.xlsx`. + +Objetivo: aclarar si la diferencia de `-20.013,43 EUR` se explica por periodo, series, abonos o por el campo de importe utilizado. + +Gracias y saludos, + +## H322 - Email an Italien: Abweichung Net Sales 2025 + +Quelle: FINANCE_IT_MAIL_ABWEICHUNG_2026-05-15.md.raw + +# Email an Italien: Abweichung Net Sales 2025 + +**Oggetto:** Verifica differenza Net Sales 2025 - Italia + +Ciao, + +nella riconciliazione dei Net Sales 2025 per l'Italia abbiamo identificato una differenza significativa rispetto al valore di riferimento Rhino / `check.xlsx`. + +Riepilogo: + +- Actual Italia: `14.704.336,29 EUR` +- Riferimento Rhino: `7.669.840,00 EUR` +- Differenza: `+7.034.496,29 EUR` + +La differenza e molto rilevante. Prima di chiudere il dato dobbiamo confermare quale logica di calcolo e corretta per l'Italia. + +Potete per favore verificare i seguenti punti? + +1. Base di calcolo corretta + Confermare quale valore deve essere usato per i Net Sales 2025: valore netto per riga/posizione, totale documento deduplicato oppure un'altra logica. + +2. Totali documento vs. posizioni + Verificare se i totali documento sono ripetuti su piu righe e quindi devono essere conteggiati una sola volta per documento. + +3. Intercompany / 2nd-party + Confermare quali clienti o transazioni devono essere esclusi come Intercompany o 2nd-party. + +4. Note di credito / Credit Notes + Confermare che le note di credito sono incluse correttamente e con segno negativo. + +5. Criterio data + Confermare quale data deve essere utilizzata per delimitare il 2025: data registrazione, data fattura o altra data. + +6. Valuta + Confermare che la valuta di confronto per l'Italia e `EUR`. + +Obiettivo: capire se la differenza di `+7.034.496,29 EUR` deriva da doppio conteggio dei documenti, trattamento Intercompany, criteri data o dal campo importo utilizzato. + +Grazie e saluti, + +## H323 - Email an UK / England: Abweichung Net Sales 2025 + +Quelle: FINANCE_UK_MAIL_ABWEICHUNG_2026-05-15.md.raw + +# Email an UK / England: Abweichung Net Sales 2025 + +**Subject:** Review difference Net Sales 2025 - UK + +Hi, + +In the Net Sales 2025 reconciliation for UK / England, we identified a difference against the Rhino / `check.xlsx` reference value. + +Summary: + +- Actual UK: `3,533,710.09 GBP` +- Rhino reference: `3,749,865.00 GBP` +- Reference UK LC/GBP: `3,538,972.00 GBP` +- Difference: `-5,261.91 GBP` + +The mapping has already been reviewed technically, but we still need to clarify the remaining difference before closing the 2025 value. + +Important clarification: UK / England is treated as a Sage source. The current SharePoint folder name `UK_B1` is only a technical folder/source reference and does not mean that UK is read from SAP Business One. + +Could you please check the following points? + +1. Full-year completeness + Confirm that the UK source file/import contains the full year 2025 and not only a partial period. + +2. Period included + We currently see data from approximately `03.01.2025` to `22.12.2025`. Please confirm whether this is complete for 2025 or if transactions outside this range are missing. + +3. Credit notes + Confirm that credit notes are included correctly and with the correct negative sign. + +4. Net sales field + Confirm which column should be used as the net sales amount for comparison with Rhino / `check.xlsx`. + +5. Discounts, freight or additional charges + Please check whether discounts, freight, additional charges or other adjustments are included in the Rhino reference but not in the current import value, or vice versa. + +6. 2nd-party / 3rd-party / Intercompany + Confirm whether any customers or transactions should be excluded from the Net Sales 2025 value. + +7. Currency + Confirm that the correct comparison currency for UK is `GBP`. + +Goal: clarify whether the difference of `-216,154.91 GBP` is caused by an incomplete period, credit notes, a different net sales field, adjustments, or 2nd-party/3rd-party handling. + +Thanks and best regards, + diff --git a/TrafagSalesExporter/docs/raw_md_archive/original_history_raws.zip b/TrafagSalesExporter/docs/raw_md_archive/original_history_raws.zip new file mode 100644 index 0000000000000000000000000000000000000000..d2e05e899000a328cd0107d44824a60ee26f412c GIT binary patch literal 87583 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
oXtwUGBmo-n6-{EH)>Dvf$;?6i{{u2y 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ൊivrokjIrVGrWU{&Fj zxDfvFJPMQ562(h)zKl($Ggf)Qbe&R{GZYXvF_;_Z5GGAtak2Cm|Nmx1=zfZ}gJyc$ z=LMqXY!?4s_Z;5GK=?p2P@L?)2)BdWE`O3l4k@-sgHRX=WbHDSZYs^6^E44zsoOY1 zWE3tXwa9HUGBQJ#xMGMg<%#+P7e)RvoQJ?^B&5ymSz1Tbs7-Ieb!INEMWtce+;;wR$WlrKqrb{j&8FQFk1FawB|4W@SmlYze&3Fm>0A7@t&Ek}MGu;vC0wV_N@6)|GM$Nk+zA;~e%C{-hXb z?-G=PpIIoo`%#$?9U|EO0?+qH)? z#;kGgQY`CFyi{DAq6r~tX@ba3nb@$vr3q)bZ+;O0((wLu1q1?I7&nBBQ0}PV1qgaV znTwT8x<#?jc3Gz#=>??+5tV`;E8Rp|&5t)*Akw zKbzx{Q!^zpbZ-}PM66U$M2YPwiZyV~|MI`l0fy>Q_bT93`0x|3lH$QfH3H3$sul#Do#yWURj;LUY93id z+#`k9KAVff^crPYQ;^?S?QEL~iIYbu341=M<)lDAc3FzSeXMgtX=@v(4Fe-(=Kj!&<-@YeY%dl@s-c#RgF;#+>jW(0fj z^lo^2dD$KO(PgD1q=@pIaotqV7QPup%sB?7IdmghG$_MKh~+)l`-_SLm6`BP2Uw;O z3seG;jT&AL{)H_^q8r3-yiVKVAqTDfUSrfkNr6)wBxGM5H(7B*2DmTZLS=xVaN z#x#kgP>#!Zi72nnTY{r&ou!k9mM(XbT_8GEP7OOBwd^_XkZcxGUw71!EiDDPrN$nG zLK#9%AJfwM*KXXpQ4$udno{@#rQ_gJ<5k22EyC^j-BIT?MtO35{0Cd)EO>^YTT=m^ zH$N}tfq0=F*ag6)m0G4|cWKH&H9$^4lIpT)Kt@=*O-FW)e4sr-fQg-mCdY}hTB@*0 z$BJ#jf_`u_Jbu4Mx^FPB-tg|S+rPN$9)0ZfkI!ze-n-CIV7IY(;4w;%_;ZEpHP{_%ys`d?jX$y8;`n6Y5Wl&|A6+P)^==-L z;XHLbkDHy{MrUWcdC>6~GRRY7Ths*&JVppg(Q;tpNK}IIG}u!eVX?Opph8qcVOdcC zJrpg3tjzE(^e5ZKfYtey2*8O6P>Axe>?W?={>VI2yH`?m65r~K&Tf;;33`HIjeP*H zV;a2p!Q{Z7Qi&BkBj;3Y!bA+p!2)St)o|khwqM|odt_NEcs(@GSc?HP%AWp)MP$1E ze(}?*xP8T|?}p{YH6e$w(!36Wzlpuy-}=5sRe@{bPG&H0YkP zar3@6>|I<8kI%ZNBk%OKH=vuY2mSM!U!5PTgrOXF1~Ro^>ii{K;bZRt9#nFIc&Z1*VQCkC8iqF?JcuF(UvC+zrj%G4Hq^|$L(DVfz6VoS+GN{hF{^riE ze+HZ7W=kvn7d_!%c4X+CT-qi3CCHS&y$|vsLxm@K1&{KLy|!uNx7?anrjV>(Q%Dx~ z1nEvfQVm*Whf?(ir-Gj?-_l61L=l$Dv`~{VH97-T=#tB=xI+>d%{+JTMGsgK!6YQ7;L{^Jx0+R|RPO zzp_nw(Mj0AqlTDyy&5z>!P4iS_~}66NW&Wt`^VP%YD3%74L5xxHc_{Tn zG-&6W)p!m})xV}B05ACTsQ_{9!ydx<_Q&zm$SAH}0AxuST%V3?AoQO&$e@Wx z!Xjg~B}|ZtZ$%ihCro8dusG62Dyx7hH$#D#xsEYoM?-PxeJZUTxjYdfE0-KV8%rE$ z0XBzEHYzuvL&yn?H&^Hal8Qf&Zzl-o$2b{Wa_%qhtyC}k(Mh%qr@%p^GJ*h{!iD@+ zP96o8NYuEmCl{DYGR3S4I}MYDcxB2<(@4H+TQiMdLLc>q%nw_wZzGSELj^57K+WQF z5!ftL0bK_6r>bj~s|S*)Q_x}TCeNI>)_RIFCFPs@a0>5Arqs$J<{D1xgI9+QwS)wo zCS-Re2Mso2nm*@V?+NvQ4>6`6l#*h7a|<$C?{_!^>{Mv0{&U(JCWGLS?B+|bkcck; z-&?^ZeAq;CrwtMsz`vbgyk3^2EIo04H)%SrOo4gL#XwbRbabbpz)UF%R`e=GLEvOS z7n-5+F_qu8Hemw`cmAkqpQ2n-qz`2rq3A-QgXx28qsl8%sIzix>}ds!$7$*5AULw< z36_*Rlkuc=2GlW0Y45&4C+`l9&-$a@`RI0VH|Txn_debYM_sVyhIeP6p&wtL^uO*8 zIf^u;3J(@G@kWOcr4Ua7|1v5bQt_PODmE)2Il0gF?2uOCFDtGGG)FOU7R{HGK8^}D zI_Q3+uFLaC5eihF)aGOgbRAbuoHU@%aM3c1?yq!~AENh0tnZY>*ujzxKYWILJ zkxPmSYFSh*voS8h1V6prX&#@lk_qCBCNoc zN~f%F+i;x;V6nVsVE3W0DIj|q3A0<*Xh&>dw_3R5!5JK)iOrGd*W86wP7SMVZ*VaD zjwGniAGJ!jZKI#P8DZdq1LNE|0gAiLz4nf4@&9K`-paguGcTi42~CS5(zgysTHAWZ zjrGc`du-O6I{yjBjqh3ke=Aom{kMkxs0qeAzTkYNE&i+AT%N>@(8a6aQksE9~*4*7aXzp*f8*O)B zbemc)0HbYa{D0YO?r!bEOq}tt_=)g8-M@OrTa;15ghCKSyoU+lJBe}jN7aq2%tO?1 zF2#YTkVFVW;GFgkUv(|lw9293v|NOwZNOe|cQM9^4!K}IBY|rhG+E%K%Of4A%vYQq zrvxYho2jNQP6xvV-{TY`l zj94lWj-)}j6rcrOg}wkpI)J)}i_zkXQRylPkBCrw`oU~^GWp|l8-j^r0GtLG$Hplv zNCeQtX_HmFP@P8?L1*!#B_tgSS1|eQvP2mfN{M(&u2NvEQG=RlkPIyEmF*4c)~eyq z*SC29{&6UvhYSpz2`oEmUBAdpu-9(wwbxTa{vpnS^S)HJ%ELsx`EM(7ym?`*C>c<< z8>HBC?nvANZ6}^QqTtPe8U?_@sxtVNkXaRbh1 zL*UH7z`(R59JT-y6o^cpy3FF_C0@o_PC&||OEUeTy9JKoE8xb4_b5?uv4t91mCuoY za!|z6YZXOt3KMM48fluL?G!<>u2`!^wax~uE?JN>G%cfPDS_qN9J^Sk&pxf02=yM_ zb@we@r74isaa-@3^?3DkaH;%Yc!ZAQIBSJ2OjfC&v#h4-zK-8td5NKK9i!^wHDimz zQ~$;z#KCRibzm!DUONZhLw3R<5-#yBqXcE2sn{yToTxy}KipfHgim)f3|0IxPV|3< z!}6r(b?3{6a0%9f6u*MSc#89sEB=5qqmVEbe|+0<^t`*mSAo5WVpkvpRBiN+YR`cb~3;s3}_u9kK^(K>^EZ^mN+W8 zOjoRqEA>G#Gc#+ZwGM1&79X~@9dgOdl60iV%R_CiknjYggxZep1Sg6q@j6@l~_V8%F@$H9U^NpuhjLlwn{~c zsq{s`-HLa%H+B!&&GwF`)qR}iOcjEq5Ovq2}ZtrdE z9BekX?UQP@V`*=vM}5a;h$v|A^issbb)|U{KFS7sA3jas@+c zg!#N~%J%=!n(Q>X3w23+S_?Wk#+FRwuhs~SYAPH&L#i&27zsB_}y@Pk6;?~ zz@YW8-ionKAlX)oDqPk>!fM+^CP{C(oUiM>YqBMlV07dKrdY%veQ;_#QCG^E7gidS zVqA1K$10UgMYYRR?zzzupGM9-64?pTD6oF?b5Gii<*131+U6OYV2n zW6XCuRjJ&xD`Ej;D1zuC!x!~psr0F-NCd4sR45OYgzI{L1~GX%g#U0|GyKCio!a|S z$cqsotAvxp>|1Gs7L6cD@zTKMJuOi{p&-e(HKF`5=Haw-ZsM9+zz8}&b9oLUjJwr|}*$&navS!O`@D(y0 z5c$Q9w{%4%%(VD|KjGV2PbK>YIS{|eG%vM@EOsTh)Ksa6o`6;wu=aA20lX&)6}>#(VwUCo&1A*IH><%%v(V7+)@vk?-{ zMOyu1&yQ@<9l2by=nfA5f8P`2JE1F^V19(4J?(+@w#mggS!9#@rOd2}Mny`*PX6vH zxo0cb9?{dSui{WleY8$0BTC;c!M34#fQfamjXV!Qlu5QWUAs=^Ujlnz#TD8j9E+Lo zfacM3)Kpy_w^JmWlWJ9Q>@BwCj-*!JZQlf<430quqsl`RY;#YBKz5~e9{dQ(1)maI zzK5O(bEk}~SMHw1@9MF1>W};(g|8U9&6QP@tEo1i?Fq$AqfMcSlkyvA+I}yY;q@o- z@TTff3u@bm1x|0TmhC1`S!g`wJcwS7CTTK>=ds%#E6|i)R7OCcmZyVzj|*aS8~PZv zt!ua=L$jw5Df4E`(jHhT&auOa|4OX6gcv^`k$?_Npimwzdv#$Q1h#@>LU>qWaQ%ru zHPKq&df4nPGcA|{a}le4RW1#?H=Zt$y+{BM`}d{x%+iM~hzN|l`*1Zc{4%MVK4NN+ zQ%0u~7>=@+=a?9gDJE?_5w@a-ob{m8`RAPkIyl>z;}$V>_o}@e7N`iZ^Yvvo1EwBN z;Db@OuYa`MAnKj>ez>{QX}1q{D)$Spnf*N^^tX{4iyyCMD8dn;zF9oLpqzA_P{o}m zGS;c?wPR_xjVGw{_6j*xlJ_ z?(e_yba~%NKXb;}+1c3L-fwPpC}iMPB6>e`H%Y1uaK6Kn8DMjNW3#=}+-=*n{s^3z z>T3IzdW7@FN%i$>|JT{r?i@7tKuo?vpQaX3lHihR_s@!4W4FYPx@w^^+5?%u}c_8zN7T!Fi!5t_FsjMUaqHY%IcX8_F{rdkyC z9iPKTb-mkqXo6U4A$M*$wY%F*sf0^bHW|U3V}ar*a(aQH0u-%gg$0R3i7aZ6QWe5a z>;~)3=XZ7=-3sZBcb%AvAZ?_sj4rgY9&A26o%e=Td@@O;^ zINMwM8=cKgb88P+;F(9wAiV9Zjh)R7yrtdT-$Yfy-tTh0-q2pRtp;F91HBHSaIdqm z+1YPyZ-4(?|H||FR|9Wvr@e8owY#x%0PltS`({3S8@sz(8=dW)<{pfHd+uSvD2>0f zwY9O=f!#TP>+s&&;R#*Wx_4V!Z`879ecW{uS^5#!k<)uGu1Bz2NVn8yc+5gLjPcCY zf6C2pCr8pzL|c9&btQ-MzyTg4(w#`pgfSP{5|F0jLX%5{q_3nB;hNv)t2Bro#HB=Y z%yUaj1{qu1+MHV)JfQiK%Lzjs$|o#)qEd>b=af0M2dTb4xq3}%XK7~0ae5&chcP016WsY~8p{bk|FyzA#~1Ty#l438`$U z6nD-`Fb4{xfkA_yGJ1=Yg3yc}7!~&8FaHZ6b40mR@uq>HYaqK9ZZw0YWKz?n8 zo;s9KhQU=-rJBQs^!Z~re}um;!tp6Jo~*VdE$OKzWfj#?&B!%Z(ifc{K`(QEktCqj zB+pwgPf&S&k*c?L7p>S(_=S7t4Y%-dRIkY@1G}c>ECQ23zOJ4*_bBw|RaNdbMpsPr z=b9|Z`j%gtyN4#9;xzt@)d&POdb>o`tl@nKvzQw+Q+nvhDH-e$w$i15VasE;uZ!#z zJf`@ACBtVxK3K};^G~A3d6)^z$%3{s*h+3_CGOBjfaU5O<2YN+!Sys-tmcShCl4dy z>G4BeB-;s-cR2EpMd3_+4X(46p39;+*A7D1S?;6*8mtTE>u3^?lCqm<6qMYbY2n`v zE^_vL+=Ru$5h&vx!S^I`!W`FN0DU+0ndJzMl+&UiKg7J_o9p4o?T?c~+k=E_igj;%>-pMTMfpKP+=O;9Wj~qTsp*c)Mzh=w$!q}y2|wx+u#m|rFWgMTPY)Sb(4p|e z?3t>0yDUqsjcJTXRIDJ$<*3EpaUh4x=4TjFDg7#?5Ba9jF9?W-r9cn@a$~}vlx}#V zJ|9D}<``L}q(ZG}!(n_c_>d-CNhQFBQAcsEe`)aqI<%xanhKQTNPJp~)m|@yiW{x3 zG7%4_8Y#R%D>1?0uhz&kPogczwf^Wp2vD}5Y9{PH!~CE?%4IrGgek=}uxzFx#L=Uk z7g9Bb5e=-{&I@+FQYgjTuGDI#GK-`E#al0V)E<`g@1SC}=t3kCkbXyRY_IVK8${78 zdZq%N?#ygZ!>M!;T&|`_oi}ja5w5|DtF4wmcLQbb%%J^1$`c%!0vEwnr`g_WqWs`f zE195F>OnfWO5Ir0z%c*FDc=v`!*88rtI6Y7IQh>}rGT_$`7cfHs42aS93mpPoUAGR zTdP);;QtazbV@}BMkA*Qv~VusI>@AAA!q+%iWpi+F*j|*S;d4Hr%-g$8zJ6SVB4w9 zL1f3l%PJ2k8qLMkn01zTxqPmbtHg&)lOQVVAX*Ul<-V2ueB#2}{u2*u1V0WqXJF2#L`W8*La8=CiSl!Qjda~pD3{8 z{^+tO`y6^YGB}LXWfOxfaWt+}-^;ks4(IxFzyqtggAPX8yJ_{T12tSj6lF2ot(n2m zI9EZ{X*WCQ*=Tn5WQruSNh<>xAa@*WH+OfMo12GQ?RG~SBVpHqkZ%8fYrDGMv|%Xv zZfXC4KR{Bg?aJ5_Em4ca3If(idkL&@0TluwX)E^YcRw8mNIGrWTh-hI$FZ+{kMBJP z1?AA{3Z{AR>8xahM|cAS8NEkc1Rp=QTW17Dk<9{jWy8&qXn+`=n9YL>|GUNi!m7V+ zUyvdriq>s$4x$dx3bWTmRwUI6exCCeR~x}um>8Y9x5q>}a>}rRXOz}V8%XA0<_ruN zRtbkZ|4Iyef-UqYJ>q|{{=W0uv=~mWTH#eoXnZ*ahJk}c9VJsf_5EA+g<_8fzfc)o z9IILgRY5qi&>(mxOk}s-m@*HEAN4;Esugt zIWR85;{I$8FFre=!p6jR^q#3+A6rr=D>~2T(^?k|#@fc+%+76TsFhy|e^SqO;8#L-Nt-|LkyP{h~&T{jmsFDua)ld)YIZtf5js10DgD6>G_)H% z#N%l65RKw*(RDPs?RXRy(p2y5x{fw5x<_sdFO?cP1C5orh+Q?RXDa(L3MBp{Vhq0$ zQS+sd0&rgbER_&T zq8_7tC!G-KaCu$xhxj+<(>irvFHi1Z3Gi{v;!t2XOYN%OtDJ%<)wK&Q={?ZHB@g_+ zXH>mN=ym!v@Glr*R+`CKLZYMj`)-++&1-SfgJ;$Qr^Y~Qi1vju7HFKHGTd;VFE(jY zu1cC-lS({fQPWdHyd0000?Oif=?SyNO+OY7^#Y zHUr@@dzyuXj#Qb@K!s)&F8Ux9&UErub(KYnC<$Z#;y7ml6SO|oMHt0?e^Ab%VxrN< zyytn}eWwPiqSSE=QrB7fn_d+>gvLC1Y9Osb(>75j=pdPDzkeRmu(EKnh;@Vsn5kmS zxyGb0P_*Vb9(bOw{`;rF2JgU8K05ILwRbGE5fw+lV*5XNu#&>F{oRJvh6( z8~%EIHM+U0cj4Rm_zJ~0o_C(ELfU+@q2Pgu#!dx6K>X`1i(+%o@5kvhjF)L%9DMlj z!~S3Tb7@V@T1@n%%){cT#Y2BlE-`vRGoE+ITm{VNSg%Q9x5 z2b~eCm3jhdI!d%kbg7Aee-loq6BSqr0azPf6$|=4jtg+~XV563g;v*PvMMw)-QW-( zk2I~xfeJGIqZdxXO@NmU;RA;<-pF`|Nf8x~V_i6J@rxP^HXEPSf)K7p)mK5s)aa8_ zy@^8>T>AKW9zvxA7($@_#{WvE!JbNJ9uT7p5{cGe_klm&=%*-*rzz>9UueN|R#E;D zp5#1Lrgcy+cmEV3_z*tsspBX|*N>OsTDv`&Z|-u@{ZEm8$U8_-D}`2I zIcdY>4$t;MiQWnE)1mY8VsLpoI0rW#4bSm-`1@4H{iE?G&$|dW8=dhiYHmr&;t7g# z9B#(U?#CLe7Zp*OV2$YU&uNrwJv@nYJR^EhvIu%0c)WXBYL)6F0mre*iYNHXd|5SA z;KgJfV!3%dP}jVZYj9^yYhl|DlLhf>M5>-=Gh=BS>1mqHj?y&*RcAaN8l*hnVUKlo zA5C=tojy~+PcQ}8-R#jk?w#sli(Ed)ACqYyRv@1)bwpB=lLV2Tr7-hgVWT6wCMKt1ip-B#?o2zAF_Q(zdtQAcPo<H~3P` z$vy>FXP2M)_;0^|H9EWOP9_PRNrj_9V`|TNR!W8=%CXb^sZjgAF%=}H56_5S1BYeKlF@Jhk z&K9~@l^M*WQF$TwD>y1M8pR_7gKfhI@(Xgb?!je>zo97PTT-tdf@(L2=n>D(7xmxw z&(`#>D%W$MhoZ9C^&FT3oMCxZh52KxXS_VJ!)g#mAx6h~vC@cJ3eoObSk9Y_#WHc9 zW)nRpdIfj9fWab0P#TaV(%B@;46m)NYQ^XuqHM+xs2ZCY5=0Mkf}pQWuh1Uqb^{SB z6s;UBib{!dpz*^D9q<}`hO{fA6;<$WYv7_8DMA%Tv@XS7r4WcVzBW>Hd&V6E=4n{w zmiq;F(M~YVG24mNWV>?$SQn>@XeHcsc>8fQR{Q&J-;&BVRsveMn^x920I6~ z*;n}6`QV*=;Fy!@qrpx65&ou+j&8>{R~N(49X+M*K4QUj5|dS?kp~|y2m3yMLhUbg zQKWu}}vHhj!N9MY!-Qp!MU+2e@`jBT_N6SfI4RM-)=VADeJcl_#9XKTo%m>S}m z4Zbz6J$#o$W>}0?VUF_@*y%%Wn%@)Ivz$!+`|scW`0o4n@80(I ze+<;{c0|StI)h*Bzs0Nf?|XmdH9n5!B6fJ^zkB=r+x_>wAKo(pDZ-+}3E~vi2hia< zE5V2fUfk&EGGPfp?~sl?H791m-s_s2sQPqHpLoZ*EYP0zxiO{V;T^;(-@q>3iFUZ7 zS4p+7V_p`2T&~HsGe2B|%kooAV)iR6b@1c&@BZ^`?=NrdJTGBpEYW!sYX}a*HNu8i z;h)20rt_z889R!hsAhCe$AplWa?gB`spFw9UlBPq*UPv7K-I7)T781im`5u|Z_m;q zfexCKQ9M(K@W~2Kb2=j@tU}gMR3s_NLCm7r zKokpPVO*}hfRhQBtV20|U^SOyG+eALCyIdKvOfuFLBO3d187Z*fbp-vR)l>m!ag0` z3_lP49+;yIQ6zzf_0~@mYPihayiJ>GHmIS83)*gF;qt} zPAaosFV4+bjG_ORasd@QKj6blkGQu-FuzCh=-t2T?e}JJY);e_!0HR1A7F17_$za! zF+xD9jJ{ZgnZCx6qyT`6({R>5P9GBb<3L?R(=5%?d7)0TaI?hv4xUP^+}TVs4rMzD zZF!)6zr`Vtw`vH9#^x^a4LboGuYlQW@kK!wlJbJG{sz}d{W1G)_^=I?bUZl{*Wb5M z?IOeU`LqbREb{(&_?VVO|1!M4&`H_Lh}FKKtFKUe19e=_F@OeIKoK*H1`H7wA7qwb zLje|ZOorLp<1J=J`~{nHy(igY+BS<4Xq zX^f^ZOj19FQ*&@Mj-#Tm2ea8xm`}qQU`SJl2!634-XUXbQ!7c->UIr#%|?)9P2cM{ z-H^KRo8S2mjv1jE>wyg*_>lXftI_aoc=_pUbai<#yuA6FL&BO3JuNe^_JQ;2@R3}= ze=7hEX{?Jlosfn)feM~L7x~vvozq7H02)fC(0%ffu>fGBh)F=ew8y#tms}M=b)L&Ps z+MgO#E#HEp$eSR)pmB48IcV{Cny%CZFq=oppQ0$);pteff;&(iVbdb;Q*;*#Y(7 zZ>&&}u4qF&uhQ+F#m^&{UOppXZ2yxTC^HH zRXS7@UWu46AX*V$|V#h;6s{?edbBHtb#3xIA9L<{YKOwpYvOThSF)t$k2>Qd}j0* zPXf2aOHYD+8zGmb`v zc-Q77`8d&dnZ`v=lAbEMIYkc=wJtT;dEl6wdg7z9;_N1FiLPelCT4KMzTgTcjC35j zVIs2a%KtA_Tf{)68)^~8?)whqYoK1;ps6jlUb_me`En$klK39F2w&8 zhb)6F7hN)Jsyudu$vA*qxlW)uoNT<$)q*@XmUR6C&L?8Gc>oJu)0`OaW`a!R7H7XK09Yf_!IrBU0q zMZ-1qO)B)CBmAZ@2HG^cF|W~e7rkbWN5=b(-I~2-&(G0qjbLkMUugu-(0$Xf^I-GW z-0ucC7|fA#u;0xQIKy!;zMzmASxCdXaj46==3RL@_lN3Ct)DhB_K9z2NMJ~dc)r2rt3mP_PAD_NmEX@ z(xhItTOH(DG8t}6RO6LovV-1MkK0LNFYmRJX0zvuFe$^BjlcLgUZ?YC$hKx)nJS3~ zz0%xwQfC(q(L$W$xwLfaKF!PF_z3Rhm0kdyS1tKlp|pNg(Mo8K>J9Cv)tR6 z2za0_fP4+x`+c&GzD=_82jzScmI5U(7~>)9Tv!k?Nnp|1Xb>^kf+Fj@njK4n@8!4j zCKP5SUP|+@aXNW#oqz54GzoGOFTe(y=`@A9+3E-j7k}$1>8mu~Jk#@-)UjRwO22C7 z4YJMtMYXn?zY5zwPq}4;JJ8!Jnc-(Cw+(UK<~8-tb97rO;8PfvI`EsTrcE?ZvlBki z=G022-#%ljs{cymC~4kMMw$Zu~=1#Dt6Ydle!y!7I<>@&_DstN2zO z`=pciZgk9t_AR_i&Zun=>?X(qW@b8q6wM;^iy<`ufG7&p@*_}%z;M=ybei0|8<%{X|ymvj5uqI9Qe6A&x zp&8?AhV?l8tVvtf!#v6~=ih{}e|4|3ETV%&Yf3;&I9G7)5YPtafmAbUx(6Gx{UcZE zeXo^|XUGb^5|eQPRel{7OZLREE6osopv-bko9o|R9#Ojck`r7HOfH?n09in$zfIiK z>EEX0AE^5%G>J|)o^8~U928(+XE$WtTSzmg zNg>&Q;PP;y|Ecw6$p`m+bW{5*jO>vAuS@;zlO%;!fj^6AWy=)VkZ+$WmGN#?$U1OYjA1MAw{_0@r49kAJr$S1DY79V#<#wRtD_lmD3CuasoXIVP zU-y6_tCZcTT;i6P2;J_q;Cv7wS-xOKXyc#FV1pc*W%?hrk$4B#LK_n z4Yq|M7yrU4jM8P!+nZ9MlUp_9@0qF|U-Es&R5GNwZp107aK~X>S{#~_R)?KwHQn{>dM@-{(e9ZsaVq-~0SGIXxqgY!L_RIkw z=y8QvO-$;(u(+Q&R1ulv?T2bGYLS&NxKz`lE@?^q33xwTNO44Czc?qmS`oDjiLU5C zJK7$AJna(Hotx`n!y^m*M7t>XoJ^Y3e3NWGJ@jgx<-MJR*vs5eu6&F#3M)t8T(69gg5{WNwt9NDix4QFsd%` zG|{Id(Nm)I5wqk+XSw7YyY6^GmPz%EJi89_{DA?GV<%+4Z?ib4{TJRKp_-L4uk@Bp zu=iT2^Ikh$Ue<(bOTCk-Hs-u4x2hDcgGxKF4*4sc<@T(N%&BmUeKwz!M*I{PQ$jl^dQ2oBKNLXF)}g5d7b? zl*e-W+!UgrxqPW`K3w26X4NaWN;jwx*~F&!P~LZ_6IP>hRXlEFnGW}TOO`mas)c27 zqFPJJM51y_`j;v$>0d6oq~AxQWB&K-=E7_e@AR{KM2TgHqGUx8Zn{9S-_h1z! ziG-URb|dU!msm-X8y&*keXN$%IRoq|LH#89F3y)p2`&_j)IB>slJvUqBabu3CLDNV z9b!|8Z}O12DwbaWP1ZkL)H*tEKcZ%GyP;_HTcobH`4Sn(RU`~n)65f}Cu=ZNb1r}RpH zmr`r>1&OtsCkA=yp` zXrR_)9}B7ggDPIYZqa$b_$TSiz-Ht2tX{%S7h<6JY*B3GZ#HQ0p1QWx^FCGQBk%dR z@lLOuu_42wL;r@dXoc{zi@vqQjr7u{SIY>f3oJ|nzlO8C`UHvuw=phK2K*3<*|ZFM z7O5a$wC=7|;yy*MZ(}fX{{YYArxP*mAY?wa2OlF@Bvtl4hb>%MS2fepPSS#@f~YOI z7wo%4yBi(F95@W)Sjy!vkXFvA2`7R?b*iGV@rmZCRI50Y?BsO9ebCS>^fZX~sjlv* z*LiE$7-~jGE~yJ=u5ypjli7qexiEn(djW>KqO>wnSjpDdW{EV63hgv){C2lhDv)#K0D+7dc?kHb z4bHN`qd4UXXSRm2t5hl!8KwU9Gu?_N9ty9c+Lf+7Jd06&GpVXR}`J=ML2!5Fb&O4 zKGHQe1X;^WjB%BJ#5X!boJ+3Pn|VsQOSh#slh6e0B59#!RTl;=hjd{f7-K0omdbvB zpk)-#&BX-l_#g~%zk8c&het+z|RSiY)-aPvYv0>N(Z}VY?MxDgR5q1XV}(# zo(DJw(IJ|u9wdpXU3x$jrX~BQY^qeF4$D?E^z9#48z~$5M)BH7?M-KIT*UT*80~Iy z&HkJ^yk?P~squSZ|NjK}b`262jl4?zkxS{1sx7iD0|0aO zzfx~4z5*$5t_o!!gbxrsQBXIq>jEb9Jbyl&UQ@(9O+zO_0pKe;*Rr?zlq#iVCfCU4cosE6t&wq|1?PP?R zk~Dc-r{z|wnQpeLIFNi$%uu!2%~X@y>R3**^bNvb134|5@J9vYZLvb5&2>0k;gI#R z@`oK19hjF1nCB(>HXU2M{Pl^}34zra z2bm_{p42g(r;7#WrVVp(3O-SI4Nv_c!Kz03E~mvy5B2p-^2)^a*eB7*qL=25Q<@xX zRi>{g8zm)#(oM?EQKz?c;IC zboX)4^LBcec){q-is_2A@Y91iuW(d3oHYI815@41r8IR+laGfBo%?%=f72gwjh4S> zuc-4SV_YswM21Cn1Ba-RmVwMMcRLYq5mg=0ZAX!=VAxo=mK67nTsY+HWqO zI8bd1AK0#-nk|NaV&-&wDYxD+mL>qJha&ef*{0%8X%ulcM!-EB#bHDquANExUt6+k z2tCK*pCm82L__iU(;Dn3#M>DQX!@D7QJ&T>d_vFl1hd7X@U`BK2pj5vRZlgdgCkzPEwy1(< z?kvPY({Qwyg31?S;<=7Xgu-jYtS9YT*Nhut58#gm*}go@7`3NTE#j~!tp8KN9@}fV zjNvj_YR~GI>VmWehO3+=e!q6TV6AlK23`)+w4f}TO^=hrn)hDV+i05ik+{{IwMEUi zbnl)w0E)`^J9GBz^eC;03|W<+W5QB(PEg|9Vdo^o;883WM9fkMVO(GA+4Fv&+?KrC zhhDj!*#||rG;-~%U0qop$*T3wX;FIKhn^d{A`0fJusSeR-w?+4`LtY}QBlOCT}QIiGC9yaMuxr7WF(DTi;UtWEA zm)E$J%d@dYS#@#9@y!>F_??r!RmrJup}2osjpx*)V#t^{VAQIwGuOz5au4v9L2sxb z1_EYps*I=lPC>g2b&Y3!i(}z02p>qw~;H@l3`(b-6z;nZqGxL*l zg(1<@l?~19%ERy)Wt&xH=B~oX?z+gXvdA4(kt{TMDoToFl|ufs*j|f2ngk2be#< zxEud{d^5bbJH0(S9`gSQ1SytH7Ogo-W}@6Ha{(OA1KgJ#3k}gRLU!-=_(g}H@N7u{ z`e6UQtF+`3hoiTA=vCGSSpu#S>|z+3Bgr?C_W+#8nZ=`>lL^f8uUat2>0cQxi3-?2 zow=TrXf^e&(bDyGm8_tRfv**M^Kxd6vi3|+T5|lXnyv2CWRPk$LFW01@^H(!040hj z{6G6YwJ_JoPUJ3m8%|{OR3Vy&E-9%2#n_ai>|tM$`a*}=rqlg-ld$CEPqT&szp@Ao zD87UT^`*2VUOn&s08mQ<1QY-O00;o=OS@d;+^8(QLI42wy#N3l0000^MOai{Q&dGz zQ(rPLGBzzRG%YbTE^TBka$$Gved%%>$&u!NnDHHQr7>%%2U!L1>Lz48vI0;bA>tAW zASI5*kXfieAsbnlwRr#pcJ^)dP4>msKX;EK>j0_I%4~n^jLkGr85tSj;rA84jZVzh zCK@$nUTLyAi<#pYsx311lFE57Yz1bv*@^oT~UbLT?+C=+lW3s4dt0<>Gi_Pf4 z6h$=2O!Tp>o+kWMW~tI?|LpwqPs6TVVWo_bOp!z zSNo?QFOP>O7sHd$#o*#{bmc#VMfGT|59jfKAXH3DHKC73X+Ie{+gnj#a2oXO zz4H2Qo;C4VTii8fGrCB}CeHy`J-BiC)f7=noBUK(w34))R_RT4hqWJMMOs{&e{2H> zhbM!Rz2Vi~=^kz5BG?H(`SPvZ=pv#~JDa7|Bffoila~*h^du(~tIX8ovV*g#H8*qK zX@T{h5EK9k!h+nm{f)Dn_7dFyLclE93~j9rmwj7Z5#X+_1%6la%G_t>p*Jt4Nigb0 z7PorX#;$p2Yr=cMOW4_Mm z|3?oQ%~=BsLE(?)v8_#ocUBC!O`GUf z0FU=_&P+K<cD4T>~>tZ93MV~lL) zRRyHAt22&D)YR5NH2ae)ij5|@bl1FjS1Ov`q6Qoc(gQ! zZu*F@E~cYv+L~u5JQ2-l6~t`vDETlr8AOBe4Pm_L^?J0I4UvtvwBPdP#uS3rLt+W@ z+jO3%MSMV*k&dTCg--PKfKtxK?W+YH94`o*r&^=1g5))rkl}G zIb{xUU~cK7V{=O%&9O;*^oEW_5svmgB>}zuxGv1~ZNZE_8dTS}ghqEwTRnejqrZ+W zhR1{Ry$^>M!;cr2=T{fQy$>gcqrDH`b9$pknwF4XzecAwG8K5*WJX8Sj~cfm#-d+o zjLIC^#=s*n<~kw8j<~_3WriIM=JPzeV_gi;`N-_@0?0d`Z(_2si7(2M=#r%uErU)j zH4t73TAGZw%4`OZ2_f=#6w_kGYSvpGTA~Cda(XST2xlS!TVxb!&*+RHWeU5Z&)#RX zN;g&x$7#E$MedX0LC$WIy8cWZnbU7St^<#q_>&4ZJiKNmuIxo`n{>sS@V}9ivNxF zKx9{+RoS)ql;*9`o$Z?3Obe0%rjlWY#eGR*PTCnkO9!2mbp{-g5%#asLdWW;LDgh; zCO-)#JErYaS(tJEv8BqJWd0&<7+|F4%^`cKh zdH&}%Et;%()MuEt&xd-HnH!?0qDeNxpPB9Br(JqRK*v9c)712AOn6pITc?dOphyI^ zv-sR})>PKup*T4e^a>XKMPA-7uh}ZPc$^!;A9tpLqY0}vIC!gqE^-(mmN!>4Bo(Z= zBJTS&ufGaA*`<}5LO8&74>S+lt61-R*`tHE95{(eb8}PR_gB3R_4J7tKn8xm>)sMg z-j)~*)r6VF*-c979BDon{-)=VpV2%66X|Wd?Ja0tB14GcNqnmw+}rqxR+F-_wxGa? z9%za`;0+MfBqhxpit?TeWTd9^APb`w=m!EMRKPb*p$IrpAWW>B&2u6aQG?7X%GrsM z*FS8(dHuuNcU!%!H_`C&oOLDe*~FvJ0@I+kUj6X;&6^)y{`9u@_O*Kp(hSxF?S_ZE zef8#tcQ0S{wzk|56^DJ+H(2rY%7&OGIb>5uUy<`r0s7R=p!8%|^r)k3@lU<>N?hn`U0`^!p8o!uWwW{(K&fvx!yud$i)4bV}-N zUS6kpe>ZdXK!1{@(_Ztn5k(U=D}98_41jdEDj%Q~scKC~7_2{-B$~J5JgaY`o09F< z$`F*yB!JPy*3UcJ?{>Cd_g=nz`_oT9zxvm$mpfZqvNg~!7&~!;*{lILS%ydae|5uh)NeM(rC(D}#?@1V=ykh~ME0HlbS`R5N8 z7iWF^zfnxQ?17k74OOTnnMza5dU6V_HTpzu^9kq@2+6GaOjJs&f#J@iCj5ukJJvU7 zYbaB}@Fdu4Z<6Q4Pw!ag82*Lz#e`0^cU=}Y88Oeay`eJ~?s-food5EhlB61}nQIc6 zze!|`syxukbu*y>r0NZely)-tP704n}7u!;8Js^C7Xyi^1X1aDRAy zetJIo1#hTbw@)}zl(mTz5NZ?(8a%-gktP1^Z{LTIe+xGMFMmrs&tcVoRl0aIH%}xF zEz0+3mC?`92LVE~OJ_*DuOAKSIq{;svN8miHaDMMl14;^p12ag;m=5Gv%jg_=gIbt z&Y>&U@V@;Los_CAPoh17uu3EQ(^)n*IZg-Ar_qO`R8FC{S+z&t9KCu;yKY38yk=#x zrqKt4eFmaycn?+lQ)Y;@iC0k<1dif&63JGgPcM^Tz2_|nY$yGLPejA2Dyu}c8)Lii zA+bD2_XuQ`&~(|&qo7fjc1VclWDlq`mP5KSin+bX_{SvVsh|faVA)iaN_$w*xJp}S zW=vICL2u+a(8AQwadusmb$QcxL*_3>qrZr5#-6%pFDKlZ{N?zle@eOx{TKczKnH{O zMxWx#8RIsaVs+!(WnhU!=dqYFsvH(27W)kIzHo-rv1xAUJQsB3!wdU>mcc5id*MjD z5RM@*1?{ypDVU~W)l3Ab$s5ZHqC%c&qiE7glk2@%@?)zw?4#9dtFT z9sK5nuBk}xfP#`$@B*xtyunMc6~XLYE8tTVL`^zMM@shdJSEJgPl_?KAg1MKC#rQ+ zD6GYzAO_I;+v=B{G-W9)EP6>`v-HLKp&89Yro^nh6?TFqjsK>Zs0 z0=~+;yd%ab?igkZBF^|ozO>USySag0Ni1SYASd(~Lo(eKO%EIQ3}Zy=&YEVO0@H<( zm(Hf5FOg&uApB!;TJ6j5LmVKm1}=kHOh=#;9yL%Ig*yO2GWO(pP3^i-=;xc6&aa_piBxV5ffa19k* zaM160*Ay+CS4GCH#_f{uqY<7;7y_sVdOIVo^Z<*@^166&vp9nPCeysn%Q1w=U_b7k zmymxfv$_ftf%3RyZqE2VGS@93@ncU}5J{06R$OVMbyPH-TKD7k;(HSCF2ofDsWe;& zXbBkD9aSg&WB`w?{uNC$60RS3;k3*SPQ*N?9yt+L1>Y+%K^P7y*+rcch&h0z67Nvb z*jIRv+#?*o>gS~00vs*z$(2wLLx@apRVV}!Hk`qXprltNeu6)@dtNJIPXt^sD~@7$ zN+#MDp!8X>&K_B|S>mI2dP8JDUSr$eli?(0>)Z3!}-QIb#_3oVwS;rc( z?%!Lj#0j7`Jq?o*JoU((_Qhe*lk`5D3TZNLv;?H16FTRLwS*gNh=z%t^BwHVt4RIm zpsZ#l2cF_ZXD$eSChPZ+C?T`4l9Tpf*9S*jah;KZh&3r6N|;~W0WVmu49|qI_XyTN zbXYgmM9`B^W%onc&YKu=lmff%q`;s9{w7I`{h41W%ee7JT%BHFCMUlVct z$T+3)T|@ks9@Norv>6R9HlxdrJOi0t$|{`IahIpx!iZHmc{doh0xR~H_*aiH1f=&6BU08X4#mOw!7{@c{AXzCauE11EV4Q8L$ukJ|U%* zzZng#n>NimQ?#I_>(2XXZG=Bb^e5u52`!mO#$m!rh`3#|H!jO>>Tx&fuC7`eu!xv!$`u=l}BnbeEat%P~DadFAT+|ACu^|TF zb8uD=y*JF;ECxwbZqXiRdM(tPd!C&Lrm{KA6yga4B(e8llgZ=Yd^0*cq5tz_aycTv zz*;JzUrFc7i2WzWgNwZn39AbGq!xo_o}z@9`Bt)^49_dbE%CR8RL_hYRzaadNx30n zW3K|+)!=!f+q5!gWmYtr)b$+EXbgtejD-cqub30}-1yj z!4uLmNwTKAHWf3X-VhXP3~rcnu=(hYg+9q)4wxYqqdok`#(;%!>7w~Uq?55#MONS-&yT~ZIcjur~+KOs8&sK)my*!yt2 z4cOM~8&WUi3(W#l0CU(x^TMoqiFh_tI?m1{@V12Xa|Fk9aTaupyq@L+xb*QO9X*M#fCsloCGgS1`s{Wo4MeF03M;wgLEOCSp~+o>w$Vlej+G zw_*(3jOsFnH>R_}y)tiSg^nZHSU~Xx!m>X`2$FpT@wu3bE%blJWhT%O@bC(&&#J33 zpJ)~tuk*4X8w$cfkjBHU?xy%y)WRv=mlg77Ec@`e9WF!BYEHuwVhSIIhx*o3vJLEJ)242@G_B!5v!_UBriQCFDvBFwxt|>{2g6zRJ@A_}v2^S`%HM^0J4DA79 zVIeJQbPbY+p{7T@zpZeb_4pg>pY*N~A^SCoz5X~=aInn?G z%2L=@R95O&^X^5&?Q9E=ZMc#uUE2!{UqDxKfP)x; zWJUGGWzuIP?E+^SE7kgCnm3YYFJ%mKJxr#(#b=GChoUcG)N z(}Klool?o6(J$V5 zDR6pft5z5g^Axy>cOtbjEBTxLE3l9;9@fFYr2}ByUUV*|Zk8nCi59{$ zH?pbo%#k)qm{hokD0CEwmT;N}=_$jkV5NpNs^Bv?d#qz@Zp*QyD%H~wBf6`gL8zbG zSf&hLL*Qh#IM0ea3Gujp&Z1WR8WQiIuZWMU1A~A;GI=e=*zl!fYkTX>%ePl}K@osH z40DklyzV|ofi#L^#5E6R-w)HpPjjp>#FdHU=!^4?BLY+ByL;V97wfysu$?ILsr7uu zRx2zP)5l`55`y)zdgaKGPv=cHEo~8emQx8+WdOR5h+TD`=Gnw@owq$CDG=!s+x7J5 ze5256g^!UgBt$wkcO@*8O-r6!`x0@i1Tn|wSXt=TTEVfx$C`?S1Zn32IX5CPXo29| zj)@fMctZ3Fp8c!wuoi`^qeJa|=npPPe*mGgBbJAVt?-4^w9muCFNt_OQzD;kv?oZC zUL*%`RSL^Ncu6sQ69Wk@PyJJHMoGEaw8YBi6`tjy>yIf+O4FEb4wZNf3l7$=*X+HE z%jz>^X~!i>q$?uJVJ>9~bb8P#gVp<#-o+7Ei0VLl;*vzrR-7b2l9UWw(z$YTPev1y9xr=v(ck+Zyw9KJ zs@Q#UMEdr&cM&Ip3oBCK>d-*zb0&A^m_8oHqXu40It4};@C_);@p;)cPAlnXqW=Sy z@kjIcKh;^Ys!YHvz7-QW=y)a!TXW-Rr`@M;nn(yQFjLCe`5}fdWCe&RC_4#E*ErFe1z$)lsk*$7wzZ zI34p%d%7Zb-YiVy$=!YHt;?|u9L{W?b?WSD&hfuu7F6FOOYaWeJPmQK=YKy5Y6AJ; zpK^tb?M;=McBaU)sKpJ=;!_yX8U-7i44fgVF)&e46P|YxWc%)wB;{(G4&m~QFrziN zPs(bhEBEY>(1FmuXw>^7IHQK85))BK&A!_S9S6}OXJV|%H+Cu+vj>Z(TJ#l72r00G z#Jcs^NhaE2ZL)4S)@JUQ&1kosOign~)`yhLAS=|o)OA_QUY`S&*kCTopvH{D>iHGDr$-8icp)hn3|-~Bl1JF{xxw6P+u$kjf}WK;xru1aTUKYug8|l_mPJqb%;b3 zsOjeExVG~GnE|zoP)M-jTya%}PUv*7IZJjyQU=Hs`^z8Y89$ZPopK|U29{22&YV<> zIiSDjl#H!FPUo8M){X(1^2CNC>|8_kk&jGpwDd>f4n@SlfypN`>#CAKIj5B&JxWr` z=B!39*{Pt|sd*~7jKt@bPQtpivAX8XSMUU@COT2_j~U7fQXp|+ApW-y>r7X_7xV)& z4e*OI8pViG3-y)G>1&-Pf$kU*i!E^y)tc?YP8B+sg*x=PfWvv?lP_ndpNHqWhgZYH zlaGVTgR9Z`C-t>&y4*hf9@eU}aAw*mvHXfGi^O?DICYHvD+-VuyJ)Vt1URU8f+3Kf zHN3K9xDqKQqTG3G(!~ZSw2%(_0tHtI5DB_=Yh7c7m}8jl=U()FS@v{h`Gc*rjDU?= zq)%txg3z^v!h2GM9@57cpAy>}>4;=ab1ta~IVbVTN3thu<}$DH-O8derUF&foOb(S zLo7L4{mEp4EJaC;mGt>dkMVY87VOEt%uJI`7`Loy{Vhvr>rFHmLtUqhOBa)l(a?9M za6dGJyFp9qZ{zSi_}5C$H|MgVQfBAPo7dYvExEos-*wpszjoqj#&C(rU`C2ETg#!X zWo=>>JJ$$Mh|lgLd@r#Xi6KdGt~x~Zxyi>nK_s1ZUhi4(#mW*Rv6H6ljwT-y zUruYJj%$(w+usszqw~q~&TD1KtQvd#CpFepeA$+!!pwz$MJa;%FxM=Xz>uvt&ux^%X zZ@Kz!>*tq0yn4CS+x|I0`QHmI5L`M09=yFpgI~Ssy_H!Vi0NVca_fh!?N`0mulSKx zY4cg26M*p27p|#7kTXh);#M5~z+3_m+W`U|*Y!Y?iU6$up?&sKJk6@12|KImG{q7VJs9QnJIgSaMS_CsCwojU1!Blb zpuc|p;pMxn-cMWZIFL?nRTqwdGXmL~HpQ3yVa#EW`YFB5Uo4cRtJ>sR;pjU;g-io| z(qmc@AEbTa6P>Dy%1_Qjsn)#P0` zQaM(T3lm_MMF8s@Q&(HTRngWlM!$ivpAX-|Mm!pDF~`~YDgJXl+)H%adxlY!-89S~ z!$-b)l>k144}lXGIBG>$nQ;`eX1~A9Q+wI<8(Y!32)eYmAxuP!hk+Qt3=`j|%^}pE zhPnK!e1~9L9ZkhM(+l<$+Cu47zQTS`?Jq7I>*w41aDW|y-_Qw5x{d`nJ!4!H4O+#S z3Vu9OiKV0KvLM_&Mi+vDJGY!7s6u;02%)mgFVh1y%Tl+zZ%T{)~A%u*wFDRZ~ZQBFNiq#jD>|ClQ&!a zH^e{WA!jn+=g(#g4?}{Y+z9sMYL()3{PLaeapZg*EDD(E5(Nh>kUDZcD!GLfXH_PP zxp=h*{O*iF6y;0G*t#fqY#*6u_fQRSzfRVQE`rV^Vfqy$_h*~>-3g^i!Prdf$Rhek z?_@$Tel^Z7ZUd@2VUkmaqj#GtARq0ZM2nZgW_Hr^PiaF8e&P3(?;b(TT6(kdt4fjF zOz+CMbOy6l*qn2+Mte#0uib_Zogao$=QuHwcCJ;%e_$(QoYIkS4pp}U2R;ZsrV$Qt zhlU*{Hc`+ZuP4K=gif5b!H?LmbqU`BVLs7#_mB@r-mQJc&!%#XqdkW#nx3jyr$zK> z?UVT6BH+Bf8`8Ob7K~FRp4v`Y2WnAWR$h)=4P{3NGJ8BJaTtCR-21W%493~gHICDoKXyLdEb(hmlc{-E*y?*YGJpYO@Gutc0~#{ zOEY%PotT#G^8VRgOm<4sR!^bbt~R@F)gG@J$2-!DVafD(n@9*`0H6f^+9VK{BJ{?j zX-QFC5Wq1U2kLlwMY!6?#FtLACTIoM{e%{0%)s>UMb9&LkwLzW0lG6z#6>ZeQpo^$ zmkedHx<5n6CfbDTm+15(Q5+Xj$|Rfy{X|09CzhZTR=*^+`N9;clG8lewzKn9E9@O+ zTlfhs_64~Y2Gz_XtO7NT)ID2q*}o_)QkzrVNmX)~y`|A)|2D|mGGE;y!^hL~C@atn zkUriGsfE3&I^~0$ZovAOG6B)eQVFxeR0t$nn6$)7k>nY%&g7&6L9BU#ED4g~fy|yS z)#1|9;)zSBB%?%PYOKcd%IvI?3Sl$M-=gu(PfnrU>@W!zeOCv>&_ywc+{P6gZ0RhJ zm{zlpBo<_uX;P2F-2wM!I*rJxS7TeN}4%WasC0GxhT{l6$J3V9Zv{cYwLUq6 z&cSkqQmaX5wC5rBk&r(h>E2?_7&k&$=?W-V?# zc~$r5w^dthLY~hSMYtLCsSJW?S=d$fO%QtJLK%I{wH zZ~03V;JxrKH}2f(iOK0;|G0OYX3&vE)74}T_*0fv5-78spE`>2v#R-u5zDG}vQB$< zk5;^6=k$BqlZb6F?8U|x4|nOn(eam#w0qwksXp#C;WWSyMrcmNV54anc5ztZ^W$PU zoL369(neOfio-wuPN0dZG}+&+J8>al)!m>)3 z+cFp5y|rQWXobq>z9uHC>GPy0Xc2#GwKCSBcuAqT#>R(Df~o|IdfGNVR6eKOs^5kS6Koz$fqcF?ZJrzkiPw7$HU!VfVezY$jA+=ogh4?WV@1y ziUvtnjIg(`Qqo~@Q>7Ls`==EG$xWrHc#@JYt^2K==}8hPzicO{{fl1RQiGC?H>0)}rM-x_ zLs6sDQhS?hs?SG$M{5~dpLbYf&>FKR-%i0dkk%$67IOj=%ScJg0~AVD&*x52b#QoV zJf)z+yV_fE|2UgUqFc>n?$XT1wsKVcnZ0VY=CE*^Is1;}M#!ny{wx(vHk1I|yjy?u zZYbZLu`+oI$^c>jlltyf0M5{`g_m96*e${Y?ZDVqJ<WJ?9tl#_E2AeA$vr)#!EXsbs zQ`ri-B(~J&wlR{JUx4!!%N*~9-GJ;PlZHh&4%ZS4-U7@KWMxWx+a@^MoJSLiti^1e z^+yl&OA;k3Beq(+84ac+Hl<04NH(h`qe0#rL;rAh~wz4?KzJWi?cltqR zNY8{&v!05nh-B+;kSGdoZL*`V+mP5it%*mN^KRJB$aeJ^q3U%;-*hgp8-@osb)g+` zo_f)4@9#LEH$6eD{zW!3W!v-*(kyQ)6MsPWdROR8Tp9ij?Gx`@&aUeedMq=3lZ8!o z5|V?Tm;+tU1JG_X`;gCSjnATO{q(xbvdtPJ< zS5Z48Z4Nbi%(q5YUOKgXoEE=c&u;))CLG5_;eJDLIH$>eCYmiDYWJ#Eu=e5SMT+k} zr+}2zBWGjiihySf{))ZqD(`)-C+0@JD-~x$N|P=3i6WaZx5)J)}dpDRHuSuZ}k5|eV>W6AsKpQQJ= zisku1u(0KyYsP_B)cplMvu4l&-&sAXt7mj(Tn>Q8-?b%+O z4-N+JSD8OCgoOhCnNf`Cbz+S=j>SRL9A3aA2y%GP(Ccf8Ok5&`{c=XYMG-o$MzZxf zVK3s~L3^~c2pnpG7s5WbUU*^6Xod|p652eBTkhjgH#~uI*c)!exrVyEw~l$H9X(*q zQ?^UvL;s$zM`lObHAH)#c>W?1_IpUvc8ZpO;!izRSQ)sG1v3)Zs5pTk2a8NQXVC9_ zBz$}#cr=V(#_~vfhrWyAX5@P)YLvnYQ_+)MuEIK*%U=<82pw~VPV$Wu zomGTE$~Nv{L_E^3Adcf%8a)oXEK( z7Y0Q?MvKo0J0va_f41pq!J_QvaZQH)^K!Ir|7jE3l)K@)gr9y66Ld6p#+oU^uhOUn zQ37wu63n$jj`J1AD`tda*85;xZVEzWcKIBw+QHK(xw)}?EKx$KC^6Vs(4rEMIWnCzlekpwBL;T}zf|sCe;R5i7>X?}0|EZEz3Q z*|p0bBK0M+6>ZZn49h&_lt z)Uf`(WbDSc{*VqkM5qo9*RA`a7*s%~2m8SNLzN$RkKfPhXD0BRL5FL0MR1P~>!6ZH?)Y7|sEKu5 zfw)riV$^3XHw`GgFNCht?N-m#;6#I|lC$_Sd`6JbOA&ZKTmnHVUS{Op#-hV$f>}u; zUhF_BHC%fi4iXYT;E@7GUOzZEv#BM{4@itlab7a76#eSwHS@1#vs^Q_#lQg4yR2th z-^2bt*7r0ATATRD6&%5b*Sk)@xy%$J3VQ`Kvls6xA<9EL^}sYRguID>lC~R^j3k_lyt-QLvos z#s)YKNn;1!<2y%Xg(S=LrEJiK3sQnBQu+`Oa1G9NMtixzrZqLBQQv~O!wpNc;B?jr zb6Drl7|PW5Dh>KT9D2nT{D4t9*J8$JhXw5>*N@XPc-eCSk8<4B4f+(+IRYNbK>t*VDLrHE zvecc8{~DaxdP_%T9K$@JlSjJ%6BsIyCfEtw-IY}0mWKtX-Xxr9BR(QuAY% zZOI-P%TM?YW`yXjTj3Ykl4w9UBPBIEo7@qZf-~$;ZwHGGvE8)VHkcZ!#tXPic+lCMv7!IZadT3s$_NuRt zX<^&baQ7vy+k!Yf&@L|FS~`}q9JgG9JIZ7~D1PNa#?a2|gc-bBz}+l#Uf$Mnxgttx z;YWkvf~ne>ixqK+tus2wI-~=uwd{rHI!y0dL*v{&QF8^{ZBL=C=Pu3>6y~g3*Eh;0 zX>i3(U^j}!+qqGQRaC^1ZVWPxOx;cE|M5rWA3y%cNW$ST6b3+c21&1a{f(p=2AgAM zDn7)81RtAvWsjJzS~zr!-RjI%2>N1x`o>3@AX)@N zh#CyhA_<8S$>@w8L>rSKdM|@0BYH`Q5-^7JXFs3z{_xw^zV7GKUeA5qyDu^#y6*`KV2Du*q<*d;xRQN-a?5bVWkvE<{d$xPp-nq03au)N9W(O5hU|VdDtP@96>I+3@eQrU!7D=pN}{Q#MCKa}j$< z*W?0bF4=C*NO%j+TihC9z7%^+I6HyOwPp zg01zSu}=Jw4$_2X{mZ-z;#2@#dyCLFpmNipcz;ss;>1^B>>+K-s=N2 zoUoqLfUDaNGo&@>l^aNisU{hzo#dha(OW>BRx$9{q{h*v`Fe?6B%gk?Pes}I@k?x# zdx|{SnhfYf0G%#lk_UM^lKXQdvo-8g#(eiK^r2I#oyo-wt*g`BN0-R_yar1!7Cmnv^wBTX zKhfd8?D5QO%FA`yqM$(nA*D;|lzUCVV(GJiumyKjj{#xQFk;lXaH%-|wj;pc81g`( z)TIH46LOg7qwC-OIai!q&xUQKnni)BQg1J%-JTvTkTon)MaoU9iJ$th*D zVK3iGd9I}4l0HX%JUm{U-ku9{A%$ISriaRJX@jN&x2erK; zOU}olxznNaOYN7$w$*lC<1tDAhXm3qND8m;=2EgNO?c0T%MQy68wavf5?6&Ede##i zZG#f5s4KKgED-8iPAtZ#c3QMgib&l+rbeZJPJ)@kUA6`F`m0RA=f5LhuZWy3d5$U} zD(Su7O!ps#XU=W5DuITrJh5_{Y;lhQNIKqnzBwZ0e6%k3sb5g>saOAMa;KkWWr(6s zhR~%MZw_x?Vu04(HD@5Jm)H(RL#+_$ka?F-1VB^Q-JyOe=lHX?gk`wku3r46P{KOb z16zfpSCNg(@QwP3+UuKv7fg!?Tkmzsts+`Q9U0jC%Sg$LdL< zd^In4DppLag^z|sQU#c;({ULRlR1d`nD)8ovEY{`M$p)rAEoA?hO|oII2X;MJ=_xK z1v6=G7%;_qNLhgEEB$>*w`mgAZ#k2PvpX>+w;3|iZ08*F>MRxOsXJ*mK;EGW>5B!# zQO1ie$BY<_>91~eVz=uj=hcEZrz$pcN%i@h1MPzoPcpUpvjuY|@q;xZI!l}KC5rEP zdWFlz!F(2lUA$mwsx3w=_p%6*h4o6HQ^rUQF`;1LygeIQqiVuoo(^7HCyX1vBU}4a z*LAU!LNlZ?%!RC1AQLBmSU54#K*J)nwL(`1Swnc&rN|=vbyDLntP@^W+-u!pEDN~w zsq-A)@=TRkeBqwbBt@gr@V>H0h0?&KG^aMIth!2X4T|{k{R|Nm@4im$A(O~6XdB>5 zS#^3>qm__+$&{hAVsmHp>f0wy!6x~2BqcvW151tHZiu&iy~tKKa;m!rJVZ-~Ert%t zZK?1tEIq1=5f>Byp?Wcu8|zH**GF~Jn`djjKl8YTB=O$hK#YIfj+{MFT;xw^bt-sK zd=JEJE^sILAigj9whgG$&v{2_ZnoJ~R18;cS3lxz2XxDhy{bF)x^G1+ms!fk8elKk zv?)TcywF9}57~`$X@YIvuN`SNnO$_)@avdQ;$YI_8%*TQzaKMomEF1`R$v=pV>X@2 z_#U=m^(}L@>H4&SM0%~5GSYU;nCDY|NPs z_JCa$xry1<+Sg=pz$$J1R3fMJ@nE7XK*|KE@gC^2b^8r;wKT`uwQRj|tF=O- z=ydH~rZ+=D);u}a@>C*rr!KP&2GG#)t(Ibn8V^0^`bIul@Ldn3zEbgp-!5)@xbH_Q zOiA73CA8g0t4&7#UZkfsqOrqDqN|gO!KzyyUV(G{LEa`YIh5vJdoj?Eze_xU8wQ4X z!vru|oW@(S(SbuW^Jc|uh7A;5tOnDtnHmPxtS5YN%XyUzjw?ME;&H`U&;#?gW7zGQ zpx5si4&CE1Bsz7sS*u3NFSic+ywP*a*ob>OBAI2{(Qem`qkjA%%h%wo=~Z z#}WJN(jhN;0|38d^B)NbkID@^-rF+>t56#+K=$dqLbp zPJa7$x2AeY_i9GVV;UzQ6YDu~MJtUfiL`usZ;5y38I@*w8^11$+u-_Qzx|Zg<4|=O z30=eQWz1$|T9|i#3Uz@Ik%lKs@!*{XM{gq4i{0KA8#pac8WJa~R|YOh1u|YujLLX3 z3@yPH*}h1>Fwe_+Ol*{eza1QunP z!=82zrcTBJhX**>Snt{02Z}!lZ9FfL7Jk|}{!%8jpD@05>d8F>o4MARkh4pjU{?87&H)F1lohhI<%*=; z=<3Kay=-(!@SJxjz@zF;3d0>IJZqr#G8pD}5TlUq23l%6~{kh)@1N(=j;{vUP*nE4w+Th6*Xh>l)jxS4dg*R1(RB`-8 zZIn9E(6-?;VF5h1bk_kX^xmY%;zclhSLwBxJynQF*v7_B??8V-c_Ut@n%X4{u%weD z;B`er1Yhvo!pwC$mLcf$3q3=JyicC7{1u<-=j(FM61^??uy#%nzYvIB|F$UI&g_5$ zbc0Jemk71;*m+g~rxyeCHXj-f+O$Bfkzd}uXfC`TqgLSrN5ZY?9Ld0?^#ZRH<9a1k z3`NFxM=Tcd64K^kI$s!09+UgOQTG_G-zFtEE<00*nN!iXo}#5?ixwM{eV#X*9ikE$tvFUCJnY;$vdhA#_3_holF{oG4D*m(9|v~&+ZTIDWKiX{ zieR=FKjW zN@+&f+XB2roknEGHovtGOKv6>NkGqP?^H__2yA17eoeS&XEaGR=Z@a#rJ;U}kcf^B zoV^b@k~WAfxAUl2qqw>_C$jvB2dR&Pi#?(A3E2GLVh-p>kC{AQot+O|;FhX^dv5GC1rBASNx#&U$x!%Ea4oFK`Zp;#DUN-D)rCPv z^X$Q@O-WLdK98R6j*xz@yO?G3t^WntOoM&~Jhg@cNYXH;7{%!^T1OpUBU!mAxC- zv^jHZ%7=pH8r9U03-;2l>&aF1-=b1UsVTbj>d5#HvFaC@;h@~`RY3Es3qFS!EHGF@k7|u`8mu&hMs99Y@Q1BDS*v>|H;2Xxw2V?o_ktVT@;VC@zd zTy~Rfiyk;18h}bqv^NS%p*k*W-$V&!7nS?Hd-5d=d_t6 zNrVwMFW88BDIWafj_$|PF3XKyx}}o2I{tytT|QvHy|&3a;z7Q9o5-y_GYHd-o(;)f zeI)%>w9QAdqr$z8jyb0z=~iTH>>CX`YMK)Nib1g%ut1%}>TM~+uqNq2gkAG!4l|cU z3h;zlC98GiROjGE)O626V}lbopByxXq9G7>SPci>->JrzSiuUlh?3lWv>$Hc=ZBve zf;@yoy?)WsWvq)WX;2ywIDA`6A*RFh5Bpme{))XIA!PzEokv_y0-z|gdA5swuJ#20 z-~$Z+Ab9@t&r3yJ8=|eK3|E3YR8!D_=qteubd+@d6^SAFI}+ocR6eOPbLynH{cKVI zKn4f^i2Q+kb^flusmc%GS`c+jI7H!*vbv(0p|:5000 +docs/raw_md_archive/HISTORY_CANONICAL.md.raw ``` -Aktueller Stand vom 2026-05-21: +Die frueheren Original-Volltexte liegen als Wiederherstellungs-Backup hier: ```text -PC-IP im WLAN/Firmennetz: 172.16.9.185 -Lokale Test-URL: http://172.16.9.185:5000 +docs/raw_md_archive/original_history_raws.zip ``` -IP des PCs ermitteln: - -```powershell -ipconfig -``` - -Firewall-Regel einmalig in einer PowerShell "Als Administrator" anlegen: - -```powershell -netsh advfirewall firewall add rule name="TrafagSalesExporter local web 5000" dir=in action=allow protocol=TCP localport=5000 profile=domain,private -``` - -Am 2026-05-21 wurde eine allgemeine Port-5000-Regel angelegt und danach auf alle Firewall-Profile erweitert: - -```text -Regelname: Local Dev Web Port 5000 -Aktiviert: Ja -Profile: Domaene, Privat, Oeffentlich -Protokoll: TCP -Lokaler Port: 5000 -Aktion: Zulassen -``` - -Damit koennen spaeter auch andere lokale Entwicklungsprogramme auf Port 5000 von anderen Firmen-PCs erreicht werden, sofern sie an `0.0.0.0:5000` oder die konkrete PC-IP binden. - -Pruefen: - -```powershell -netsh advfirewall firewall show rule name="TrafagSalesExporter local web 5000" -``` - -Spaeter wieder entfernen: - -```powershell -netsh advfirewall firewall delete rule name="TrafagSalesExporter local web 5000" -``` - -Hinweise: - -- Die Firewall-Regel bleibt nach einem Windows-Neustart aktiv. -- Die Firewall-Regel bleibt normalerweise auch nach Windows-Updates aktiv. -- Da die Regel auf Domaene, Privat und Oeffentlich gilt, ist Port 5000 auch abgedeckt, wenn AlwaysOnVPN oder Windows das Netzwerk nicht als Domaenenprofil erkennt. -- Die App selbst startet nach einem Neustart nicht automatisch; `dotnet run ...` muss erneut gestartet werden. -- Die PC-IP kann sich nach Neustart, WLAN-Wechsel oder DHCP-Erneuerung aendern; dann `ipconfig` ausfuehren und die neue URL weitergeben. -- Der PC muss eingeschaltet bleiben und das PowerShell-Fenster muss offen bleiben. -- Nur im Firmennetz verwenden, nicht oeffentlich freigeben. -- Die lokale Uebergangs-URL ist bewusst HTTP, nicht HTTPS. Fuer diesen temporaeren internen Betrieb reicht das; lokales HTTPS waere moeglich, wuerde aber Zertifikats-/Trust-Aufwand fuer andere PCs verursachen. -- Finance Cockpit und HR KPI bleiben ueber ihre App-internen Logins geschuetzt. -- Wenn ein Finance-User im Buero die App ueber die VPN-IP des Entwicklungs-PCs trotzdem nicht erreicht, liegt es wahrscheinlich am AlwaysOnVPN-/Firmennetz-Routing. Das kann lokal auf dem PC nicht sicher freigeschaltet werden. - -Serverbefund: - -- Der IIS-Server fordert beim HTTPS/TLS-Handshake ein Client-Zertifikat (`RequestedClientCert=True`). -- Dadurch erreichen Requests weder `diag.txt` noch `BiDashboard.dll`. -- Marco/IT muss in IIS die SSL Settings pruefen und Client Certificates auf `Ignore` oder hoechstens `Accept` setzen, nicht `Require`. - -## Adminbereich und Passwortwechsel 2026-05-21 - -Geaendert: - -- Finance Cockpit und HR KPI Login-Masken haben einen Bereich `Passwort ändern`. -- Passwortaenderung verlangt Benutzername, aktuelles Passwort, neues Passwort und Wiederholung. -- Neue Passwoerter muessen mindestens 8 Zeichen haben. -- Gespeichert wird ein SHA-256-Hash in `appsettings.json`, kein Klartext. -- Neuer interner Adminbereich `/admin/sessions`. -- Der Adminbereich hat eine eigene App-interne Sperre `AdminAccess`. -- Adminseite `Aktive Logins` zeigt App-interne HR-/Finance-Entsperrungen seit dem letzten App-Start: - - Bereich - - Login-Name - - IP-Adresse, soweit aus dem Request verfuegbar - - Entsperrt seit - - Zuletzt gesehen -- Hinweis: Da HR und Finance gemeinsame App-Logins verwenden, zeigt die Seite nicht zwingend die echte Person, sondern die verwendete App-Session. -- Standorte-Tabelle zeigt jetzt Icons fuer den Quellentyp: - - Upload-Datei = Manual Excel / CSV - - Cloud Sync = SAP OData - - Storage = HANA / Server - -Initialer Adminzugang: - -```text -Username: admin -Initialpasswort: TrafagAdmin2026! -``` - -Nach erster Nutzung sollte das Adminpasswort ueber die Admin-Loginmaske geaendert werden. - -Verifiziert: - -- `dotnet build .\TrafagSalesExporter.csproj --no-restore --verbosity minimal -p:OutDir=C:\TMP\trafag_out\` -- Ergebnis: Build erfolgreich, nur bestehende MudBlazor-Analyzer-Warnungen zu `Dense` auf vorhandenen Controls. - -## Markdown-Doku und Anwenderdokus nachgezogen 2026-05-20 - -Geaendert: - -- Neue zentrale Markdown-Uebersicht `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` erstellt. -- Markdown-Dateien werden dort als aktuell fuehrend, Detaildoku oder historisch eingeordnet. -- Alte Markdown-Dateien wurden nicht geloescht, weil sie Pruefwerte, Zwischenentscheide und Audit-Spuren enthalten. -- HR- und Finance-Word-Anleitungen wurden visuell ueberarbeitet: - - Titelbereich - - Tabellen - - Hinweisboxen - - eingebettete neutrale Cockpit-Vorschaugrafiken -- Neue Bilddateien: - - `docs/hr_kpi_cockpit_preview.png` - - `docs/finance_cockpit_preview.png` - -Commits: - -- `0bff161 Document HR cockpit feature list` -- `a044040 Improve cockpit user guide documents` - -## Management Analyse auf Finance Summary ausgerichtet 2026-05-20 - -Geaendert: - -- `Management Analyse` hat jetzt einen fuehrenden Reiter `Finance Summary`. -- Die Kennzahlen in diesem Reiter verwenden dieselbe `FinanceRuleEngine` wie das zentrale Excel-Blatt `Finance Summary`. -- Filter fuer Jahr, Land und Waehrung wirken auf das Endergebnis, nicht nur auf eine Rohdatenansicht. -- Die bisherige Management-Tabelle bleibt als separater Rohdaten-/Diagnose-Reiter erhalten. -- Fuer DE 2026 wird kein Fehler mehr geworfen. Da DE/Alphaplan fachlich auf 2025 gezwungen ist, zeigt das Dashboard fuer DE 2026 einen leeren Zustand mit Hinweis. - -Verifiziert: - -- Lokale Probe gegen DB und Excel zeigte, dass die alte `Management Analyse` wegen Rohwerten, anderem Datum und EUR-Umrechnung nicht mit der Finance Summary uebereinstimmte. -- Tests: `dotnet test TrafagSalesExporter.sln --verbosity minimal` mit `77/77` bestanden. - -Commit: - -- `610e771 Add finance summary view and HR guide` - -## HR KPI Cockpit erweitert und Anwenderdokus erstellt 2026-05-20 - -Geaendert: - -- `HR KPI Cockpit` hat einen neuen Reiter `Anleitung` fuer HR-Anwenderinnen. -- Der Datenordner fuer Rexx-/SAP-Dateien ist im Cockpit sichtbar und je Lauf anpassbar; dauerhaft ueber `HrKpi:DataFolder` in `appsettings.json`. -- Dateistatus zeigt jetzt letzte Aenderung, Dateialter und Frischebewertung. -- Neue Auswertungen: Ampeln, Periodenvergleich, Datenqualitaets-Hinweise, Austritte nach Typ/Organisation und Absenzen nach Organisation. -- Managementsicht anonymisiert personenbezogene Details und reduziert die Anzeige auf aggregierte Kennzahlen. -- Print-/PDF-Funktion im Cockpit ergaenzt. - -Anwenderdokus: - -- `docs/HR_KPI_ANLEITUNG_HR_2026-05-20.docx` -- `docs/FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx` - -Verifiziert: - -- Word-Dateien als gueltige DOCX-Pakete geprueft. -- Tests: `dotnet test TrafagSalesExporter.sln --verbosity minimal` mit `77/77` bestanden. - -Commit: - -- `06fb560 Expand HR KPI cockpit and add user guides` - -## Workflow-Konsistenz fuer Keyuser verbessert 2026-05-20 - -Geaendert: - -- Export Dashboard zeigt jetzt Warnungen, wenn aktive Manual-Excel-Standorte noch keine Datei/Pfad hinterlegt haben. -- Nach einem Einzelstandortexport wird darauf hingewiesen, dass die zentrale Excel separat neu erzeugt werden muss. -- Dashboard markiert, wenn seit der letzten zentralen Excel ein Standortexport gelaufen ist. -- Neuer Keyuser-Menuepunkt `Manuelle Importe` fuer DE/UK/ES-artige Excel-/CSV-Quellen: - - Pfad/SharePoint-Referenz pflegen - - Datei hochladen - - Standort aktiv/inaktiv setzen - - Pfad pruefen -- Live-Status startet nicht mehr pauschal mit `HANA Abfrage...`, sondern quellenneutral bzw. fuer Manual Excel/SAP passender. -- Zentrale Excel enthaelt ein neues Blatt `Finance Summary` mit Summen nach Jahr, Land und Waehrung. -- `Management Analyse` ist klarer als Rohdaten-/Plausibilitaetssicht markiert. -- `Soll/Ist Vergleich` ist klarer als verbindliche Finance-Sicht markiert. - -Nachtrag: - -- Unter `Manuelle Importe` gibt es jetzt einen zweiten Reiter `Anleitung`. -- Der Reiter zeigt den Keyuser-Ablauf grafisch: - - Excel bereitstellen - - speichern und aktivieren - - Standort exportieren - - zentrale Excel erzeugen - - Finance pruefen -- Zusatzhinweise markieren die richtige Reihenfolge, den offenen DE-Fachentscheid und dass auf dem Server kein Microsoft Excel benoetigt wird. - -Bewusst nicht geaendert: - -- DE-Fachregel bleibt offen, bis Munir/Finance bestaetigt, welche Kundenlaender/Filter zum offiziellen DE-Ist gehoeren. - -## Keyuser Prozessdoku SVG 2026-05-20 - -Erstellt: - -- `docs/KEYUSER_PROZESSDOKU_2026-05-20.svg` - -Inhalt: - -- Prozess von Vorbereitung ueber Standortexport, zentrale Excel und Finance-Soll/Ist bis Fehlerbehandlung. -- Fokus auf Keyuser-Aktionen in der App: Settings, Standorte, Export Dashboard, Management Analyse, Soll/Ist Vergleich, Logs. -- Enthaltene Fachpunkte: Manual Excel fuer UK/ES/DE, DE Alphaplan, IT-Sonderregel, Finance-Spalten im Endexcel. -- Technische Implementierungsdetails und Testprogramme sind bewusst ausgeklammert. - -## Technische Systemarchitektur SVG 2026-05-20 - -Erstellt: - -- `docs/SYSTEMARCHITEKTUR_TECHNISCH_2026-05-20.svg` - -Inhalt: - -- Laufzeit und IIS-Publish als `BiDashboard.dll` ohne EXE/AppHost. -- Blazor-UI, Authentisierung, Start-/Background-Services. -- Applikationskern: Export-Orchestrierung, Standortexport, Adapter, Transformationen, zentrale Tabelle. -- Datenquellen: SAP HANA/BI1/SAGE, SAP Gateway/OData, Manual Excel/CSV, SharePoint. -- Persistenzmodell mit wichtigsten SQLite-Tabellen. -- Output-/SharePoint-Pfade, Finance-Sonderregeln, HR/Finance-Zugriff und Betriebspruefpunkte. -- Test-/Probeprogramme sind bewusst nicht enthalten. - -## IT Finance-Methode fachlich bestaetigt 2026-05-20 - -Entscheid: - -- Fuer Italien gilt die vom Finance-Leiter bestaetigte Methode. -- `CustomerName` enthaelt `Trafag Italia` wird aus dem IT-Finance-Ist ausgeschlossen. -- Doppelte IT-Zeilen mit leerem `Supplier country` werden nur einmal gezaehlt. -- Diese Regel gilt nur fuer IT. - -Wichtig: - -- Die bisherige Kundenausschluss-Kombination passte 2025 numerisch naeher an den Sollwert, ist aber nicht die belastbare Methode fuer Folgejahre. -- Der 2025-Zufallstreffer wird deshalb nicht als fachliche Regel weiterverwendet. - -Gegen aktuelle DB getestet: - -```text -Soll IT: 7'669'840.00 -Bisherige IT-Summe: 7'669'641.47 -Bisherige Differenz: -198.53 -Trafag Italia Abzug in DB: 6'495.71 -Dubletten-Abzug SupplierCountry leer: 0.00 -Neue fachliche Methode: 7'663'145.76 -Neue Differenz: -6'694.24 -``` - -Umsetzung: - -- `Services/FinanceReconciliationService.cs` -- `Services/ExcelExportService.cs` -- Tests in `TrafagSalesExporter.Tests/FinanceReconciliationServiceTests.cs` - -## IIS Deployment Handoff 2026-05-19 - -Aktueller Deployment-/IIS-Stand wurde hier dokumentiert: - -```text -docs/DEPLOYMENT_IIS_HANDOFF_2026-05-19.md -``` - -Kurzstand: - -- `TrafagSalesExporter` veroeffentlicht jetzt als `BiDashboard.dll`. -- Keine EXE im Publish. -- Publish-Ziel: `\\trch-webapp-bidashboard.trafagch.local\BiDashboard$\`. -- Wahrscheinliche URL: `https://trch-webapp-bidashboard.trafagch.local/BiDashboard/`. -- Diagnose-`web.config` ist aktiv mit `httpErrors Detailed` und `stdoutLogEnabled=true`. -- `logs`-Ordner existiert auf dem Share, blieb nach dem 500 aber leer. -- ACL-Befund: `IIS_IUSRS` hat nur `ReadAndExecute`; App braucht fuer SQLite/logs wahrscheinlich `Modify`. -- Rechte konnten lokal nicht gesetzt werden: `icacls` auf dem Share endete mit `Zugriff verweigert`. - -Naechster Schritt: - -- Server-Spezialist muss App-Pool-Identity bzw. `IIS_IUSRS` mit `Modify` auf Publish-Ordner, `logs` und `trafag_exporter.db*` berechtigen und danach App-Pool neu starten. - -## ASP.NET Publish direkt aus TrafagSalesExporter 2026-05-19 - -Entscheid: - -- `TrafagSalesExporter` bleibt das fuehrende Projekt. -- Das separate `BiDashboard`-Projekt wird fuer den aktuellen Stand nicht benoetigt. -- `TrafagSalesExporter` ist bereits eine ASP.NET/Blazor-Webanwendung (`Microsoft.NET.Sdk.Web`) und kann direkt veroeffentlicht werden. - -Umsetzung: - -- `OutputType=WinExe` wurde aus `TrafagSalesExporter.csproj` entfernt. -- Der `BiDashboard`-Verweis wurde aus `TrafagSalesExporter.sln` entfernt. -- Das Publish-Profil `Properties/PublishProfiles/FolderProfile.pubxml` zeigt auf den Server-Publish-Pfad: - -```text -\\trch-webapp-bidashboard.trafagch.local\BiDashboard$ -``` - -Wichtig fuer Deployment: - -- Die Anwendung wird nicht durch Doppelklick auf eine EXE gestartet. -- Der Server-Spezialist soll die publish-Ausgabe als ASP.NET-Webanwendung/IIS-App betreiben. -- Publish lokal: - -```powershell -dotnet publish .\TrafagSalesExporter.csproj -c Release -``` - -## Finance Cockpit Login und Vergleichsnachtrag 2026-05-19 - -Nach dem Finance-Handoff vom 2026-05-18 wurden noch mehrere Schritte umgesetzt: - -- Haupt-App-Seite `/finance-cockpit/vergleich` wurde an die Logik und Darstellung der FinanceProbe angeglichen. -- Leere Ist-Zeilen ohne belastbaren Ist-Wert werden im Finance-Vergleich ausgefiltert. -- Die verwendeten Berechnungsformeln je Land wurden dokumentiert: - -```text -docs/FINANCE_BERECHNUNGSFORMELN_LAENDER_2026-05-19.md -``` - -- Finance Cockpit erhielt einen separaten Login, unabhaengig vom HR-KPI-Login. - -Technischer Stand Finance-Cockpit-Login: - -- Konfiguration: `FinanceCockpitAccess` in `appsettings.json` -- Benutzer im aktuellen Stand: `finance` -- Passwort ist als SHA-256-Hash gespeichert. -- Finance nutzt ein eigenes Passwort: `Trafag-Finance-Cockpit-2026!`. -- HR-KPI nutzt weiterhin seine eigene `HrKpiAccess`-Konfiguration. -- Umsetzung: - - `Services/FinanceCockpitAccessService.cs` - - `Security/FinanceCockpitAccessOptions.cs` - - `Components/FinanceCockpit/FinanceCockpitUnlockPanel.razor` - - `Components/Routes.razor` - - `Components/Layout/NavMenu.razor` - - Registrierung in `Program.cs` - -AD-/Rollenstand: - -- `Security.Enabled = false` deaktiviert die globale AD-/Rollenpruefung fuer den Moment. -- Die vorhandenen `AccessGroups` und `AdminGroups` bleiben in `appsettings.json` stehen und wurden nicht geloescht. -- Wenn AD/Rollen wieder gelten sollen, `Security.Enabled` auf `true` setzen. -- Finance- und HR-KPI-Sperren bleiben auch bei deaktivierter AD-Pruefung aktiv. - -Relevante Commits: - -```text -8f1b1b8 Align main finance comparison with probe -f855e06 Filter empty actual finance rows -5c654ad Document finance formulas by country -9c544af Protect finance cockpit with login -``` - -## Zentrale Excel Finance-Filter 2026-05-19 - -Die zentrale Laenderdatei `Sales_All_yyyy-MM-dd.xlsx` wurde fuer den CFO-/Finance-Abgleich erweitert. - -Im Blatt `Sales` gibt es rechts einen zusammengehoerigen Finance-Spaltenblock: - -```text -Finance | Year -Finance | Country Key -Finance | Date -Finance | Net Sales Actual -Finance | Currency -Finance | Include -Finance | Source Value Field -``` - -Ziel: - -- Finance kann im zentralen Excel dieselben Ist-Summen erzeugen wie im Testprogramm. -- Es muss nicht geraten werden, ob `Land`, `TSC`, `Sales Price/Value`, `Document Total LC`, `posting date` oder `invoice date` zu verwenden ist. - -Filterregel fuer Finance: - -```text -Finance | Year = 2025 -Finance | Country Key = gewuenschtes Land -Finance | Include = TRUE -Summe ueber Finance | Net Sales Actual -``` - -Nur in der zentralen Datei wird ein zweites Blatt erzeugt: - -```text -Finance Filter Hilfe -``` - -Dieses Hilfsblatt beschreibt die zusammengehoerigen Finance-Spalten und die konkrete Filter-/Summenlogik. - -Verifikation: - -- Build erfolgreich: - -```text -dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_finance_help_sheet\ --verbosity minimal -``` - -- Preview-Excel erzeugt und geprueft: - -```text -.tmp_tools\GenerateConsolidatedPreview\out\Sales_All_2026-05-19.xlsx -``` - -- Gepruefte Blaetter: - -```text -Sales | Finance Filter Hilfe -``` - -- Finance-Spaltenblock im Blatt `Sales`: - -```text -36: Finance | Year -37: Finance | Country Key -38: Finance | Date -39: Finance | Net Sales Actual -40: Finance | Currency -41: Finance | Include -42: Finance | Source Value Field -``` - -- Summenvergleich gegen `FinanceReconciliationService` fuer 2025: - -| Key | Finance-Service | Excel-Finance-Spalten | Status | -| --- | ---: | ---: | --- | -| AT | `3'438'121.37` | `3'438'121.37` | MATCH | -| CH | `43'521'390.82` | `43'521'390.82` | MATCH | -| ES | `3'082'320.18` | `3'082'320.18` | MATCH | -| FR | `1'471'218.44` | `1'471'218.44` | MATCH | -| IN | `750'936'591.38` | `750'936'591.38` | MATCH | -| IT | `7'669'641.47` | `7'669'641.47` | MATCH | -| UK | `3'533'710.09` | `3'533'710.09` | MATCH | -| US | `3'749'865.33` | `3'749'865.33` | MATCH | - -Relevante Commits: - -```text -ebbc5a1 Add finance filter columns to consolidated export -b23f73e Add finance filter help sheet -``` - -## UK_B1 Mapping / FinanceProbe Nachtrag 2026-05-11 - -Anlass: - -- In der FinanceProbe zeigte UK/England fuer `TRUK` nur `395'605.82 GBP` Ist gegen `3'749'865.00 GBP` Soll. -- In den Varianten fehlten weitere sinnvolle Abgrenzungen; sichtbar war nur `Positions-Netto (Sales Price/Value)`. -- Der Standort soll weiterhin `UK_B1` verwenden. - -Technischer Befund: - -- Standort: - - `Land = England` - - `TSC = TRUK` - - `SourceSystem = MANUAL_EXCEL` -- Korrekte Quelle: - -```text -https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1 -``` - -- Lokal waren fuer `TRUK` keine `ManualExcelColumnMappings` vorhanden. -- Der Import lief deshalb ueber die Header-Automatik. -- Die Header-Automatik behandelte `Sales Price/Value` als fertigen Positionswert. -- In der UK-B1-Datei ist `Sales Price/Value` nach aktuellem Befund aber ein Stueckpreis. -- Der Finance-Positionswert muss deshalb berechnet werden: - -```text -[Sales Price/Value] * [Quantity] -``` - -Probe auf den bereits geladenen UK-Daten: - -| Berechnung | Wert | -| --- | ---: | -| Bisher importiert: Summe `SalesPriceValue` | `395'605.82 GBP` | -| Rekonstruiert: Summe `SalesPriceValue * Quantity` | `3'533'348.89 GBP` | -| Soll `check.xlsx` | `3'749'865.00 GBP` | -| Restdifferenz nach Multiplikation | ca. `216'516.11 GBP` | - -Umgesetzte Codeaenderung: - -- `Services/ManualExcelImportService.cs` - - grafische Manual-Excel-Mappings koennen jetzt einfache berechnete Quellen auswerten - - aktuell benoetigte Syntax: - -```text -=[Header A]*[Header B] -``` - - - Konstanten wie `=GBP` bleiben unveraendert gueltig - -- `Services/DatabaseSeedService.cs` - - England/TRUK wird auf den SharePoint-Ordner `Import/Finance/UK_B1` repariert, wenn der alte/falsche Pfad `Import/Finance/England` oder ein leerer Pfad vorhanden ist - - fuer `TRUK` wird ein grafisches Manual-Excel-Mapping geseedet - - wichtigste Zuordnung: - -```text -SalesPriceValue <- =[Sales Price/Value]*[Quantity] -SalesCurrency <- =GBP -DocumentCurrency<- =GBP -CompanyCurrency <- =GBP -PostingDate <- invoice date -InvoiceDate <- invoice date -``` - -- `TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs` - - neuer Test fuer Multiplikationsausdruck im Manual-Excel-Mapping - - prueft, dass `123.45 * 7 = 864.15` als `SalesPriceValue` importiert wird - -Aktueller Verifikationsstand: - -```text -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false --verbosity minimal -``` - -Ergebnis: - -- Tests erfolgreich. -- `59/59` Tests gruen. -- Bekannte Warnungen bleiben die bestehenden MudBlazor-Analyzerwarnungen zu `Dense`. - -Zusatzfix: - -- `DatabaseSeedService` wurde gehaertet. -- Der UK-Mapping-Seed wird nur ausgefuehrt, wenn `ManualExcelColumnMappings` sauber auf `Sites` referenziert. -- Dadurch wird der Initialisierungslauf nicht blockiert, wenn eine bestehende SQLite-DB gerade noch aus alten Reparaturtabellen wie `Sites_repair_old` bereinigt wird. - -Naechster praktischer Schritt: - -- Lokale DB wurde direkt aktualisiert: - - `TRUK` zeigt auf `https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1` - - `TRUK` hat `18` aktive Manual-Excel-Mapping-Zeilen - - `SalesPriceValue <= =[Sales Price/Value]*[Quantity]` -- FinanceProbe wurde auf `http://127.0.0.1:5099` neu gestartet. -- `/finance` antwortet mit HTTP `200`. -- `/run/export/TRUK` wurde angestossen, konnte aber wegen lokaler SharePoint-/Graph-Authentifizierung nicht neu laden: - -```text -ClientSecretCredential authentication failed -Es konnte keine Verbindung hergestellt werden, da der Zielcomputer die Verbindung verweigerte. (127.0.0.1:9) -``` - -Damit gilt: - -- Code, Seed und lokale Mapping-Konfiguration sind vorbereitet. -- Die zentrale Tabelle `CentralSalesRecords` enthaelt fuer UK noch den alten Importstand, bis der SharePoint-Zugriff wieder funktioniert und `TRUK` neu exportiert wird. -- Aktueller alter Zentralstand bleibt deshalb: - - `1'882` Zeilen - - `395'605.82 GBP` Summe `SalesPriceValue` - - rekonstruiert `3'533'348.89 GBP` ueber `SalesPriceValue * Quantity` - -Offen fachlich fuer UK: - -- Nach neuem Export mit Mapping muss die Restdifferenz gegen `check.xlsx` erneut gemessen werden. -- Wenn der Wert bei ca. `3.53 Mio. GBP` liegt, UK-Datei auf Rabatte, Fracht, Nebenpositionen oder eine andere Netto-Spalte pruefen. -- Wenn der Wert auf `3.75 Mio. GBP` steigt, war das Mapping die Hauptursache. - -## Manual Excel/CSV SharePoint-Ordner und Quellordner-Export 2026-05-08 - -Umgesetzte Anpassungen: - -- Manual Excel/CSV Quellen erzeugen nun immer eine neue Exportdatei; die Quelldatei wird nicht als Exportdatei weitergereicht. -- Lokale Manual-Dateien schreiben die neue Exportdatei in denselben lokalen Ordner wie die Quelldatei. -- SharePoint-Manual-Dateien schreiben die neue Exportdatei in denselben SharePoint-Ordner wie die Quelldatei. -- SharePoint-Referenzen ohne Dateiendung werden als Ordner behandelt. -- Bei SharePoint-Ordnern sucht die App die neueste passende Excel-/CSV-Datei fuer den Standort. -- Fuer datierte Dateien wird das Muster `ddMMyy_TSC.xlsx` bzw. `ddMMyy_TSC.csv` ausgewertet. -- Beispiel England/UK: - - Ordner: `https://trafagag.sharepoint.com/sites/WorldwideBIPlatform/Import/Finance/UK_B1` - - `010526_TRUK.xlsx` wird vor `010426_TRUK.xlsx` gewaehlt. - - Falls kein Datum aus dem Dateinamen gelesen werden kann, faellt die Auswahl auf das SharePoint-Aenderungsdatum zurueck. - -Technischer Befund aus den Logs: - -- Spanien konnte die SharePoint-Datei lesen (`4'341` Zeilen), fiel danach aber auf einen ungueltigen lokalen Pfad, weil die URL als lokale Exportdatei behandelt wurde. -- Fehlerpfad war sinngemaess `...\https:\trafagag.sharepoint.com\...\Spain_Sales_2025.csv`. -- Deutschland hatte keinen manuellen Dateipfad hinterlegt. -- England/TRUK zeigte lokal versehentlich auf die Deutschland-Alphaplan-Datei; die lokale DB wurde auf den UK_B1-Ordner korrigiert. - -Codeaenderungen: - -- `DataSourceFetchResult` enthaelt optionale Overrides fuer lokalen Output-Ordner und SharePoint-Zielordner. -- `ManualExcelDataSourceAdapter` erkennt SharePoint-Dateien vs. SharePoint-Ordner und waehlt bei Ordnern die neueste passende Datei. -- `SharePointUploadService` kann den neuesten passenden Datei-Eintrag in einem SharePoint-Ordner aufloesen. -- `SiteExportService` nutzt fuer Manual-Quellen den Quellordner als Zielordner. -- `StandortePageService` erlaubt fuer Manual-Importe nun auch SharePoint-Ordnerreferenzen. -- Standort-UI-Hilfetext wurde entsprechend angepasst. -- `DatabaseSeedService` repariert England/TRUK auf den UK_B1-Ordner, wenn der Manual-Pfad leer ist. - -Letzte technische Verifikation: - -```text -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore --verbosity minimal -``` - -Ergebnis: - -- Tests erfolgreich, `55/55` -- Bekannte MudBlazor-Analyzerwarnungen zu `Dense` bleiben bestehen. - -## FinanceProbe erweitert fuer alle Finance-Referenzen 2026-05-08 - -Umgesetzte Anpassungen: - -- FinanceProbe zeigt nun alle aktiven `FinanceReferences` fuer 2025, auch wenn noch kein aktiver/importierter Standort dazu Daten liefert. -- Damit werden auch Laender wie AT, CH, CN, CZ, GFS, JP, MS, MSA, PL und RU sichtbar als `Keine Daten`, bis Ist-Daten vorhanden sind. -- Zusaetzliche Sektion `Datenabdeckung je Standort`: - - Standort / TSC - - Quellsystem und Anschlussart - - Manual-Datei- oder SharePoint-Pfad - - Aktivstatus - - Anzahl 2025-Zeilen in `CentralSalesRecords` - - Summe `SalesPriceValue` - - Waehrungen - - importierte Periode - - letzter Exportstatus und Hinweis -- Referenzschluessel-Erkennung wurde fuer CH/AT praezisiert: - - `AT`, `AUT`, `Oesterreich`/`Austria` -> `AT` - - `CH`, `CHE`, `Schweiz`/`Switzerland` -> `CH` -- Damit koennen Zeilen aus `ZSCHWEIZ` mit `LAND1 = AT` fachlich Oesterreich zugeordnet werden. - -Verifikation: - -- `Tools/FinanceProbe` Build erfolgreich. -- Haupttests wurden mit separatem Output/Obj-Pfad ausgefuehrt, damit die laufende App nicht stoert. - -## FinanceProbe als KI-Steuerprogramm 2026-05-11 - -Die FinanceProbe ist bewusst als temporaeres Test-/KI-Steuerprogramm erweitert worden. Die produktive Blazor-App bleibt davon getrennt. - -Neue Routen: - -- `/run/export/{siteKey}` - - startet einen Standortexport nach `Id`, `TSC` oder `Land` - - Beispiele: `/run/export/TRUK`, `/run/export/Spanien`, `/run/export/7` -- `/run/export-all` - - startet Export aller aktiven Standorte - - erzeugt danach die zentrale Datei -- `/run/consolidated` - - erzeugt nur die zentrale Datei aus `CentralSalesRecords` - -Nach jedem Lauf zeigt die FinanceProbe eine Run Summary: - -- neue Exportlogs seit Start -- Finance-Abgleich gegen `check.xlsx` -- Datenabdeckung je Standort - -Zweck: - -- Exporte und Finance-Abgleich koennen fuer Tests von der KI per HTTP angestossen werden. -- Die Funktion ist nicht als produktive Bedienoberflaeche gedacht und kann spaeter wieder entfernt werden. - -## Mapper-/Finance-Konfiguration konsolidiert 2026-05-07 - -Umgesetzte Aufraeumarbeiten: - -- Die doppelte SAP-OData/HANA-Mapping-Engine wurde entfernt. -- Neuer gemeinsamer Service: `MappedSalesRecordComposer`. -- `SapCompositionService` und `HanaQueryService.GetMappedSalesRecordsAsync` laden ihre Quellen weiterhin separat, nutzen danach aber denselben Composer fuer: - - Primaerquelle - - Left Joins - - `SapFieldMapping` nach `SalesRecord` - - Konstanten wie `=SAP` / `=HANA` - - Datums-/Zahlenkonvertierung -- Der alte HANA-B1-Pfad fuer `OINV/INV1/ORIN/RIN1` bleibt bewusst bestehen, damit BI1/SAGE ohne grafisches Mapping weiter laufen. -- Die SAP-Mapping-Normalisierung liegt nur noch in `StandorteSapEditorService`; `StandortePageService` ruft diesen Service beim Speichern auf. -- Der tote Parameter im konsolidierten Export wurde entfernt. `ConsolidatedExportService.ExportAsync()` liest eindeutig aus `CentralSalesRecords`. -- Manueller Import erlaubt in UI und Service jetzt `.xlsx` und `.csv`. - -Finance-Konfiguration: - -- Neue Tabelle `FinanceReferences` fuer Soll-/check.xlsx-Referenzen je Jahr. -- Neue Tabelle `FinanceIntercompanyRules` fuer 2nd-party/IC-Erkennung nach `ScopeKey`, Kundennummer oder Namensmarker. -- Budgetkurse 2025 werden in `CurrencyExchangeRates` mit `Notes = Budget 2025` geseedet. -- `FinanceReconciliationService` liest Sollwerte, Budgetkurse und IC-Regeln aus der DB. -- Config-Export/-Import enthaelt jetzt `FinanceReferences` und `FinanceIntercompanyRules`. - -Noch bewusst offen: - -- HANA-B1-Spezialpfad und generischer HANA-Mapper laufen parallel. Das ist aktuell noetig fuer bestehende BI1/SAGE-Standorte ohne Mapping. -- Manual Excel hat weiterhin Header-Automatik und grafisches Mapping. Naechster Aufraeumpunkt waere eine gemeinsame Import-Mapping-Engine. - -Letzte technische Verifikation: - -```text -dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false --verbosity minimal -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore --verbosity minimal -``` - -Ergebnis: - -- Build erfolgreich -- Tests erfolgreich, `52/52` -- Bekannte MudBlazor-Analyzerwarnungen zu `Dense` bleiben bestehen. - -## SAP OData / ZSCHWEIZ / HANA Mapping 2026-05-07 - -Aktueller Entscheid: - -- `ZSCHWEIZ` wird nicht direkt als SAP-HANA-Spezialfall gelesen. -- `ZSCHWEIZ` wird ueber den bestehenden SAP-OData/Gateway-Pfad gelesen. -- Der grafische Quellen- und Feldmapper bleibt dafuer aktiv. -- Feldinfos muessen nicht hart codiert werden, solange der Gateway-Service `$metadata` fuer das EntitySet liefert. - -Quellsystem-Namen wurden zur Entwirrung geschaerft: - -- Code `SAP` bleibt technisch bestehen, DisplayName ist jetzt `SAP OData`. -- Code `SAP_HANA` bleibt fuer direkte HANA-Tabellen/Views bestehen, DisplayName ist jetzt `SAP HANA Tables/Views`. -- Bestehende Konfigurationen bleiben dadurch kompatibel. - -Seed / Vorkonfiguration: - -- Standort `ZSCHWEIZ` / Land `Schweiz/Oesterreich` wird als inaktiver Standort angelegt bzw. repariert. -- `SourceSystem = SAP`. -- Quelle: Alias `Z`, EntitySet `ZSCHWEIZSet`. -- Mapping ist grafisch editierbar und wird auf die Felder der Tabelle `ZSCHWEIZ` gesetzt. -- Die Seed-/Repair-Logik zieht Quelle und Mapping auch bei bereits vorhandener ZSCHWEIZ-Konfiguration nach; manuelles Mapping ist nur noetig, wenn die Gateway-Feldnamen vom erwarteten `ZSCHWEIZ`-Layout abweichen. - -Wichtig fuer die UI: - -1. App neu starten, damit Seed/Repair laeuft. -2. `Settings -> Quellsysteme`: `SAP` sollte als `SAP OData` erscheinen. -3. `Standorte -> ZSCHWEIZ`: - - Quellsystem `SAP OData (SAP)` - - SAP Service URL Override auf den finalen OData-Service fuer `ZSCHWEIZ` setzen, falls die zentrale SAP-URL noch auf `ZPOWERBI_EINKAUF_SRV` zeigt. - - `Entity Sets refreshen`. - - Quelle `Z` soll auf `ZSCHWEIZSet` zeigen. - - `Felder aus Quellen laden`. - - Mapping kontrollieren. - -ABAP / SAP: - -- ABAP-Report liegt in `report.abap`. -- Report fuellt Tabelle `ZSCHWEIZ` aus Buchungskreis `1100` = Schweiz und `1200` = Oesterreich. -- `LAND1` ist Reporting-Land aus Buchungskreis. -- `CUSTOMER_LAND` ist Kundenland aus `KNA1-LAND1`. -- Upsert erfolgt per `MODIFY zschweiz FROM TABLE`. - -Letzte technische Verifikation: - -```text -dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false --verbosity minimal -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore --verbosity minimal -``` - -Ergebnis: - -- Build erfolgreich -- Tests erfolgreich, `50/50` - -## Finance-Abgrenzung: Antworten Andreas 2026-05-07 - -Fachliche Vorgabe nach Rueckmeldung: - -- Net Sales Actuals werden in Hauswaehrung gerechnet. -- Massgebend ist der Nettofakturawert. -- Umrechnung nach CHF erfolgt mit Budgetkursen, nicht mit Tageskursen. -- Umrechnung/Summierung soll pro Artikel bzw. Belegposition erfolgen. -- Indien wird in INR betrachtet. -- Italien wird in Hauswaehrung betrachtet; Intercompany-/2nd-party-Abgrenzung wird separat angeschaut. -- UK wird in GBP betrachtet. -- Gutschriften haben eigene Rechnungsnummern/Rechnungspositionen und sollen ueber Artikelnummern/Positionen behandelt werden. -- Intercompany soll im zweiten Schritt als 2nd-party/3rd-party-Klassifikation pflegbar werden. -- Genannte 2nd-party/Intercompany-Indikatoren: Trafag, Magnetic Sense/Magnets Sense, Gesellschaft fuer Sensorik; Nummern/Uebersetzungen koennen je Land abweichen. - -Budgetkurse 2025 fuer CHF-Ausweis: - -```text -USD/CHF = 0.85 -EUR/CHF = 0.95 -GBP/CHF = 1.13 -CHF/INR = 90.91 -CHF/CZK = 25.64 -PLN/CHF = 0.22 -CHF/JPY = 156.25 -``` - -Umsetzung in der FinanceProbe: - -- Auswahl der Ist-Variante bevorzugt nun `Nettofakturawert Hauswaehrung` (`DocTotal - VatSum`). -- `Sales Price/Value` bleibt als Vergleichsvariante sichtbar. -- Zusaetzlicher Kandidat `Nettofakturawert Hauswaehrung -> CHF Budget 2025`. -- Referenz in der Oberflaeche wird als `check.xlsx Sollwert` bezeichnet, nicht mehr als fuehrende Power-BI-Referenz. -- Intercompany-Anzeige wurde fachlich als `2nd-party/IC` beschriftet; Regeln werden jetzt in `FinanceIntercompanyRules` geseedet und per Config exportiert/importiert. - -## Finance Probe / Sales-Abgrenzung - -Ziel der heutigen Arbeit: - -- separate kleine Pruef-GUI fuer Finanz-/Sales-Abgrenzungen bauen -- moeglichst viel Logik aus dem Hauptprogramm wiederverwenden -- verschiedene Summenlogiken pro Land nebeneinander sichtbar machen -- gegen `check.xlsx` vergleichen - -Wichtiges fachliches Verstaendnis nach Klaerung im Chat: - -- `check.xlsx` kommt von Rhino und enthaelt die Soll-Zahlen von Andreas. -- Aus den Landessystemen kommt der Ist-Wert. -- Power BI soll in der fachlichen Kommunikation nicht als fuehrende Referenz genannt werden. -- Ziel ist nicht, zufaellig die passendste technische Variante zu nehmen, sondern je Land/System die fachlich korrekte Abgrenzungslogik zu klaeren. - -## Commit - -Rollback-Commit fuer die Finance-Probe wurde erstellt: - -```text -15dec06 Add finance reconciliation probe -``` - -Dieser Commit enthaelt gezielt: - -- `Services/FinanceReconciliationService.cs` -- `Tools/FinanceProbe/FinanceProbe.csproj` -- `Tools/FinanceProbe/Program.cs` -- DI-Registrierung in `Program.cs` -- Dashboard nutzt den ausgelagerten Finance-Service -- `TrafagSalesExporter.csproj` schliesst `Tools/**` aus dem Hauptprojekt aus -- `TrafagSalesExporter.sln` enthaelt das neue Tool-Projekt - -Andere bereits vorhandene Worktree-Aenderungen wurden nicht mitcommitted. - -## Neues Tool - -Neues separates Probe-GUI: - -```text -Tools/FinanceProbe -``` - -Start: - -```powershell -dotnet run --project Tools\FinanceProbe\FinanceProbe.csproj --urls http://localhost:55417 -``` - -URL: - -```text -http://localhost:55417/finance -``` - -Aktueller Start im Chat: - -- Probe-GUI wurde auf `localhost:55417` gestartet -- HTTP `200` bestaetigt - -Hinweis Netzwerk: - -- Start mit `localhost` ist nur lokal auf dem Laptop erreichbar. -- Andere im Trafag-Netz koennen es so normalerweise nicht ueber Laptop-IP oeffnen. -- Fuer Netzwerkzugriff waere `http://0.0.0.0:55417` noetig. -- Probe-GUI hat aktuell keine Authentifizierung, daher nicht unkontrolliert im Netzwerk freigeben. - -## FinanceReconciliationService - -Neue wiederverwendbare Logik: - -```text -Services/FinanceReconciliationService.cs -``` - -Interface: - -```csharp -IFinanceReconciliationService -``` - -Aktuelle Funktion: - -```csharp -Task> BuildNetSalesReferenceRowsAsync(int year = 2025) -``` - -Logik: - -- liest `CentralSalesRecords` -- filtert Jahr ueber `InvoiceDate`, fallback `ExtractionDate` -- gruppiert pro Referenz-Key/Land -- berechnet Kandidaten: - - `SalesPriceValue` - - `DocTotalFC - VatSumFC` - - `DocTotal - VatSum` -- Belegkopfwerte werden vor Summierung dedupliziert: - - bevorzugt `TSC + DocumentType + DocumentEntry` - - fallback `TSC + DocumentType + InvoiceNumber` -- erkennt aktuell Intercompany nur pragmatisch fuer IT/TRIT anhand bekannter Kunden -- liefert pro Kandidat Wert, Waehrung, IC-Wert, Differenzen - -## FinanceProbe Darstellung - -Die Tabelle zeigt aktuell: - -- Status -- Firma -- gewaehlte Abgrenzung -- Ist-Waehrung -- Ist 2025 -- Referenz-Waehrung -- Referenz -- Excel LC -- Excel CHF -- Excel Power BI -- Excel Status -- Differenz -- Differenz ohne IC -- Waehrung -- Zeilen -- Varianten aufklappbar - -Wichtig: - -- Die Bezeichnung `Power BI` ist in der Probe-Oberflaeche noch sichtbar, weil `check.xlsx` diese Spalte enthaelt. -- Fachlich soll in Kommunikation gegen Andreas aber `check.xlsx` / Soll-Zahl genannt werden, nicht Power BI als fuehrende Referenz. -- Eine sinnvolle naechste UI-Bereinigung waere, die Spalte/Labels in der Probe auf `Excel Sollwert` oder `Rhino Sollwert` umzubenennen. - -## Probe-Output vom 2026-05-04 09:55 - -Zusammenfassung: - -```text -8 Standorte -4 OK -1 Pruefen -3 Keine Daten -Excel-Referenzen gelesen: 17 -``` - -Befunde: - -### CH - -- Keine Ist-Daten -- keine sichtbare Soll-Zahl - -### DE - -- Keine Ist-Zeilen aus Systemdaten -- Soll/LC aus Excel vorhanden: - - Referenz ca. `3'635'923` - - Excel LC `3'635'922.91` - - Excel CHF `3'407'000.00` - -Offen: - -- Quelle fuer DE klaeren -- evtl. MANUAL_EXCEL oder noch nicht exportiert - -### ES - -- Keine Ist-Zeilen aus Systemdaten -- Soll/LC aus Excel vorhanden: - - Referenz ca. `3'102'334` - - Excel LC `3'102'333.61` - - Excel CHF `2'907'000.00` - -Offen: - -- Quelle fuer ES klaeren -- evtl. MANUAL_EXCEL oder noch nicht exportiert - -### FR - -- Status OK -- gewaehlte Abgrenzung: `Sales Price/Value` -- Ist-Waehrung: `EUR` -- Ist: `1'471'218.44` -- Soll/Referenz: `1'471'218.00` -- Differenz: `0.44` -- Zeilen: `1649` - -Befund: - -- FR passt praktisch exakt mit `Sales Price/Value` in EUR. - -Offene Frage an Andreas: - -- Ist `Sales Price/Value` in EUR fuer FR fachlich korrekt? - -### IN - -- Status OK -- gewaehlte Abgrenzung: `Sales Price/Value` -- Ist-Waehrungen: `CHF, EUR, GBP, INR, JPY, USD` -- Ist: `750'936'591.38` -- Soll/Referenz: `750'936'591.00` -- Differenz: `0.38` -- Zeilen: `4000` - -Befund: - -- IN passt rechnerisch fast exakt, aber Waehrungen sind gemischt. - -Offene Frage an Andreas: - -- Ist diese gemischte Summe fachlich korrekt? -- Oder muss nach CHF umgerechnet bzw. nach Waehrung getrennt werden? - -### IT - -- Status Pruefen -- gewaehlte Abgrenzung: `DocTotal - VatSum` -- Ist-Waehrung: `EUR` -- Ist: `11'866'896.53` -- Soll/Referenz LC: `7'669'840.00` -- Differenz: `4'197'056.53` -- Differenz ohne IC: `3'733.67` -- Zeilen: `15883` - -Befund: - -- IT liegt ohne IC-Abzug stark daneben. -- Mit erkanntem IC-Abzug ist die Differenz sehr klein. - -Offene Frage an Andreas: - -- Soll IT mit Intercompany-Abzug gerechnet werden? -- Falls ja: nach welchen Kunden/Kriterien erkennt Finance Intercompany? - -### UK - -- Status OK -- gewaehlte Abgrenzung: `Sales Price/Value` -- Ist-Waehrung: `USD` -- Ist: `3'749'865.33` -- Soll/Referenz: `3'749'865.00` -- Differenz: `0.33` -- Zeilen: `942` - -Befund: - -- UK passt praktisch exakt mit `Sales Price/Value` in USD. - -Offene Frage an Andreas: - -- Ist USD fuer UK korrekt? -- Oder muss fuer offizielles Reporting nach CHF umgerechnet werden? - -### US - -- Status OK -- gewaehlte Abgrenzung: `Sales Price/Value` -- Ist-Waehrung: `USD` -- Ist: `3'749'865.33` -- Soll/Referenz: `3'749'865.00` -- Differenz: `0.33` -- Zeilen: `942` - -Befund: - -- US zeigt denselben Ist-Wert wie UK. -- Das wirkt auffaellig und sollte fachlich/technisch geprueft werden. - -Offene Frage: - -- Welche Quelle und Logik ist fuer US korrekt? -- Ist US im aktuellen System richtig zugeordnet? - -## Word-Datei fuer Andreas - -Erstellt: - -```text -FINANZ_OFFENE_FRAGEN_ANDREAS.docx -``` - -Inhalt: - -- kurze Mail an Andreas -- `check.xlsx` als Soll-Zahl von Andreas/Rhino formuliert -- Power BI fachlich nicht als Referenz genannt -- bisherige Befunde pro Land: - - FR - - IN - - IT - - UK - - US - - DE / ES -- offene Fragen zu: - - Waehrung und CHF-Umrechnung - - Umsatzdefinition - - Periodenabgrenzung - - Gutschriften/Storno - - Intercompany - - Entscheid-Tabelle pro Land - -## Markdown-Datei fuer Andreas - -Erstellt/angepasst: - -```text -FINANZ_FRAGEN_ANDREAS.md -``` - -Aktuelle Formulierung: - -- `check.xlsx` kommt von Rhino und enthaelt Soll-Zahlen von Andreas. -- Landessysteme liefern Ist-Werte. -- offen ist, welche fachliche Logik pro Land/System zur Soll-Zahl fuehren soll. -- Power BI ist nicht mehr als fuehrende Referenz formuliert. - -## Verifikation - -Ausgefuehrt: - -```powershell -dotnet build .\TrafagSalesExporter.csproj --verbosity minimal -dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal -``` - -Ergebnis: - -- Hauptprojekt baut erfolgreich -- FinanceProbe baut erfolgreich -- Tests erfolgreich -- `48/48` Tests gruen - -Bekannte Warnungen: - -- `NU1900` im Probe-Build, weil NuGet-Sicherheitsdaten wegen Netzwerk/nuget.org nicht geladen werden konnten -- bekannte MudBlazor Analyzer-Warnungen zu `Dense` - -## Offene sinnvolle naechste Schritte - -1. In der Probe-UI `Power BI`-Labels fachlich bereinigen: - - z. B. `Excel Sollwert` / `Rhino Sollwert` -2. Andreas' Antworten in eine Konfiguration ueberfuehren: - - Land/System - - Summenlogik - - System-Waehrung - - CHF-Umrechnung ja/nein - - Periodendatum - - IC-Regel -3. DE/ES Quelle klaeren: - - aktuell keine Ist-Daten -4. US/UK Doppelwert pruefen: - - US zeigt denselben Ist-Wert wie UK -5. IT Intercompany-Regel fachlich bestaetigen -6. Wenn Regeln bestaetigt sind: - - Finance-Probe erweitert anzeigen - - spaeter produktiv ins Hauptprogramm uebernehmen - ---- - -## Nachtrag 2026-05-04: Excel-Spaltenmapper fuer manuelle Land-Excel-Dateien - -Ausloeser: - -- Deutschland hat ein eigenes Excel-Beispiel geliefert. -- Das Format entspricht nicht dem bisherigen Standard-Excel-Import. -- Ziel war, nicht fuer jedes Land statischen Spezialcode zu schreiben, sondern die Spaltenzuordnung konfigurierbar zu machen. - -Beispielhafte deutsche Spalten: - -- `Export-Datum` -- `Firma` -- `Belegnummer` -- `Position` -- `ArtikelBezeichnung` -- `Warengruppen-Bezeichnung` -- `Anz. VE` -- `Lieferanten Nummer` -- `Name Lieferant` -- `Land Lieferant` -- `AdressNummer-Kunde` -- `Name Kunde` -- `Land Kunde` -- `Branche` -- `EinstandsPreis` -- `Währung` -- `BestellNummer` -- `NettoPreisEinzelX` -- `NettoPreisGesamtX` -- `Versandbedingung` -- `AdressNummer_V` -- `Belegdatum-Rechnung` -- `BelegDatum Auftrag` -- `ArtikelNummer` - -Wichtige fachliche/technische Interpretation fuer Deutschland: - -- `NettoPreisGesamtX` wird als `SalesPriceValue` verwendet. -- `Währung` wird fuer `SalesCurrency`, `DocumentCurrency`, `CompanyCurrency` und `StandardCostCurrency` verwendet. -- `Belegdatum-Rechnung` wird als `InvoiceDate` verwendet. -- `BelegDatum Auftrag` wird als `OrderDate` verwendet. -- `ArtikelNummer` wird als `Material` verwendet. -- Kommentar-/Info-Zeilen ohne echte Position und ohne Betrag werden beim Import ignoriert. - -## Neue Datenstruktur - -Neue Tabelle / neues Model: - -```text -ManualExcelColumnMappings -Models/ManualExcelColumnMapping.cs -``` - -Felder: - -- `SiteId` -- `TargetField` -- `SourceHeader` -- `IsRequired` -- `IsActive` -- `SortOrder` - -Zweck: - -- Pro Standort kann festgelegt werden, welche Excel-Spalte auf welches internes `SalesRecord`-Feld gemappt wird. -- Konstanten sind moeglich, wenn `SourceHeader` mit `=` beginnt, z. B. `=Manual Excel`. - -## Geaenderte Hauptlogik - -Geaendert: - -```text -Services/ManualExcelImportService.cs -``` - -Neue Logik: - -- Beim manuellen Excel-Import werden zuerst aktive `ManualExcelColumnMappings` des Standorts geladen. -- Wenn Mapping-Zeilen vorhanden sind, wird dieses Mapping verwendet. -- Wenn kein Mapping vorhanden ist, laeuft weiterhin die bisherige statische Standarderkennung. -- Damit bleiben bestehende manuelle Excel-Imports abwaertskompatibel. - -Wichtig: - -- Der Mapper ersetzt nicht die fachliche Finanzlogik. -- Er sorgt nur dafuer, dass fremde Excel-Spalten korrekt in die internen Felder geschrieben werden. -- Welche Summe spaeter fuer Finance gilt, muss weiterhin fachlich entschieden werden. - -## Geaenderte Standort-UI - -Geaendert: - -```text -Components/Pages/Standorte.razor -Services/StandortePageService.cs -``` - -In der Standortbearbeitung fuer manuelle Excel-Standorte gibt es neu: - -- Bereich `Excel-Spaltenmapping` -- Button `Spalten aus Excel laden` -- Button `Auto-Match` -- Button `Mapping hinzufuegen` -- Tabelle mit: - - Zielfeld - - Excel-Spalte / Konstante - - Pflicht - - Aktiv - - Loeschen - -Auto-Match erkennt aktuell u. a. die deutschen Spalten und schlaegt passende Zuordnungen vor. - -## Config-Export / Import - -Geaendert: - -```text -Services/ConfigTransferService.cs -Models/ConfigTransferPackage.cs -``` - -Neu: - -- `ManualExcelColumnMappings` werden im Konfigurationspaket mit exportiert. -- Beim Import werden die Mapping-Zeilen wieder hergestellt. - -Damit kann die Konfiguration spaeter zwischen Umgebungen mitgenommen werden. - -## Datenbank-Schema - -Geaendert: - -```text -Data/AppDbContext.cs -Services/DatabaseInitializationService.SchemaSql.cs -Services/DatabaseSchemaMaintenanceService.cs -``` - -Neu: - -- `DbSet` -- `CREATE TABLE ManualExcelColumnMappings` -- Schema-Wartung legt die Tabelle nachtraeglich an, falls sie in einer bestehenden DB fehlt. -- Beim Loeschen eines Standorts werden dessen manuelle Excel-Mappings mit geloescht. - -## Deutschland lokal eingerichtet - -Am 2026-05-04 wurde Deutschland in der lokalen Datenbank direkt ohne UI eingerichtet. - -Lokale DB: - -```text -C:\Users\koi\source\repos\Ai\TrafagSalesExporter\trafag_exporter.db -``` - -Gefundener/konfigurierter Standort: - -```text -Id=8 -TSC=TRDE -Land=Deutschland -SourceSystem=MANUAL_EXCEL -``` - -Aktive Mapping-Zeilen: - -```text -26 -``` - -Konkrete Zuordnung fuer DE: - -```text -ExtractionDate <- Export-Datum -InvoiceNumber <- Belegnummer -PositionOnInvoice <- Position -Material <- ArtikelNummer -Name <- ArtikelBezeichnung -ProductGroup <- Warengruppen-Bezeichnung -Quantity <- Anz. VE -SupplierNumber <- Lieferanten Nummer -SupplierName <- Name Lieferant -SupplierCountry <- Land Lieferant -CustomerNumber <- AdressNummer-Kunde -CustomerName <- Name Kunde -CustomerCountry <- Land Kunde -CustomerIndustry <- Branche -StandardCost <- EinstandsPreis -StandardCostCurrency <- Währung -PurchaseOrderNumber <- BestellNummer -SalesPriceValue <- NettoPreisGesamtX -SalesCurrency <- Währung -DocumentCurrency <- Währung -CompanyCurrency <- Währung -Incoterms2020 <- Versandbedingung -SalesResponsibleEmployee <- AdressNummer_V -InvoiceDate <- Belegdatum-Rechnung -OrderDate <- BelegDatum Auftrag -DocumentType <- =Manual Excel -``` - -Wichtig fuer Rollback/Umzug: - -- Diese DE-Einrichtung wurde direkt in `trafag_exporter.db` gespeichert. -- Die DB-Aenderung ist kein Git-Commit-Inhalt, weil SQLite-Datenbankdaten normalerweise nicht sauber versioniert werden. -- Der Code fuer den Mapper ist aktuell im Worktree vorhanden, aber noch nicht committed. -- Wenn die DB zurueckgerollt oder neu erstellt wird, muss das DE-Mapping erneut ueber die UI, Config-Import oder ein Hilfsskript eingerichtet werden. - -## Tests - -Ergaenzt: - -```text -TrafagSalesExporter.Tests/ManualExcelImportServiceTests.cs -``` - -Neuer Test: - -```text -ReadSalesRecordsAsync_Uses_Configured_Manual_Excel_Mapping_For_German_Headers -``` - -Der Test prueft: - -- deutsches Excel-Headerformat -- Kommentarzeile ohne echte Position wird ignoriert -- echte Belegposition wird importiert -- `NettoPreisGesamtX` mit Schweizer Tausenderzeichen wird korrekt als Dezimalzahl gelesen -- Waehrung `EUR` wird in Sales-/Document-/Company-Currency uebernommen -- Rechnungsdatum und Auftragsdatum werden korrekt gelesen - -Letzter bekannter Teststand nach Mapper-Arbeit: - -```text -dotnet build .\TrafagSalesExporter.csproj --verbosity minimal -dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal --no-restore -``` - -Ergebnis: - -- Hauptprojekt baut erfolgreich -- FinanceProbe baut erfolgreich -- Tests erfolgreich -- `49/49` Tests gruen - -Bekannte Warnung: - -- `NU1900`, weil NuGet-Sicherheitsdaten wegen Netzwerk/nuget.org nicht geladen werden konnten - -## Aktueller Laufstand - -Die Haupt-App war nach der DE-Konfiguration erreichbar: - -```text -http://localhost:55416/standorte -HTTP 200 -``` - -Hinweis: - -- Der Browser kann geschlossen sein, waehrend der Serverprozess weiterlaeuft. -- Wenn ein Build wegen gesperrter Dateien fehlschlaegt, zuerst den laufenden `TrafagSalesExporter`-Prozess beenden. - -## Noch offen nach Excel-Spaltenmapper - -1. Mapper-Code committen, sobald der aktuelle Stand als Rollback-Punkt gesichert werden soll. -2. In der Standort-UI Deutschland oeffnen und visuell pruefen, ob die 26 Mapping-Zeilen angezeigt werden. -3. Mit echtem DE-Excel einen Importlauf testen. -4. Danach Finance-Probe erneut pruefen: - - ob DE nicht mehr `Keine Daten` ist - - ob `SalesPriceValue` gegen Soll aus `check.xlsx` passt -5. Falls weitere Laender eigene Excel-Formate liefern: - - nicht statischen Code bauen - - neues Mapping pro Standort pflegen -6. Klaeren, ob DE fachlich `NettoPreisGesamtX` in EUR als Ist-Wert verwenden soll oder ob CHF-Umrechnung noetig ist. - ---- - -## Nachtrag 2026-05-05: FinanceProbe Ampel, Spanien v2 und Deutschland-Beispielfile - -### FinanceProbe Management-Ansicht - -Das Testprogramm `Tools/FinanceProbe` wurde fuer das Finance-Meeting erweitert. - -URL lokal: - -```text -http://localhost:55417/finance -``` - -Neue Ansicht: - -- `Meeting Ampel 2025` -- Ampel pro Land: - - Gruen: Zahl passt rechnerisch gegen Referenz - - Gelb: Differenz oder fachliche Abgrenzung offen - - Grau: keine belastbaren Importdaten -- Anzeige pro Land: - - Ist - - Soll / Referenz - - Differenz - - passender technischer Wert - - Waehrung / CHF-Hinweis - - kurze fachliche Begruendung - -Wichtig zur Waehrung: - -- Wenn Quelle `CHF` liefert, kann CHF direkt gezeigt werden. -- Wenn Quelle `EUR`, `USD`, `GBP`, `INR` usw. liefert, ist es Mandanten-/Originalwaehrung. -- CHF-Ausweis braucht dann eine separate FX-Regel bzw. offiziellen Umrechnungskurs. - -### Spanien v2 im Testprogramm - -Spanien wird im FinanceProbe nicht mehr nur als normaler Zentralimport betrachtet. - -Direkter CSV-Check: - -```text -sagespain/v2/Spain_Sales_2025.csv -``` - -Gelesene Werte: - -- Zeilen: `4'341` -- Ist 2025 / `SalesPriceValue`: `3'082'320.18` -- Waehrung: `EUR` -- Soll aus `check.xlsx`: `3'102'333.61` -- Differenz: `-20'013.43` - -Status: - -- Ampel: Gelb / Pruefen -- Grund: Export technisch lesbar, aber Differenz zu `check.xlsx` offen. - -Offen fuer Spanien: - -- korrekte Datumsabgrenzung (`FechaFactura` vs. Alternativen) -- Serien `REG`, `LAT`, `PRO`, `REC` -- Behandlung von Gutschriften / `REC` -- offizielle Sage-Auswertung mit identischem Filter zur Sollzahl - -### Deutschland-Beispielfile - -Neues File im Projektordner: - -```text -DE_Beispiel_Export_Daten.xlsx -``` - -Hinweis: - -- Der Benutzer hatte zuerst `.xls` genannt, vorhanden ist `.xlsx`. -- Das File ist als Beispielfile zu behandeln, nicht als finale Jahresdatei. - -Technischer Check: - -- relevante Spalte: `NettoPreisGesamtX` -- Mapping-Ziel: `SalesPriceValue` -- Betragszeilen: `2` -- Summe `NettoPreisGesamtX`: `8'290.70` -- Waehrung: `EUR` - -Einbau im FinanceProbe: - -- eigener Abschnitt `Germany Excel sample check` -- zeigt Datei, Zeilenzahl, Summe und Referenz aus `check.xlsx` -- markiert explizit, dass die Differenz nur Sample-Charakter hat -- in der Management-Ampel wird Deutschland weiter nicht als OK gewertet, solange kein finaler DE-Jahresexport/import vorliegt - -Fachliche Interpretation fuer Deutschland: - -- Das Mapping funktioniert technisch. -- `NettoPreisGesamtX` kann als Kandidat fuer `SalesPriceValue` gelesen werden. -- Das Beispielfile darf nicht gegen die Jahresreferenz `3'635'922.91` als finale Ist-Zahl verwendet werden. -- Fuer das Meeting ist die Aussage: - - Deutschland-Format ist technisch verstanden. - - Finale DE-Zahl fehlt noch. - - Benoetigt wird ein vollstaendiger DE-Jahresfile 2025 oder ein bestaetigter Importlauf. - -### Verifikation 2026-05-05 - -Ausgefuehrt: - -```text -dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --verbosity minimal --no-restore -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal --no-restore -``` - -Ergebnis: - -- FinanceProbe Build erfolgreich -- Tests erfolgreich -- `50/50` Tests gruen -- Web UI liefert `HTTP 200` -- FinanceProbe enthaelt: - - `Meeting Ampel 2025` - - `Spain CSV direct check` - - `Germany Excel sample check` - -## Financechef-Regeln abgesichert 2026-05-11 - -Umgesetzt: - -- `PostingDate` als eigenes Feld in `SalesRecord` und `CentralSalesRecord`. -- Zentrale SQLite-Tabelle erhaelt `PostingDate` automatisch per Schema-Maintenance. -- HANA-B1 liest `DocDate` als Buchungsdatum und `TaxDate` als Fakturadatum. -- Excel/CSV-Import erkennt `posting date`, `Buchungsdatum` und `LineRegistrationDate`. -- Finance-Abgleich filtert das Jahr nach `PostingDate`, mit Fallback auf `InvoiceDate` und danach `ExtractionDate`. -- Finance-Abgleich bevorzugt Nettofakturawert in Hauswaehrung positionsweise. -- Wenn lokale Belegkopfwerte pro Position wiederholt wirken, wird die Ueberzaehlung erkannt: - - B1-Positionswert `SalesPriceValue` wird dann als Positions-Netto bevorzugt. - - deduplizierter Belegkopfwert bleibt als Kandidat sichtbar. -- Intercompany wird weiterhin separat ausgewiesen und nicht still entfernt. - -Verifikation: - -```text -dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\verify_probe_out\ --verbosity minimal -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false --verbosity minimal -``` - -Ergebnis: - -- FinanceProbe Build erfolgreich. -- Tests erfolgreich: `57/57`. -- Bekannte externe Warnung: NuGet-Sicherheitsdaten konnten wegen fehlendem Zugriff auf `api.nuget.org` nicht geladen werden. -- Lokaler Smoke-Test `/finance`: `HTTP 200`. -- Hinweis: Ein bestehender `dotnet`-Prozess sperrt den normalen FinanceProbe-Build-Output. Der Smoke-Test wurde deshalb ohne Rebuild direkt aus dem vorhandenen Output gestartet. - -## Finance-Entscheide dokumentiert 2026-05-11 - -Neue Doku: - -```text -docs/FINANCE_ENTSCHEIDE.md -``` - -Enthaelt die verbindlichen Financechef-Entscheide: - -- Hauswaehrung ist fuehrend. -- CHF-Umrechnung ueber Budgetkurse. -- Aggregation pro Artikel/Belegposition. -- Net Sales Actuals = Nettofakturawert. -- Jahresabgrenzung ueber Buchungsdatum. -- Gutschriften separat ueber Beleg-/Positionslogik. -- Intercompany/2nd-party separat ausweisen. -- Indien fachlich immer in `INR`. - -## FinanceProbe / UK Nachdokumentation 2026-05-11 - -Ergaenzt in `docs/FINANCE_ENTSCHEIDE.md`: - -- Pruefstand der Finance-Regeln. -- Testergebnis `58/58`. -- UK/England-Befund: - - `TRUK` - - `1'881` geladene Zeilen - - `395'605.82 GBP` Ist - - `3'749'865.00` Soll - - Differenz `-3'354'259.18` - - Interpretation: vermutlich Teilmenge/Monatsfile statt Jahreswert. -- Offener UK-Entscheid: Monatsdateien aufsummieren oder kumulierten Jahresfile lesen. - -Ergaenzt in `docs/PROGRAMM_DIAGRAMME.md`: - -- FinanceProbe-Start und Hinweis zu Console-Logging. -- Hinweis zu DLL-Sperren durch Visual Studio bzw. alte `dotnet`-Prozesse. - -## HR KPI Cockpit und Filterkorrektur 2026-05-13 - -Ergaenzt: - -- Separater HR-KPI-Reiter `/hr-kpi`. -- Dashboard-Tabs fuer Ueberblick, Fluktuation, Absenzen, Zeit/Ferien, Mitarbeitende und Datenstatus. -- Fluktuationsvisuals: Gauge, Funnel, Donut, Organisation-Balken und Monatsbalken. -- Architektur-Cleanup: `HrKpiService` als Fassade, Build-Pipeline in `Services/HrKpi/HrKpiDashboardBuilder.cs`, UI-Tabs in `Components/HrKpi/HrKpiDashboardTabs.razor`. -- Konfigurierbare HR-Dateiquellen ueber `HrKpi` in `appsettings.json`. -- HR-KPI-Regressionstests. - -Korrigiert: - -- `Austrittsjahr` ist jetzt optional. -- Leeres Austrittsjahr bedeutet: alle Austritte. -- Von/Bis-Austritt hat Vorrang vor Austrittsjahr. -- Die Austrittsjahr-Auswahl wird aus den vorhandenen Austrittsdaten aufgebaut. -- `Austrittsjahr` ist beim Start leer statt automatisch aktuelles Jahr. -- Fluktuation nutzt nur vergleichbare Filter auf Mitarbeitenden- und Austrittsdaten. -- Kostenstelle, GLZ und Restferien filtern nicht die Fluktuation, weil die Austrittsdatei diese Felder nicht stabil enthaelt; das Cockpit zeigt dazu einen Hinweis. -- Bei Mehrjahresauswahl wird die Fluktuation als Auswahlwert statt als Jahreswert gefuehrt. -- Fluktuationsvisuals zaehlen distinct nach Personalnummer. -- Fluktuationsraten nutzen nun durchschnittlichen Headcount statt Stichtags-Headcount: Monat, Quartal und Jahr folgen `formeln.docx`. -- Krankenquote nutzt den FTE-Nenner: `Krankheitstage / (FTE * 21 Tage)`. -- Rexx-Austrittsarten mit Umlaut werden korrekt normalisiert: `Kündigung AN` zaehlt als Arbeitnehmerkuendigung, `Kündigung AG` als Arbeitgeberkuendigung-Ausschluss, `Ruhestand` als Pensionierung. - -Nachdokumentation: - -```text -docs/HR_KPI_NACHDOKU_2026-05-13.md -``` - -Verifikation: - -- `dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_app\ --verbosity minimal` -- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_tests\ --verbosity minimal` -- Ergebnis: `69/69` Tests bestanden. -- Kontrollwert `C:\temp\Personalausgeschieden.xlsx`: `104` Austritte total, `42` `Kündigung AN`, `34` `Kündigung AG`, `33` fluktuationsrelevant. -- Kontrollwert neuer Nenner: Avg Headcount 2025 `211.3`, Fluktuation Jahr effektiv `15.6%`. - -## FinanceProbe Finanzchef-Uebersicht 2026-05-13 - -Ergaenzt: - -- Neuer Reiter `Finanzchef Uebersicht` in `Tools/FinanceProbe`. -- Kompakte Soll/Ist-Sicht nur fuer offene Laender. -- Spalten reduziert auf Status, Land, Waehrung, Ist, Soll, Abweichung und Pruefgrund. -- Bestehende Detailtabellen bleiben unveraendert fuer Analyse/Nachvollzug. - -Verifikation: - -- `dotnet build .\Tools\FinanceProbe\FinanceProbe.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_financeprobe\ --verbosity minimal` -- Ergebnis: Build erfolgreich, `0` Fehler. -- Hinweis: `NU1900` wegen nicht erreichbarer NuGet-Sicherheitsdaten im eingeschraenkten Netzwerk. - -## Finance CFO Word-Kurzbericht 2026-05-13 - -Erstellt: - -- `docs/FINANCE_CHEF_SUMMARY_2026-05-13.docx` -- Kurzbericht fuer Finance/CFO mit Kernaussagen und Massnahmen. -- Enthalten: FR, IN, US, AT, ES, UK/EN, DE, CH, IT. -- Ausgeschlossen: GFS und reine 0-/Leer-Faelle ohne operative Aussage. - -Inhaltlicher Fokus: - -- Freigabefaehige Laender: FR, IN, US. -- Kleine/mittlere Klaerung: AT, ES. -- Hohe Prioritaet: UK/EN, DE, CH. -- Kritisch: IT wegen groesster Abweichung und offener Berechnungsart. - -## Finance CFO Word-Kurzbericht Erweiterung 2026-05-15 - -Ergaenzt: - -- Aktuelle Fassung: `docs/FINANCE_CHEF_SUMMARY_2026-05-15.docx` -- Erweiterte Tabellenansicht mit Status, Ist, Soll/Rhino, Abweichung, Pruefquelle, Massnahme und Prioritaet. -- Grafische Ampel-Uebersicht fuer OK/Klaeren/Hoch/Kritisch. -- Prioritaetsgrafik fuer IT, DE, UK/EN, CH, AT/ES. -- Abschnitt `Geprueft gegen` mit Rhino/Andreas `check.xlsx`, FinanceProbe/CentralSalesRecords, Spain CSV, Deutschland-Beispielfile und UK_B1. - -Verifikation: - -- DOCX enthaelt `word/document.xml`. -- Inhalte `Rhino / Andreas check.xlsx`, `Management-Ampel`, `Prioritaetsgrafik` und `Laendertabelle mit Massnahmen` wurden im Dokumentpaket geprueft. - -## Finance Spanien Mailentwurf 2026-05-15 - -Erstellt: - -- `docs/FINANCE_ES_MAIL_ABWEICHUNG_2026-05-15.md` -- Spanischer Mailentwurf zur Abweichung Spanien Net Sales 2025. -- Enthaltene Pruefpunkte: Zeitraum, Serien `REG/LAT/PRO/REC`, Abonos/Credit Notes, Datumslogik und verwendetes Netto-Umsatzfeld. - -## Finance IT und UK Mailentwuerfe 2026-05-15 - -Erstellt: - -- `docs/FINANCE_IT_MAIL_ABWEICHUNG_2026-05-15.md` -- `docs/FINANCE_UK_MAIL_ABWEICHUNG_2026-05-15.md` - -Inhalt: - -- Italien: grosse Abweichung `+7.034.496,29 EUR`, Fokus Berechnungsart, Beleg/Position-Deduplizierung, Intercompany, Credit Notes, Datumslogik und Waehrung. -- UK/England: Restdifferenz `-216,154.91 GBP`, Fokus Jahresvollstaendigkeit, Periodenbereich, Credit Notes, Nettofeld, Discounts/Freight/Charges, 2nd-/3rd-party und Waehrung. - -## Finance Entscheide Extraktion 2026-05-15 - -Erstellt: - -- `entscheide.md` - -Inhalt: - -- Fragen und Entscheide aus der Finance-Abstimmung extrahiert. -- Festgehaltene Kernentscheide: Hauswaehrung je Land, Budgetkurse fuer CHF-Sicht, Berechnung pro Artikel/Belegposition, Nettofakturawert, Buchungsdatum, separate Gutschriftenausweisung und Intercompany/2nd-party als eigenes Auswahlfeld. -- Intercompany-Marker dokumentiert: `MAGNETS SENSE`, `MAGNETIC SENSE`, `TRAFAG`, `GESELLSCHAFT FUER SENSORIK`, `GESELLSCHAFT FUR SENSORIK`. - -## Finance Dokumentgueltigkeit 2026-05-15 - -Erstellt: - -- `docs/FINANCE_WELCHES_DOKUMENT_GILT_2026-05-15.md` - -Festgelegt: - -- Fuehrendes CFO-Dokument: `docs/FINANCE_CHEF_SUMMARY_2026-05-15.docx` -- Alte CFO-Version `docs/FINANCE_CHEF_SUMMARY_2026-05-13.docx` entfernt, weil sie durch die Version vom 2026-05-15 ersetzt wurde. -- Entscheidbasis: `entscheide.md` und `docs/FINANCE_ENTSCHEIDE.md`. - -## Finance Dashboard Todo 2026-05-15 - -Erstellt: - -- `docs/FINANCE_DASHBOARD_TODO_2026-05-15.md` - -Inhalt: - -- Todo-Liste fuer Group Sales Reporting Intranet-Dashboard. -- Priorisierte Punkte fuer CFO-Dokument, offene Laenderabweichungen, Intercompany, Budgetkurse und Berechtigungskonzept. - -## Navigation und HR-KPI-Zugriff 2026-05-15 - -Geaendert: - -- Linke Navigation reduziert: - - Hauptgruppe `Finance Cockpit` - - eigener Hauptpunkt `HR KPI (Login)` -- Bisherige Finance-Seiten liegen als Unterpunkte unter `Finance Cockpit`: - - Dashboard - - Management Cockpit - - Standorte - - Transformationen - - Settings - - Logs -- HR KPI hat eine separate zweite Zugriffssperre mit Name und Passwort. -- HR-Daten werden erst geladen und angezeigt, wenn die HR-KPI-Sperre erfolgreich entsperrt wurde. - -Konfiguration: - -- Abschnitt `HrKpiAccess` in `appsettings.json` -- Benutzer: `hr` -- Passwortvorschlag: `Trafag-HR-KPI-2026!` -- Im Repo ist nur der SHA-256-Hash gespeichert, nicht das Klartextpasswort. - -Verifikation: - -```text -dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_hrlogin\ --verbosity minimal -``` - -Ergebnis: - -- Build erfolgreich. -- 3 bestehende MudBlazor-Analyzer-Warnungen in `Logs.razor`, `Transformations.razor` und `Standorte.razor`. - -## IIS 500 Diagnose und Hosting-Modell 2026-05-20 - -Geaendert: - -- `web.config` fuer IIS auf `hostingModel="outofprocess"` umgestellt. -- `stdoutLogEnabled="true"` bleibt aktiv, Logziel bleibt `.\logs\stdout`. -- `ASPNETCORE_DETAILEDERRORS=true` fuer die temporaere IIS-Fehlerdiagnose gesetzt. -- Ziel: Wenn IIS/ASP.NET Core vor dem App-Start scheitert, sollen eher verwertbare Startlogs entstehen; ausserdem wird die App nicht mehr direkt im IIS Worker-Prozess gehostet. - -Aktueller Stand: - -- Publish-Ordner `\\trch-webapp-bidashboard.trafagch.local\BiDashboard$\` enthaelt `BiDashboard.dll`, `web.config`, `wwwroot`, `runtimes`, `trafag_exporter.db` und `logs`. -- `logs` war trotz aktivem stdout-Logging leer. -- Die veroeffentlichte DLL liess sich vom Publish-Ordner aus starten und brach nicht sofort mit einer Exception ab. -- Remote-Pruefung der installierten .NET-Runtimes per WinRM war nicht moeglich; der Serveradmin muss deshalb am Server pruefen, ob das .NET 8 Hosting Bundle installiert ist. - -Naechste Server-Pruefpunkte: - -- URL `https://trch-webapp-bidashboard.trafagch.local/BiDashboard/diag.txt` testen. -- Wenn `diag.txt` nicht erreichbar ist, stimmt IIS-Anwendung/virtueller Pfad/Binding nicht. -- Wenn `diag.txt` erreichbar ist, aber die App 500 liefert, Windows Event Viewer pruefen: - - Windows Logs > Application - - Quellen: `IIS AspNetCore Module V2`, `.NET Runtime`, `Application Error` -- App Pool pruefen: - - .NET CLR Version: `No Managed Code` - - Pipeline: `Integrated` - - 32-bit Applications: `False` - - Identity muss Modify-Rechte auf Publish-Ordner und `logs` haben. - -## Architekturreview Static/Hardcoding 2026-05-15 - -Erstellt: - -- `docs/ARCHITEKTUR_REVIEW_STATICS_HARDCODING_2026-05-15.md` - -Inhalt: - -- Bewertung der vielen `static`-Methoden im Code. -- Ergebnis: `static` ist fuer kleine zustandslose Helper akzeptabel; problematisch sind fachliche Regeln und grosse Klassen mit zu vielen Verantwortungen. -- Dokumentierte Befunde: - - HR-Testpersonen sind aktuell Code-Regel und sollten in Konfiguration/DB. - - Finance Vergleich ist aktuell fix auf `2025` und Referenztext. - - Hauswaehrungen je Land sollten langfristig in Finance-/Standortkonfiguration. - - Finance-Sollwerte, Budgetkurse und IC-Regeln sind als Seed okay, aber produktiv pflegbar machen. -- Empfehlung: nicht blind alle `static`-Methoden entfernen, sondern zuerst fachlich veraenderbare Regeln auslagern. - -## CFO-Bericht IT/Intercompany Diagnose 2026-05-15 - -Ergaenzt: - -- `docs/CFO_Kurzbericht_270515.docx` -- `docs/FINANCE_DASHBOARD_TODO_2026-05-15.md` - -Inhalt: - -- IT/Intercompany-Diagnose fuer die grosse Italien-Abweichung. -- Marker dokumentiert: `TRAFAG`, `MAGNETIC SENSE`, `MAGNETS SENSE`, `GESELLSCHAFT FUER SENSORIK`, `GESELLSCHAFT FUR SENSORIK`. -- Zahlen: - - IT Ist vor IC-Abzug: `14.704.336,29 EUR` - - IC-/2nd-party-Abzug: `4.397.746,90 EUR` - - IT Ist exkl. IC: `10.306.589,39 EUR` - - Rhino/check.xlsx Soll: `7.669.840,00 EUR` - - Restabweichung nach IC: `+2.636.749,39 EUR` - -Bewertung: - -- Intercompany/2nd-party erklaert einen grossen Teil der IT-Abweichung. -- Restabweichung bleibt offen und muss ueber Summenlogik, Beleg/Position-Deduplizierung, Gutschriften/Storno und weitere lokale IC-Kunden oder Schreibweisen geprueft werden. - -## HR KPI Testpersonen-Ausschluss 2026-05-15 - -Geaendert: - -- Folgende Testpersonen werden zentral aus dem HR-KPI-Dashboard ausgeschlossen: - - Angelina Jolie - - Brad Pitt - - Peter Muster - - ICT Trafag - - Empfanger Reminder / Empfaenger Reminder -- Der Ausschluss erfolgt vor KPI-, Filter- und Tabellenberechnung. -- Betroffen sind aktive Mitarbeitende, Absenzen und Austritte. -- Im Dashboard erscheint eine Notice, wie viele Testpersonen-Zeilen ausgeschlossen wurden. - -Verifikation: - -```text -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_hr_exclusions\ --verbosity minimal -``` - -Ergebnis: - -- 70/70 Tests erfolgreich. -- 3 bestehende MudBlazor-Analyzer-Warnungen in `Logs.razor`, `Transformations.razor` und `Standorte.razor`. - -## KI-Arbeitsanweisung 2026-05-15 - -Erstellt: - -- `persona.md` - -Inhalt: - -- Rolle der KI als Entwicklungs-, Analyse- und Dokumentationswerkzeug. -- Grenzen der KI bei fachlicher Verantwortung, Finance, HR, Datenschutz und Freigaben. -- Arbeitsprinzipien fuer dieses Projekt: bestehende Architektur nutzen, kritisch testen, sauber dokumentieren und offene fachliche Punkte als Pruefpunkte markieren. - -## Navigation in Finance/HR/Admin gegliedert 2026-05-15 - -Geaendert: - -- Linke Navigation neu gegliedert: - - `Finance Cockpit` - - `HR KPI (Login)` - - `Admin` -- Unter `Finance Cockpit` stehen: - - `Export Dashboard` - - `Management Analyse` - - `Soll/Ist Vergleich` -- Unter `Admin` stehen: - - `Standorte` - - `Transformationen` - - `Settings` - - `Logs` -- Seitentitel wurden an die neuen Menuebezeichnungen angepasst. - -Verifikation: - -```text -dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_nav_groups\ --verbosity minimal -``` - -Ergebnis: - -- Build erfolgreich. -- 3 bestehende MudBlazor-Analyzer-Warnungen in `Logs.razor`, `Transformations.razor` und `Standorte.razor`. - -## DE Alphaplan-Excel provisorisch vorbereitet 2026-05-20 - -Geaendert: - -- Deutschland wird beim Start als manueller Excel-Standort vorbereitet: - - `TSC = TRDE` - - `Land = Deutschland` - - `SourceSystem = MANUAL_EXCEL` - - `IsActive = false`, damit der Gesamtexport ohne gesetzte Datei nicht scheitert. -- Alphaplan-Mapping wird fuer Deutschland geseedet: - - `NettoPreisGesamtX` -> `SalesPriceValue` - - `Belegnummer`, `Position`, `ArtikelNummer`, `ArtikelBezeichnung` - - `Warengruppen-Bezeichnung`, `Anz. VE` - - Lieferant/Kunde/Land/Branche - - `Waehrung`, `Versandbedingung`, `AdressNummer_V` - - `Belegdatum-Rechnung` fuer Posting-/Invoice-Date - - `DocumentType = Alphaplan Excel` -- Testdatei erhalten und eingeordnet: - - `docs/2025_DataExport_DE.xlsx` - -Erster Befund: - -- `NettoPreisGesamtX` komplett: `4'154'690.05 EUR` -- `Land Kunde = Deutschland`: `3'455'276.64 EUR` -- `Land Kunde = Deutschland + China`: `3'647'592.44 EUR` -- Sollwert DE: `3'635'923.00 EUR` - -Offen: - -- Finance/Munir muss bestaetigen, welche Kundenlaender und Filter in Alphaplan fuer den offiziellen DE-Istwert gelten. -- Manager-Input nennt Warengruppen- und Versandbedingungs-Codes; im Excel sind aktuell vor allem Bezeichnungen/Texte sichtbar. - -Verifikation: - -```text -dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_de_alphaplan\ --verbosity minimal -``` - -Ergebnis: - -- 75/75 Tests erfolgreich. -- Bestehende Warnungen: NU1900 wegen lokaler Paket-Sicherheitsdatenabfrage, sowie bekannte MudBlazor-Analyzer-Warnungen zu `Dense`. - -## Management Cockpit zentrale Filterkopplung 2026-05-15 - -Geaendert: - -- Die untere `Zentrale Roh-Auswertung` im Management Cockpit ist nicht mehr nur global. -- Neue Filterfelder: `Landfilter` und `TSC`. -- Wenn oben eine Einzeldatei analysiert wird, uebernimmt die zentrale Auswertung automatisch Land und TSC aus dieser Datei. -- Beispiel: Auswahl `USA | TRUS | Sales_TRUS_2026-05-08.xlsx` setzt unten automatisch `USA / TRUS`. -- Button `Global` leert die Filter, falls wieder alle Laender/Standorte ausgewertet werden sollen. -- Jahres-, Monats-, Jahreswerte-, Monatswerte-, Tageswerte-, Quellen- und Laendertabellen verwenden denselben Land/TSC-Filter. - -Verifikation: - -```text -dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_management_scope2\ --verbosity minimal -``` - -Ergebnis: - -- Build erfolgreich. -- 3 bestehende MudBlazor-Analyzer-Warnungen in `Logs.razor`, `Transformations.razor` und `Standorte.razor`. - -## Finance Vergleich als eigener Reiter 2026-05-15 - -Geaendert: - -- `Net Sales Actuals 2025 Referenz` aus dem Start-Dashboard entfernt. -- Neue Seite `Finance Vergleich` unter `Finance Cockpit` angelegt. -- Route: `/finance-cockpit/vergleich` -- Die Seite zeigt den Soll/Ist-Vergleich gegen `check.xlsx` separat, inklusive IC-Abzug, Referenzwert, Summenfeld, Differenz, Waehrung, Zeilen und Status. -- `DashboardPageService` laedt die Finance-Referenzdaten nicht mehr automatisch mit dem operativen Dashboard. - -Verifikation: - -```text -dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false -p:OutDir=.\obj\verify_finance_compare_tab\ --verbosity minimal -``` - -Ergebnis: - -- Build erfolgreich. -- 3 bestehende MudBlazor-Analyzer-Warnungen in `Logs.razor`, `Transformations.razor` und `Standorte.razor`. - -## Finance-Regeln und Dashboard-Basis-Spalte 2026-05-20 - -Geaendert: - -- Neuer Admin-Reiter `Finance Regeln` angelegt. - - Route: `/finance-rules` - - Navigation: `Admin -> Finance Regeln` - - Zugriff wie andere Admin-Seiten ueber `AdminOnly`. -- Neue Tabelle/Model `FinanceRules`. -- Finance-Regeln werden beim Start geseedet und sind danach in der UI pflegbar. -- Die Regeln wirken auf die Finance-Sicht, nicht auf Rohdaten und nicht auf das technische Spaltenmapping. -- DE- und IT-Sonderlogik wurde aus dem zentralen Excel-Export in eine generische Regel-Engine verschoben. -- `ConfigTransferService` exportiert/importiert `FinanceRules` mit. -- `FinanceReconciliationService` nutzt dieselbe Regel-Engine wie das zentrale Excel, damit Soll/Ist-Vergleich und Endexcel dieselbe Finance-Sicht verwenden. -- Export Dashboard: - - neue Spalte `Basis` direkt nach `Land` - - zeigt Datenbasis mit Icon und Text: - - `Excel-Datei` - - `CSV-Datei` - - `SAP Service` - - `Server` - - `Manuelle Datei` - -Aktuelle Default-Finance-Regeln: - -- `DE` - - Jahr auf `2025` erzwingen fuer das Alphaplan-Jahresfile. - - `CustomerName = Trafag AG` ausschliessen. - - `CustomerName contains Magnetic Sense` ausschliessen. - - `InvoiceNumber = GS2510095` ausschliessen, weil bereits 2024 erfasst. - - `InvoiceNumber starts with GS` als negativer Betrag zaehlen. -- `IT` - - `CustomerName contains Trafag Italia` ausschliessen. - - doppelte Zeilen ohne `SupplierCountry` deduplizieren. - -DE-Fachabgleich nach Rueckmeldung Deutschland: - -```text -Gesamtumsatz NettoPreisGesamtX: 4'154'690.05 -- Weiterberechnungen Trafag AG: 391'655.88 -- Weiterberechnungen Magnetic Sense 2025: 55'648.21 -- Gutschriften GS als negativ statt positiv: 28'205.60 doppelte Wirkung -- GS2510095 nicht in 2025: 1'419.70 -= DE Jahresabschluss-Umsatz: 3'652'394.46 -``` - -Verifikation: - -```text -dotnet test TrafagSalesExporter.sln --verbosity minimal -``` - -Ergebnis: - -- 76/76 Tests erfolgreich. - -Echter DE-Import und zentrale Excel erneut geprueft: - -```text -CentralSalesRecords DE 2025 rows: 4'430 -CentralSalesRecords DE 2025 SalesPriceValue: 3'652'394.46 -Central Excel Sales sheet Finance DE 2025 sum: 3'652'394.46 -Central Excel Finance Summary DE 2025 sum: 3'652'394.46 -``` - -Technische Hauptdateien: - -- `Models/FinanceRule.cs` -- `Services/FinanceRuleEngine.cs` -- `Services/FinanceRulesPageService.cs` -- `Components/Pages/FinanceRules.razor` -- `Services/ExcelExportService.cs` -- `Services/FinanceReconciliationService.cs` -- `Services/DashboardPageService.cs` -- `Components/Pages/Dashboard.razor` -- `Data/AppDbContext.cs` -- `Services/DatabaseInitializationService.SchemaSql.cs` -- `Services/DatabaseSchemaMaintenanceService.cs` -- `Services/DatabaseSeedService.cs` -- `Services/ConfigTransferService.cs` - -## Finales zentralisiertes Excel `finall.xlsx` geprueft 2026-05-20 - -Gepruefte Datei: - -- `C:\Users\koi\Downloads\finall.xlsx` - -Ergebnis: - -- Datei ist als zentralisierter Export lesbar. -- Blaetter: - - `Finance Summary` - - `Sales` - - `Finance Filter Hilfe` -- `Sales` enthaelt 67'247 Datenzeilen. -- `Finance Summary` stimmt gegen die Finance-Spalten im Blatt `Sales` exakt: - - Differenz je Land/Jahr/Waehrung: `0.00` -- Die Summen entsprechen der lokal erzeugten zentralen Datei `output\Sales_All_2026-05-20.xlsx`. -- Deutschland 2025 bleibt korrekt: - - `DE 2025 EUR = 3'652'394.46` - -Finance-Summen 2025 aus `finall.xlsx`: - -```text -AT EUR 3'438'121.37 -CH CHF 43'521'390.82 -DE EUR 3'652'394.46 -ES EUR 3'082'320.18 -FR EUR 1'471'218.44 -IN INR 750'936'591.38 -IT EUR 7'663'145.76 -UK GBP 3'533'710.09 -US USD 3'749'865.33 -``` - -Hinweis: - -- Der direkte Vergleich gegen die lokale SQLite-Datei `trafag_exporter.db` war nicht aussagekraeftig, weil diese lokale DB keine passenden `CentralSalesRecords` fuer diesen Stand enthaelt. -- Die Excel-interne Summenpruefung und der Vergleich gegen `output\Sales_All_2026-05-20.xlsx` waren konsistent. - -## Admin Bereich und Startseite aktualisiert 2026-05-21 - -Admin Bereich: - -- `/admin/sessions` ist nicht mehr durch den Finance-Cockpit-Login vorgeschaltet. -- Der Admin Bereich nutzt weiterhin ein eigenes Admin-Passwort über `AdminAccess`. -- Initialer Benutzer: `admin` -- Initiales Passwort: `TrafagAdmin2026!` -- Das Admin-Passwort ist unabhängig vom Finance-Cockpit-Passwort. -- Dokumentation ergänzt: `docs/ADMIN_BEREICH_STARTSEITE_2026-05-21.md` - -Startseite: - -- Corporate-Schrift auf `Open Sans` mit Trafag-nahen Fallbacks angepasst. -- Manometer-Startgrafik bleibt auf weißem Hintergrund, schwarz gezeichnet und mit Trafag-Schriftzug. -- Willkommenstext ist sprachabhängig. -- Optionales Strichmännchen mit Kittel unter dem Willkommenstext ergänzt. -- Das Strichmännchen ist standardmäßig deaktiviert. -- Aktivierung über `Admin Bereich` -> `Strichmännchen anzeigen`. -- Einstellung wird in `appsettings.json` unter `LandingPage.ShowWalkingLabFigure` gespeichert. - -Technische Dateien: - -- `Components/Routes.razor` -- `Components/App.razor` -- `wwwroot/css/app.css` -- `Components/Pages/Dashboard.razor` -- `Components/Pages/AdminSessions.razor` -- `Program.cs` -- `Security/LandingPageOptions.cs` -- `Services/LandingPageSettingsService.cs` -- `Services/UiTextService.cs` -- `appsettings.json` - -## Nachtrag 2026-05-26: Publish-Fixes, HR-KPI-Upload, Varianten und PDF - -Deployment / Blazor: - -- Interaktive Blazor-Server-Render-Mode-Deklarationen fuer die routbaren Seiten ergaenzt, damit Buttons und Formulare auf der publizierten IIS-Seite reagieren. -- Navigation auf relative Links umgestellt, damit die Anwendung unter `/BiDashboard` nicht auf Root-URLs ohne PathBase springt. -- Admin-, Finance- und HR-KPI-Login auf serverseitige POST-Endpunkte mit Unlock-Cookies umgestellt, damit Login auch auf der publizierten Seite ohne Blazor-Click-Event funktioniert. -- SAP-HANA Native DLL `libadonetHDB.dll` wird mitpubliziert und `HDBDOTNETCORE` im `web.config` auf den Publish-Ordner gesetzt. - -HR-KPI: - -- Massenupload fuer die fuenf HR-KPI-Dateien direkt im HR-KPI-Cockpit eingebaut. -- Upload-Ziel auf dem Server: `C:\inetpub\wwwcust\BiDashboard\hrdata`. -- Erwartete Dateien: - - `Saldiperstichdatum.xlsx` - - `Exportkommengehen.xlsx` - - `HR_KPI_Export.xlsx` - - `Abwesenheitinstunden.xlsx` - - `Personalausgeschieden.xlsx` -- Allgemeiner Zeitraumfilter `Von Datum` / `Bis Datum` ersetzt die reine Austrittsbeschriftung. -- Fluktuation nutzt den Zeitraum ueber `Austrittsdatum`. -- Absenzquote nutzt den Zeitraum als Nenner mit Arbeitstagen statt fix `21 Tage`. -- Wenn die Rexx-Absenzen selbst Datumsfelder enthalten, werden Absenzen auf den Zeitraum gefiltert. -- Wenn die Rexx-Absenzen keine Datumsfelder enthalten, wird angenommen, dass `Abwesenheitinstunden.xlsx` bereits fuer den gewaehlten Zeitraum exportiert wurde. -- `MudDatePicker` nutzt explizit `de-CH`, damit Eingaben wie `31.03.2026` auf Server und Browser stabil geparst werden. -- PDF-/Druckbuttons je HR-KPI-Reiter ergaenzt, z. B. fuer `Fluktuation`, `Absenzen`, `Ampel`, `Mitarbeitende` und `Datenstatus`. -- Der Druck/PDF-Export rendert nur den jeweiligen Reiterinhalt inkl. Titel, Datenordner und Filterzusammenfassung. -- Serverseitige HR-KPI-Varianten eingefuehrt: - - Speicherdatei: `C:\inetpub\wwwcust\BiDashboard\hrdata\hr-kpi-variants.json` - - letzte Selektion wird serverseitig gespeichert und beim Oeffnen wieder geladen - - Varianten sind fuer alle Benutzer sichtbar - - Varianten koennen gespeichert, geladen, aktualisiert, umbenannt und geloescht werden -- Initiale Testvarianten fuer HR wurden auf dem Server angelegt: - - `Fluktuation Q1 2026` - - `Fluktuation Jahr 2026` - - `Absenzquote Q1 2026` - -Firewall / Betrieb: - -- Aktueller HANA-Fehler nach DLL-Fix ist Netzwerk/Firewall, nicht mehr SAP-DLL: - - Webserver: `10.120.1.17` - - HANA Internal: `10.194.65.22:30015` - - India HANA: `20.197.20.60:30015` - - SAP OData: `10.194.64.29:8000` - - SharePoint: `trafagag.sharepoint.com:443` -- Support-Mail an externen Support vorbereitet; Freigabe muss vom Webserver zu den Zielsystemen erfolgen. - -Validierung: - -- `dotnet build .\TrafagSalesExporter.csproj --no-restore --verbosity minimal` erfolgreich. -- `dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore --verbosity minimal` erfolgreich mit `78/78` Tests. -- Mehrfach erfolgreich nach `\\trch-webapp-bidashboard.trafagch.local\BiDashboard$\` publiziert. - -## Nachtrag 2026-05-26: Nachdokumentation Remote-/Refactoring-Commits - -Beim Rebase auf `origin/main` wurden zusaetzliche lokal noch nicht vorhandene Commits integriert. Der lokale Stand und `origin/main` sind danach synchron. - -Finance Details / Export: - -- Finanzdetail-Export und erweiterte Uebersetzungen wurden ergaenzt. -- Betroffene Bereiche: - - `Services/ExcelExportService.cs` - - `Services/ConsolidatedExportService.cs` - - `Services/SharePointUploadService.cs` - - `Services/UiTextService.cs` - - `Components/Layout/MainLayout.razor` - - `Components/Layout/NavMenu.razor` -- Tests fuer Excel-Export und UI-Texte wurden erweitert. -- SharePoint-Upload-Schnittstelle wurde leicht angepasst. - -In-App-Training / Anwenderdoku: - -- Neue Trainingsseiten in der Anwendung: - - `Components/Pages/FinanceTraining.razor` - - `Components/Pages/HrKpiTraining.razor` - - `Components/TrainingSection.razor` -- Navigation um Trainingseintraege ergaenzt. -- Neue Trainingsassets: - - `wwwroot/training/systemarchitektur.svg` - - `wwwroot/training/keyuser-prozess.svg` - - `wwwroot/training/finance_cockpit_preview.png` - - `wwwroot/training/hr_kpi_cockpit_preview.png` -- Aktualisierte Anwenderdokumente: - - `docs/FINANCE_COCKPIT_ANLEITUNG_FINANZ_2026-05-20.docx` - - `docs/HR_KPI_ANLEITUNG_HR_2026-05-20.docx` - - `docs/MANUAL_IMPORT_DELTA_STAND_2026-05-21.md` - -Lokaler Dev-Server / Uebergang: - -- `launchSettings.json` wurde fuer den lokalen Uebergang angepasst. -- Doku ergaenzt: - - `docs/LOCAL_DEV_SERVER_UEBERGANG_2026-05-21.md` - - `docs/MD_DOKUMENTENSTATUS_2026-05-20.md` -- Ziel: lokal lauffaehige Umgebung dokumentieren, falls IIS/Publish nicht erreichbar ist. - -Admin / Startseite: - -- Admin-Bereich wurde von Finance-Login getrennt. -- Startseite/Landing-Dashboard und Admin-Sessions wurden erweitert. -- Doku: - - `docs/ADMIN_BEREICH_STARTSEITE_2026-05-21.md` -- Relevante technische Bereiche: - - `Components/AdminAccessPanel.razor` - - `Components/Pages/AdminSessions.razor` - - `Security/AdminAccessOptions.cs` - - `Services/AdminAccessService.cs` - - `Services/AccessSessionTracker.cs` - - `Services/AccessPasswordSettingsWriter.cs` - - `Security/LandingPageOptions.cs` - - `Services/LandingPageSettingsService.cs` - -Trading Engine: - -- Ein Python-Trading-Engine-Paket wurde unter `trade_web` ergaenzt. -- Dateien: - - `trade_web/trading_engine.py` - - `trade_web/trading_engine/__init__.py` -- Zweck laut Commit-Historie: Trading-Cockpit-Engine als importierbares Paket bereitstellen. -- Dieser Bereich ist separat vom TrafagSalesExporter/.NET-BI-Dashboard zu betrachten. - -Aktueller Git-Stand: - -- Rebase auf `origin/main` erfolgreich. -- Neuer Head nach Rebase und Push: `d853f53 Add published HR KPI workflow fixes`. -- `HEAD` und `origin/main` sind synchron. -- Lokal unversioniert bleiben nur Arbeitsartefakte/Screenshots: - - `../BiDashboard/` - - `error.png` - - `it_export_result.html` - - `italien.png` +Nur laden, wenn genaue Chronologie, alte Zwischenstaende, Commit-Historie oder Audit-Spuren benoetigt werden.