1664 lines
53 KiB
Markdown
1664 lines
53 KiB
Markdown
# TrafagSalesExporter Handoff
|
|
|
|
Stand: 2026-05-05
|
|
|
|
## 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 `50/50` 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
|
|
|
|
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.
|