# TrafagSalesExporter Handoff Stand: 2026-04-15 ## 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` ## 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`