53 KiB
TrafagSalesExporter Handoff
Stand: 2026-05-05
Nachtrag 2026-05-07 SAP OData / ZSCHWEIZ / Schweiz-Oesterreich
Aktueller Architekturentscheid:
ZSCHWEIZwird ueber SAP OData/Gateway gelesen.- Direkter HANA-Spezialcode fuer
ZSCHWEIZwurde 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, AnschlussartSAP_GATEWAY.SAP_HANA=SAP HANA Tables/Views, AnschlussartHANA.BI1undSAGEbleiben HANA-basierte Quellsysteme.MANUAL_EXCELbleibt Excel/CSV.
ABAP/SAP:
- Datei
report.abapenthaelt ReportZTRAFAG_SCHWEIZ_EXPORT. - Ziel-Tabelle in SAP:
ZSCHWEIZ. BUKRS 1100wird als Schweiz (TRCH,CH) geschrieben.BUKRS 1200wird als Oesterreich (TRAT,AT) geschrieben.CUSTOMER_LANDenthaelt das urspruengliche Kundenland.- Der Report schreibt paketweise per Upsert.
App-Seed:
- Standort
ZSCHWEIZ/Schweiz/Oesterreichwird inaktiv angelegt bzw. repariert. SourceSystem = SAP.- Quelle
Z, EntitySetZSCHWEIZSet. - Quelle und Feldmapping werden beim App-Start per Upsert nachgezogen; eine teilweise vorhandene ZSCHWEIZ-Konfiguration bleibt dadurch nicht leer.
- Initiales Mapping:
Tsc <- Z.TSCLand <- Z.LAND1InvoiceNumber <- Z.VBELNPositionOnInvoice <- Z.POSNRSalesPriceValue <- Z.NETWR_HCSalesCurrency <- Z.HWAERCustomerCountry <- Z.CUSTOMER_LAND
Wichtig fuer naechsten Einstieg:
- Wenn die zentrale SAP-Service-URL noch auf
ZPOWERBI_EINKAUF_SRVzeigt, muss beim StandortZSCHWEIZein Service-URL-Override fuer denZSCHWEIZ-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
50/50erfolgreich.
Nachtrag 2026-05-05 Aktueller Handoff FinanceProbe / Laenderabgleich
Der aktuelle Arbeitsstand fuer den naechsten Einstieg ist der lokale FinanceProbe:
http://localhost:55417/finance
Der FinanceProbe wurde als Meeting-Ansicht erweitert:
Meeting Ampel 2025Detail alle LaenderGermany Excel sample checkSpain 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:
sagespain/v2/Spain_Sales_2025.csv
FinanceProbe liest diese Datei direkt.
Aktueller Stand:
- Zeilen:
4'341 - Ist
SalesPriceValue:3'082'320.18EUR - Soll aus
check.xlsx:3'102'333.61 - Differenz:
-20'013.43 - Status: Gelb / Pruefen
Technisch:
ManualExcelImportServicekann jetzt semikolongetrennte CSV-Dateien lesen.- Spanien-v2-CSV kann damit als
MANUAL_EXCELimportiert werden. - In der Detailtabelle wird Spanien nicht mehr als
Keine Datengezeigt, sondern alsPruefenmit dem v2-CSV-Wert.
Offen fachlich:
- Periodenlogik:
FechaFacturavs. andere Datumsfelder - Serien:
REG,LAT,PRO,REC - Behandlung von Gutschriften /
REC - offizielle Sage-Auswertung mit identischem Filter zur Sollzahl
Deutschland
Vorhandenes Beispielfile:
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.70EUR - 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
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/50Tests 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 - VatSumFCoderDocTotal - VatSumals 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
- Summe
- Belegkopfwerte werden vor dem Summieren per
TSC+DocumentType+DocumentEntrydedupliziert; fallsDocumentEntryfehlt, perInvoiceNumber - Jahr =
InvoiceDate, falls vorhanden, sonstExtractionDate - 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 BIoderLC) - Differenz
- Waehrungen
- Zeilen
- Status
OK,PruefenoderKeine Daten
Verifikation:
dotnet build .\TrafagSalesExporter.csproj --verbosity minimalerfolgreichdotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimalerfolgreich- lokaler Dashboard-Start geprueft:
http://localhost:55416antwortet mit HTTP200
Naechster Bedienablauf, damit die korrekten Summen kommen:
- App starten bzw. offen lassen:
http://localhost:55416 - Im Dashboard neue Daten ziehen:
- entweder
Alle exportieren - oder einzelne Standorte per
Export
- entweder
- Danach
Zentrale Datei neu erzeugenausfuehren. - Oben im Dashboard den Block
Net Sales Actuals 2025 Referenzpruefen. - Entscheidend ist die Spalte
Summenfeld:Sales Price/Value= PositionssummeDocTotalFC - VatSumFC= Netto-Belegsumme in Belegwaehrung, dedupliziert pro BelegDocTotal - VatSum= Netto-Belegsumme in Hauswaehrung, dedupliziert pro Beleg
Status = OKbedeutet: Abweichung zur Referenz maximal 1.Status = Pruefenbedeutet: 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*,DocRateundOADM.MainCurncymuss zuerst neu exportiert werden. - Fuer neue Jahre ist aktuell noch kein dynamischer Referenzjahres-Schalter eingebaut; der harte Referenzcheck ist Stand jetzt auf
2025, weilcheck.xlsxdie 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,AppEventLogsundCentralSalesRecordsnoch 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:
DatabaseSchemaMaintenanceServiceerkennt jetzt nicht nurSites_old, sondern auch alte Reparaturtabellen wieSites_repair_old- betroffene Tabellen werden beim App-Start automatisch neu aufgebaut
AppEventLogServiceundExportLogServicefangen 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 minimalerfolgreichdotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimalerfolgreich
Direkt danach beobachtete Exportfehler:
- Frankreich/Italien/USA:
invalid schema name ... line 40durch HANA-Query-Quoting- Ursache: Query nutzte
"schema"."Tabelle" - Korrektur: wieder
schema."Tabelle"wie im alten funktionierenden Stand
- Ursache: Query nutzte
- 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.StockPricemuss fachlich in der B1-Hauswaehrung bewertet werden- die Hauswaehrung kommt aus
OADM.MainCurncy - bisher wurde
StandardCostCurrencyausp.Currencybzw.h.DocCurabgeleitet - fuer Power-BI-/Cockpit-Gegenpruefung muessen Belegwaehrung, Hauswaehrung, Netto-/Steuerbetraege und Kurs sichtbar sein
Neue Felder in SalesRecord und CentralSalesRecord:
DocumentEntryDocumentCurrencyDocumentTotalForeignCurrencyDocumentTotalLocalCurrencyVatSumForeignCurrencyVatSumLocalCurrencyDocumentRateCompanyCurrency
B1-Feldmapping:
DocumentEntry=OINV/ORIN.DocEntryDocumentCurrency=OINV/ORIN.DocCurDocumentTotalForeignCurrency=OINV/ORIN.DocTotalFCDocumentTotalLocalCurrency=OINV/ORIN.DocTotalVatSumForeignCurrency=OINV/ORIN.VatSumFCVatSumLocalCurrency=OINV/ORIN.VatSumDocumentRate=OINV/ORIN.DocRateCompanyCurrency=OADM.MainCurncyStandardCostCurrency=OADM.MainCurncy
Technische Umsetzung:
HanaQueryServiceliestOADMjetzt perCROSS 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 CentralSalesRecordServicepersistiert und liest die neuen FelderExcelExportServiceschreibt die neuen Spalten in Standort- undSales_All_*.xlsx-DateienManualExcelImportServicekann die neuen Spalten wieder einlesenConfigTransferServiceerhaelt die neuen Felder beim Remapping zentraler Laufzeitdaten
Wichtig fuer Power BI:
- die neuen
DocumentTotal*- undVatSum*-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,TSCund ggf.Landdeduplizieren - besser: nach
TSC+DocumentType+DocumentEntrydeduplizieren, weilDocEntryaus B1 jetzt mitgezogen wird - positionsbasierte Auswertungen sollen weiterhin mit positionsbezogenen Feldern wie
Sales Price/Value,QuantityoderStandard costarbeiten
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*,DocRateundOADM.MainCurncyfachlich verglichen werden
Verifikation:
dotnet build .\TrafagSalesExporter.csproj --verbosity minimalerfolgreichdotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimalerfolgreich48/48Tests gruenManualExcelImportServiceTestspruefen die neuen Excel-SpaltenCentralSalesRecordServiceTestspruefen 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
DataSourceAdaptertrennt die Quellsysteme- Page-Services reduzieren direkte DB-Logik in mehreren Razor-Seiten
Scopedfuer UI-nahe Services undSingletonfuer gemeinsame Infrastruktur/Orchestrierung ist bewusst gewaehlt- Testabdeckung fuer zentrale Fachlogik ist vorhanden und waechst
Weiterhin offene Clean-Code-Risiken:
DatabaseInitializationServiceist weiterhin produktiver Reparatur-/MigrationspfadSettings.razorundStandorte.razorenthalten noch viel Workflow-/UI-LogikManagementCockpitServiceundConfigTransferServicesind 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.csSecurity/SecurityPolicies.csSecurity/DevelopmentAuthenticationHandler.cs
Geaenderte zentrale Dateien:
Program.csComponents/Routes.razorComponents/_Imports.razorComponents/Layout/NavMenu.razorComponents/Layout/MainLayout.razorappsettings.jsonappsettings.Development.json
Aktuelles Rollenmodell:
Security:AccessGroupssteuert Zugriff auf die AppSecurity:AdminGroupssteuert Admin-Berechtigung- Default-Gruppen sind
TRAFAG\\TrafagSalesExporter-UsersundTRAFAG\\TrafagSalesExporter-Admins - echte Gruppennamen muessen von der IT bestaetigt oder angepasst werden
Admin-geschuetzte Seiten:
SettingsStandorteTransformations
Dashboard, Management Cockpit und Logs bleiben fuer berechtigte angemeldete Benutzer sichtbar.
Development:
appsettings.Development.jsonaktiviert beiASPNETCORE_ENVIRONMENT=Developmenteinen lokalen Development-Auth-Handler- Default-User:
DEV\\TrafagDeveloper DevelopmentUserIsAdmin=true, damit lokal weiter programmiert werden kann- produktiv darf die App nicht mit
Developmentlaufen
IIS-/IT-Hinweise:
- Windows Authentication aktivieren
- Anonymous Authentication deaktivieren
ASPNETCORE_ENVIRONMENTproduktiv nicht aufDevelopmentsetzen- AD-Gruppen fuer Benutzer und Admins anlegen oder bestehende Gruppen eintragen
Security:AccessGroupsundSecurity:AdminGroupsin produktiver Konfiguration korrekt setzen
Verifikation:
dotnet build .\TrafagSalesExporter.csproj --verbosity minimal
dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal
Ergebnis:
- Build erfolgreich
- Tests erfolgreich
48/48Tests gruen- Auth-Policy-Tests fuer AccessGroup, AdminGroup und Development-Admin vorhanden
- lokaler Development-Auth-Start geprueft:
http://localhost:55416antwortet mit HTTP200 - bekannte MudBlazor-Analyzer-Warnungen zu
Densebleiben
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/ValueQuantityStandard costQuantity * 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:
EURUSDOriginal
Die Umrechnung nutzt CurrencyExchangeRateService.
Wichtig:
- nicht-betragliche Werte wie
Quantitywerden nicht umgerechnet - bei
Originalbleiben Werte in der jeweiligen Quellwaehrung - bei fehlendem Wechselkurs wird der betroffene Wert mit
0in die Zielwaehrung eingerechnet - fehlende Kurse werden als Anzahl
Nicht umgerechnetbzw. 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.razorModels/ManagementCockpitModels.csServices/IManagementCockpitService.csServices/ManagementCockpitPageService.csServices/ManagementCockpitService.csTrafagSalesExporter.Tests/ManagementCockpitServiceTests.cs
Neue bzw. erweiterte Modelle:
ManagementCockpitValueFieldKeysManagementCockpitCurrencyOptionsManagementCockpitValueFieldOptionManagementCockpitAnalysisOptionsManagementCockpitAggregatedFieldValue
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
CHFebenfalls 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.csServices/DataSources/IDataSourceAdapterResolver.csServices/DataSources/DataSourceAdapterResolver.csServices/DataSources/DataSourceFetchContext.csServices/DataSources/DataSourceFetchResult.csServices/DataSources/DataSourceCredentials.csServices/DataSources/HanaDataSourceAdapter.csServices/DataSources/SapGatewayDataSourceAdapter.csServices/DataSources/ManualExcelDataSourceAdapter.cs
Neuer Zuschnitt:
SiteExportServiceist jetzt deutlich schlanker und nur noch Export-Pipeline- Adapter loesen Quellsystem-spezifisches Laden auf
- fuer ein weiteres Quellsystem ist kein Umbau im
SiteExportServicemehr noetig
2. Page-Services sind nicht mehr Singleton
UI-nahe Services laufen jetzt pro Blazor-Circuit als Scoped.
Betroffen:
ISettingsPageServiceIStandortePageServiceIStandorteSapEditorServiceIManagementCockpitPageServiceIDashboardPageServiceILogsPageServiceITransformationsPageService
Wichtig:
ExportOrchestrationServicebleibt bewusstSingleton, 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:
DatabaseInitializationServiceals OrchestratorDatabaseSchemaMaintenanceServicefuer Schema-/Repair-LogikDatabaseSeedServicefuer Defaultdaten und Stammdaten-SeedingDatabaseInitializationService.SchemaSql.csals 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.razorueberDashboardPageServiceLogs.razorueberLogsPageServiceTransformations.razorueberTransformationsPageService
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:
tscunddateFilterlaufen jetzt parametriert inHanaCommandschemawird 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:
IHanaQueryServiceist jetzt async-basiertHanaQueryServicenutztOpenAsync,ExecuteReaderAsync,ReadAsync,ExecuteScalarAsync- Aufrufer wie
HanaDataSourceAdapter,StandortePageServiceundSettingsPageServiceverwenden keineTask.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:
dotnet build .\TrafagSalesExporter.csproj --verbosity minimal
dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal
Ergebnis:
- Projekt-Build erfolgreich
36/36Tests gruen
Bekannt:
dotnet build .\TrafagSalesExporter.slnendet in dieser Umgebung weiterhin mit Exitcode1ohne konkrete Compilerfehler- das Hauptprojekt und das Testprojekt bauen aber erfolgreich
- bekannte Warnungen bleiben:
MSB3270wegen 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
DatabaseInitializationServicebleibt 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
CurrencyExchangeRatessind im System vorhanden Settingsenthaelt bereits eine Pflegeoberflaeche fuer WechselkurseExchangeRateImportServiceimportiert ECB-Tageskurse nachCurrencyExchangeRatesNormalizeCurrencyCodeist als Value-Transformation vorhandenConvertCurrencyist als Record-Transformation vorhandenProgram.csregistriert beide Strategien sowieCurrencyExchangeRateServiceundExchangeRateImportService
Wichtig:
- die Roh-Auswertung im
Management Cockpitrechnet 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:
CurrencyExchangeRateServiceTestsExchangeRateImportServiceTests- Erweiterungen in
TransformationStrategiesTestsRecordTransformationServiceTestsTransformationCatalogTests
Aktueller Teststatus nach diesem Nachtrag:
dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal
Ergebnis:
- erfolgreich
31/31Tests gruen- bekannte Warnung bleibt:
- SAP HANA Architekturwarnung
MSB3270
- SAP HANA Architekturwarnung
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_oldnachSitesist die Spaltenreihenfolge im SQL inkonsistent - dadurch koennen Werte wie
ManualImportFilePath,SapServiceUrl,SapEntitySetverschoben 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
CentralSalesRecordsgehoeren 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:
DbContextoeffnen- 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:
ManagementCockpitServiceenthaelt noch hartcodierte Jahreslogik fuer2025und2026- 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
CentralSalesRecordsaus normalem Config-Import eher herausnehmen
4. Zentrale Export-Semantik entscheiden
Explizit festlegen:
- zentrale Datei immer aus
CentralSalesRecordsoder - zentrale Datei aus dem aktuellen Export-Snapshot
Danach die doppelte Semantik entfernen.
Priorisierung aus Architektursicht
Wenn nach Stabilitaet priorisiert wird, dann in dieser Reihenfolge:
DatabaseInitializationService/ Migrationspfad absichernConfigTransferService.ImportJsonAsyncatomar und weniger destruktiv machen- Logik aus
Settings.razorundStandorte.razorin Anwendungsservices verschieben - Export-Semantik fuer Konsolidierung vereinheitlichen
- 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:
- zuerst diesen Architektur-Nachtrag lesen
- dann
DatabaseInitializationServiceundConfigTransferServiceals Risikobloecke ansehen - 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 Serverist zentrale HANA-Konfiguration pro Quellsystem- aktuell relevant fuer:
BI1SAGE
Unten im Standort gilt jetzt:
- Standort pflegt nur noch standortspezifische Daten
SchemaTSCLandSourceSystem- optionale Username-/Password-Overrides
- die technische HANA-Verbindung kommt aus der zentralen Konfiguration des Quellsystems
Technische Umsetzung
HanaServerhat jetzt zusaetzlichSourceSystemDatabaseInitializationServicestellt zentrale Eintraege fuerBI1undSAGEsicher- bestehende verknuepfte HANA-Server werden dabei moeglichst auf
BI1/SAGEgemappt SiteExportServicebaut HANA-Verbindungen jetzt aus der zentralen HANA-Konfiguration des QuellsystemsSettings.razortestet BI1/SAGE nicht mehr ueber einen Beispiel-Standort, sondern ueber die zentrale HANA-KonfigurationStandorte.razorspeichert 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.razormeldet 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:
CodeDisplayNameConnectionKindIsActiveCentralUsernameCentralPassword
Neue GUI-Logik
Settings.razorenthaelt 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:
HANASAP_GATEWAYMANUAL_EXCEL
Damit gilt:
- HANA-Konfiguration oben in
Standorte.razornur noch fuer Quellsysteme mit AnschlussartHANA - Standort-Dropdown zieht seine Quellsysteme jetzt aus
SourceSystemDefinitions - Transformationsregeln ziehen ihre Quellsystem-Auswahl ebenfalls aus
SourceSystemDefinitions
Technische Umsetzung
AppDbContexthat jetztDbSet<SourceSystemDefinition>DatabaseInitializationServiceerzeugt und seedetSourceSystemDefinitionsSiteExportServiceloest zentrale Credentials jetzt ueberSourceSystemDefinitionConfigTransferServiceexportiert/importiert jetzt auchSourceSystemDefinitions
Verifikation
Nach dieser Umstellung geprueft:
dotnet build .\TrafagSalesExporter.csproj -v minimal
dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal
Ergebnis:
- Build erfolgreich
- Tests erfolgreich
31/31Tests gruen
Bereinigung der Legacy-Credentials
Danach wurden auch die alten zentralen Credential-Felder technisch bereinigt.
Aktueller Stand:
ExportSettingsenthaelt keine alten Felder mehr fuerSapUsername,Bi1Username,SageUsernameusw.- der Config-Export schreibt zentrale Zugangsdaten nur noch ueber
SourceSystemDefinitions ConfigTransferServicehat keinen aktiven Legacy-Credential-Pfad mehr- die fruehere Temp-Datei
standorte_numbered.tmpwurde 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:
DatabaseInitializationServiceerkennt alte Credential-Spalten inExportSettings- wenn diese Legacy-Spalten noch existieren, wird
ExportSettingsbeim Start auf das neue Schema rekonstruiert - erhalten bleiben nur die noch gueltigen Felder:
DateFilterTimerHourTimerMinuteTimerEnabledDebugLoggingEnabledLocalSiteExportFolderLocalConsolidatedExportFolder
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
HostPortDatabaseNameUseSslValidateCertificateAdditionalParams
- Username/Password werden nicht mehr in der zentralen HANA-UI gepflegt
- HANA-Verbindungstests in
Standorte.razorverwenden jetzt die zentralen Credentials ausSourceSystemDefinition SiteExportServicefaellt bei HANA nicht mehr auf inHanaServergespeicherte Credentials zurueckConfigTransferServiceexportiert/importiert fuerHanaServerkeine Username-/Password-Werte mehrDatabaseInitializationServicebereinigt bei bestehender DB auch dasHanaServers-Schema und entfernt die AltspaltenUsername/Password
Die fachliche Reihenfolge ist jetzt eindeutig:
- zentrale Credentials aus
SourceSystemDefinition - optionale Override-Credentials am
Site - 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 ohneUsername/Password- das EF-Modell
HanaServerhat diese Properties aber noch als normale Spalten behandelt
Fix:
HanaServer.UsernameundHanaServer.Passwordsind 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
SourceSystemDefinitionenthaelt jetzt auchCentralServiceUrl- zentrale SAP-Service-URL wird damit am Quellsystem gepflegt, nicht mehr primaer am Standort
Standorte.razorbehandeltSapServiceUrljetzt als Override- wenn kein Override gesetzt ist, zieht SAP die URL zentral aus dem Quellsystem
UI
Settings.razorhat fuer Quellsysteme jetzt eine Dialogbearbeitung statt nur Inline-Tabellenfelder- dadurch ist das Quellsystem sauber editierbar
- fuer
SAP_GATEWAYwird dort die zentrale SAP-Service-URL gepflegt Standorte.razorzeigt bei SAP jetzt:- zentrale SAP Service URL
- optionales
SAP Service URL Override
Laufzeitlogik
SiteExportServiceverwendet bei SAP die effektive URL aus- Standort-Override
- sonst
SourceSystemDefinition.CentralServiceUrl
- SAP-Verbindungstest in
Settings.razortestet die zentrale URL direkt aus dem Quellsystem - Dashboard zeigt fuer SAP jetzt ebenfalls die effektive zentrale bzw. ueberschriebene URL
Verifikation
Nach der Umstellung geprueft:
dotnet build .\TrafagSalesExporter.csproj -v minimal
dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --verbosity minimal
Ergebnis:
- Build erfolgreich
- Tests erfolgreich
31/31Tests 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:
BI1undSAGEbleiben auf direktem HANA-ZugriffSAPlaeuft 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:
SAPBI1SAGE
Zusaetzlich gibt es pro Standort optionale Overrides:
UsernameOverridePasswordOverride
Aufloesungsreihenfolge:
- Standort-Override
- zentrale Credentials des Quellsystems
- 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:
SapServiceUrlSapEntitySetSapEntitySetsCacheSapEntitySetsRefreshedAtUtc
Refresh der SAP-Quellen erfolgt nur auf Knopfdruck.
Beispiel Service URL:
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:
SapSourceDefinitionSapJoinDefinitionSapFieldMapping
Unterstuetzt wird:
- mehrere SAP-Quellen pro Standort
- Alias pro Quelle
- Primaerquelle
- Join-Definitionen
- Mapping von
Alias.Feldnameauf zentrales Schema
UI-Erweiterungen:
Quellen refreshenFelder aus Quellen laden- Join-Key-Auswahl aus Metadaten
Auto-Matchfuer 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:
LocalSiteExportFolderLocalConsolidatedExportFolder
Pro Standort:
LocalExportFolderOverride
Fallback wenn leer:
./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 IDClient IDClient 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
FilePathgespeichert- 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
CentralSalesRecordsfuer diesen Standort ersetzt - der zentrale Export liest weiter nur aus
CentralSalesRecords
Neue Site-Felder:
ManualImportFilePathManualImportLastUploadedAtUtc
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 oeffnenfuer die neueste zentrale DateiSales_All_*.xlsx- Button
Alle exportieren - Button
Zentrale Datei neu erzeugen
Bedeutung:
Alle exportierenliest alle Quellen neu und erzeugt danach die zentrale DateiZentrale Datei neu erzeugenschreibt nur ausCentralSalesRecordseine 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:
Valuefuer einfache feldweise Regeln aus der GUIRecordfuer komplexere C#-Strategien per Strategy Pattern
Umgesetzt:
- neues Feld
RuleScopeaufFieldTransformationRule - dynamischer Strategiekatalog
- GUI liest verfuegbare Typen aus dem Katalog
- erste
Record-Strategie:FirstNonEmpty
Beispiel:
TargetField = CustomerNameTransformationType = FirstNonEmptyArgument = 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
OINVINV1ORINRIN1OCRDOITM
vorhanden sind.
Wichtig:
- manuelle Eingabe bleibt moeglich
- fuer
BI1undSAGEwerden 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
RecordTransformationServiceTransformationCatalogManualExcelImportServiceManagementCockpitServiceConfigTransferService
Wichtiger bereits gefundener Bug:
- deutsches Dezimalformat wie
1,50wurde im manuellen Excel-Import falsch interpretiert - Parsing wurde korrigiert
Wichtige Dateien
Modelle
Models/Site.csModels/ExportSettings.csModels/ExportLog.csModels/CentralSalesRecord.csModels/SapSourceDefinition.csModels/SapJoinDefinition.csModels/SapFieldMapping.csModels/ManagementCockpitModels.csModels/ConfigTransferPackage.csModels/FieldTransformationRule.cs
Services
Services/SiteExportService.csServices/ConsolidatedExportService.csServices/CentralSalesRecordService.csServices/SapGatewayService.csServices/SapCompositionService.csServices/ConfigTransferService.csServices/AppEventLogService.csServices/ManagementCockpitService.csServices/DatabaseInitializationService.csServices/ExportOrchestrationService.csServices/ManualExcelImportService.csServices/TransformationCatalog.csServices/RecordTransformationService.csServices/TransformationStrategies.cs
UI
Components/Pages/Standorte.razorComponents/Pages/Settings.razorComponents/Pages/Dashboard.razorComponents/Pages/Logs.razorComponents/Pages/ManagementCockpit.razorComponents/Pages/Transformations.razorComponents/Layout/NavMenu.razor
Tests
TrafagSalesExporter.Tests/TransformationStrategiesTests.csTrafagSalesExporter.Tests/RecordTransformationServiceTests.csTrafagSalesExporter.Tests/TransformationCatalogTests.csTrafagSalesExporter.Tests/ManualExcelImportServiceTests.csTrafagSalesExporter.Tests/ManagementCockpitServiceTests.csTrafagSalesExporter.Tests/ConfigTransferServiceTests.cs
Datenbank / Migrationen
Viele Aenderungen laufen ueber DatabaseInitializationService.
Wichtige neue oder erweiterte Tabellen/Felder:
SitesUsernameOverridePasswordOverrideSapServiceUrlSapEntitySetSapEntitySetsCacheSapEntitySetsRefreshedAtUtcLocalExportFolderOverrideManualImportFilePathManualImportLastUploadedAtUtc
ExportSettings- zentrale SAP/BI1/SAGE Credentials
LocalSiteExportFolderLocalConsolidatedExportFolderDebugLoggingEnabled
FieldTransformationRulesRuleScope
ExportLogsFilePath
- neue Tabellen:
AppEventLogsCentralSalesRecords- 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 inAppEventLogsoderExportLogs - die alte Tabelle
Sites_oldexistierte 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
- Live-Status pollt waehrend laufendem Export nicht mehr permanent
Program.cs- SQLite
Default Timeoutvon10auf60erhoeht
- SQLite
Services/CentralSalesRecordService.cs- nach abgeschlossenem Batch-Insert wird explizit
Zentrale Tabelle aktualisiertgesetzt
- nach abgeschlossenem Batch-Insert wird explizit
Services/DatabaseInitializationService.cs- automatische Reparaturlogik fuer Tabellen, deren
CREATE TABLE-SQL nochSites_oldreferenziert - betroffene Tabellen werden beim Start neu aufgebaut und Daten rueberkopiert
- automatische Reparaturlogik fuer Tabellen, deren
Danach wurde der Export erfolgreich getestet und geht jetzt wieder durch.
Was bei einer naechsten Stoerung zuerst zu pruefen ist
- Tritt beim App-Start die Schema-Reparatur sauber durch?
- Gibt es noch weitere Tabellen mit FK-Referenz auf
Sites_old? - Erst danach wieder Insert-/Commit-Batches der zentralen Speicherung untersuchen
Build-Status
Letzter Build:
dotnet build TrafagSalesExporter.sln
Ergebnis:
- erfolgreich
- bekannte Warnungen bleiben:
- SAP HANA Architekturwarnung
MSB3270 - MudBlazor Analyzer
Dense
- SAP HANA Architekturwarnung
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 SAPwird zentral unterSettings -> Quellsystemegepflegt und gehoert nicht in diese Box- der irrefuehrende Button
Server hinzufuegenwurde 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
- Bereich oben heisst jetzt bewusst
Fachliche Regel jetzt:
Quellsystemeverwalten die zentralen Systeme und deren AnschlussartStandortezeigen fuer HANA nur noch die technische ZentralverbindungSAPwird 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.
SourceSystemDefinitionswerden mitConnectionKind,CentralServiceUrl,CentralUsername,CentralPasswordimportiert/exportiert.HanaServersenthalten nur noch technische HANA-Verbindungsdaten und keine Credentials mehr.- Standort-Overrides fuer Username/Password sowie SAP Service URL gehen weiterhin mit.
- Die vorhandenen
ConfigTransferServiceTestslaufen grün.
Weiterhin offene Architekturpunkte:
ConfigTransferService.ImportJsonAsyncist 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
SourceSystemDefinitionsenthaelt, aber noch ohneConnectionKind, faellt der DTO-Default aufHANA. - Dadurch koennte ein altes
SAPbeim Import falsch alsHANAlanden.
- Wenn ein aelteres JSON bereits
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.