Files
Ai/TrafagSalesExporter/HANDOFF_2026-04-15.md
T

1898 lines
63 KiB
Markdown

# TrafagSalesExporter Handoff
Stand: 2026-05-05
## 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.
## 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<SourceSystemDefinition>`
- `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.