Ensure ZSCHWEIZ OData mapping seed

This commit is contained in:
2026-05-07 14:55:30 +02:00
parent 34be4a5b49
commit dea171862c
5 changed files with 263 additions and 29 deletions
+51
View File
@@ -2,6 +2,57 @@
Stand: 2026-05-05 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 ## Nachtrag 2026-05-05 Aktueller Handoff FinanceProbe / Laenderabgleich
Der aktuelle Arbeitsstand fuer den naechsten Einstieg ist der lokale FinanceProbe: Der aktuelle Arbeitsstand fuer den naechsten Einstieg ist der lokale FinanceProbe:
+42
View File
@@ -17,6 +17,48 @@ Lokaler FinanceProbe:
http://localhost:55417/finance http://localhost:55417/finance
``` ```
## Aktueller Zusatzstand 2026-05-07 SAP OData / ZSCHWEIZ
Schweiz/Oesterreich werden ueber eine neue SAP-Tabelle `ZSCHWEIZ` bereitgestellt.
Wichtige Punkte:
- ABAP-Report: `report.abap`
- SAP-Tabelle: `ZSCHWEIZ`
- OData EntitySet: `ZSCHWEIZSet`
- App-Standort: `ZSCHWEIZ` / `Schweiz/Oesterreich`
- Geplanter App-Pfad: `SAP` = `SAP OData`, nicht direkter HANA-Spezialcode
Quellsystem-Codes:
- `SAP`: SAP OData/Gateway, DisplayName `SAP OData`
- `SAP_HANA`: direkte HANA-Tabellen/Views, DisplayName `SAP HANA Tables/Views`
- `BI1`: HANA
- `SAGE`: HANA
- `MANUAL_EXCEL`: Excel/CSV
Mapper:
- SAP OData nutzt `SapSourceDefinition`, `SapJoinDefinition`, `SapFieldMapping`.
- Direkte HANA-Tabellen/Views koennen dieselben Mapping-Tabellen ebenfalls nutzen.
- Bei HANA mit gepflegten Quellen/Mappings nutzt `HanaDataSourceAdapter` den generischen Mapping-Pfad.
- Ohne HANA-Mapping bleibt der alte B1-HANA-Standardpfad fuer `OINV/INV1/ORIN/RIN1` aktiv.
ZSCHWEIZ-Seed:
- Quelle Alias `Z`
- EntitySet `ZSCHWEIZSet`
- Mapping auf `SalesRecord` ist vorbefuellt und grafisch editierbar.
- Beim App-Start wird die ZSCHWEIZ-Quelle samt Feldmapping per Upsert angelegt oder repariert.
- Wenn Gateway `$metadata` liefert, koennen Felder in der UI per `Felder aus Quellen laden` gelesen werden.
ABAP-Fachlogik:
- `BUKRS 1100` = Schweiz, `TSC TRCH`, `LAND1 CH`
- `BUKRS 1200` = Oesterreich, `TSC TRAT`, `LAND1 AT`
- `CUSTOMER_LAND` = Kundenland aus `KNA1-LAND1`
- Netto-/Steuerwerte werden in Belegwaehrung und Hauswaehrung geschrieben.
Aktuelle FinanceProbe-Funktionen: Aktuelle FinanceProbe-Funktionen:
- `Meeting Ampel 2025` fuer alle Laender aus `check.xlsx` - `Meeting Ampel 2025` fuer alle Laender aus `check.xlsx`
@@ -2,6 +2,43 @@
Stand: 2026-05-05 Stand: 2026-05-05
## Nachtrag 2026-05-07 ZSCHWEIZ ueber SAP OData
Finaler Stand fuer Schweiz/Oesterreich:
- ABAP-Report `report.abap` fuellt SAP-Tabelle `ZSCHWEIZ`.
- Buchungskreis `1100` = Schweiz, `1200` = Oesterreich.
- `LAND1` in `ZSCHWEIZ` ist Reporting-Land aus Buchungskreis.
- `CUSTOMER_LAND` ist Kundenland aus `KNA1-LAND1`.
- Die App liest `ZSCHWEIZ` ueber SAP OData, nicht ueber direkten HANA-Spezialcode.
In der App:
- Quellsystem-Code `SAP` bleibt bestehen, DisplayName jetzt `SAP OData`.
- `SAP_HANA` ist nur fuer direkte HANA-Tabellen/Views und heisst `SAP HANA Tables/Views`.
- Der grafische Mapper funktioniert fuer SAP OData und fuer HANA-Tabellen/Views.
- Vorkonfigurierter Standort:
- `TSC = ZSCHWEIZ`
- `Land = Schweiz/Oesterreich`
- `SourceSystem = SAP`
- Quelle `Z`
- EntitySet `ZSCHWEIZSet`
- Quelle und Feldmapping werden beim App-Start per Seed-/Repair-Logik nachgezogen, auch wenn der Standort bereits existiert.
Naechste Schritte:
1. App neu starten, damit die Seed-/Repair-Logik laeuft.
2. In `Settings -> Quellsysteme` pruefen, ob `SAP` als `SAP OData` angezeigt wird.
3. In `Standorte` den Standort `ZSCHWEIZ` oeffnen.
4. Falls die zentrale SAP-Service-URL noch auf `ZPOWERBI_EINKAUF_SRV` zeigt, beim Standort `SAP Service URL Override` auf den finalen OData-Service fuer `ZSCHWEIZ` setzen.
5. `Entity Sets refreshen`.
6. Quelle `Z` auf `ZSCHWEIZSet` kontrollieren.
7. `Felder aus Quellen laden`.
8. Grafisches Mapping kontrollieren; manuell mappen musst du nur, wenn Gateway-Feldnamen vom erwarteten `ZSCHWEIZ`-Layout abweichen.
9. Standort aktivieren und Export testen.
Keine manuelle Feldliste ist noetig, wenn der Gateway-Service `$metadata` korrekt liefert.
## Nachtrag 2026-05-05 Abschlussstand FinanceProbe / Spanien / Deutschland ## Nachtrag 2026-05-05 Abschlussstand FinanceProbe / Spanien / Deutschland
Aktueller lokaler Testpunkt: Aktueller lokaler Testpunkt:
@@ -341,36 +341,51 @@ public class DatabaseSeedService : IDatabaseSeedService
private static void EnsureSapODataDachMapping(AppDbContext db, int siteId) private static void EnsureSapODataDachMapping(AppDbContext db, int siteId)
{ {
var existingSources = db.SapSourceDefinitions.Where(x => x.SiteId == siteId).ToList(); var changed = false;
var existingMappings = db.SapFieldMappings.Where(x => x.SiteId == siteId).ToList(); var source = db.SapSourceDefinitions
.OrderBy(x => x.Id)
.FirstOrDefault(x => x.SiteId == siteId && x.Alias == "Z");
if (existingSources.Count > 0 || existingMappings.Count > 0) if (source is null)
{ {
var changed = false; db.SapSourceDefinitions.Add(new SapSourceDefinition
foreach (var source in existingSources.Where(x => {
string.Equals(x.Alias, "Z", StringComparison.OrdinalIgnoreCase) && SiteId = siteId,
string.Equals(x.EntitySet, "ZSCHWEIZ", StringComparison.OrdinalIgnoreCase))) Alias = "Z",
EntitySet = "ZSCHWEIZSet",
IsPrimary = true,
IsActive = true,
SortOrder = 0
});
changed = true;
}
else
{
if (source.EntitySet != "ZSCHWEIZSet")
{ {
source.EntitySet = "ZSCHWEIZSet"; source.EntitySet = "ZSCHWEIZSet";
changed = true; changed = true;
} }
if (changed) if (!source.IsPrimary)
db.SaveChanges(); {
source.IsPrimary = true;
changed = true;
}
return; if (!source.IsActive)
{
source.IsActive = true;
changed = true;
}
if (source.SortOrder != 0)
{
source.SortOrder = 0;
changed = true;
}
} }
db.SapSourceDefinitions.Add(new SapSourceDefinition
{
SiteId = siteId,
Alias = "Z",
EntitySet = "ZSCHWEIZSet",
IsPrimary = true,
IsActive = true,
SortOrder = 0
});
var mappings = new (string Target, string Source, bool Required)[] var mappings = new (string Target, string Source, bool Required)[]
{ {
(nameof(SalesRecord.Tsc), "Z.TSC", true), (nameof(SalesRecord.Tsc), "Z.TSC", true),
@@ -402,17 +417,51 @@ public class DatabaseSeedService : IDatabaseSeedService
for (var i = 0; i < mappings.Length; i++) for (var i = 0; i < mappings.Length; i++)
{ {
db.SapFieldMappings.Add(new SapFieldMapping var mapping = db.SapFieldMappings
.OrderBy(x => x.Id)
.FirstOrDefault(x => x.SiteId == siteId && x.TargetField == mappings[i].Target);
if (mapping is null)
{ {
SiteId = siteId, db.SapFieldMappings.Add(new SapFieldMapping
TargetField = mappings[i].Target, {
SourceExpression = mappings[i].Source, SiteId = siteId,
IsRequired = mappings[i].Required, TargetField = mappings[i].Target,
IsActive = true, SourceExpression = mappings[i].Source,
SortOrder = i IsRequired = mappings[i].Required,
}); IsActive = true,
SortOrder = i
});
changed = true;
continue;
}
if (mapping.SourceExpression != mappings[i].Source)
{
mapping.SourceExpression = mappings[i].Source;
changed = true;
}
if (mapping.IsRequired != mappings[i].Required)
{
mapping.IsRequired = mappings[i].Required;
changed = true;
}
if (!mapping.IsActive)
{
mapping.IsActive = true;
changed = true;
}
if (mapping.SortOrder != i)
{
mapping.SortOrder = i;
changed = true;
}
} }
db.SaveChanges(); if (changed)
db.SaveChanges();
} }
} }
+55
View File
@@ -1,5 +1,60 @@
# Last Change 2026-05-04 # Last Change 2026-05-04
## SAP OData / ZSCHWEIZ / HANA Mapping 2026-05-07
Aktueller Entscheid:
- `ZSCHWEIZ` wird nicht direkt als SAP-HANA-Spezialfall gelesen.
- `ZSCHWEIZ` wird ueber den bestehenden SAP-OData/Gateway-Pfad gelesen.
- Der grafische Quellen- und Feldmapper bleibt dafuer aktiv.
- Feldinfos muessen nicht hart codiert werden, solange der Gateway-Service `$metadata` fuer das EntitySet liefert.
Quellsystem-Namen wurden zur Entwirrung geschaerft:
- Code `SAP` bleibt technisch bestehen, DisplayName ist jetzt `SAP OData`.
- Code `SAP_HANA` bleibt fuer direkte HANA-Tabellen/Views bestehen, DisplayName ist jetzt `SAP HANA Tables/Views`.
- Bestehende Konfigurationen bleiben dadurch kompatibel.
Seed / Vorkonfiguration:
- Standort `ZSCHWEIZ` / Land `Schweiz/Oesterreich` wird als inaktiver Standort angelegt bzw. repariert.
- `SourceSystem = SAP`.
- Quelle: Alias `Z`, EntitySet `ZSCHWEIZSet`.
- Mapping ist grafisch editierbar und wird auf die Felder der Tabelle `ZSCHWEIZ` gesetzt.
- Die Seed-/Repair-Logik zieht Quelle und Mapping auch bei bereits vorhandener ZSCHWEIZ-Konfiguration nach; manuelles Mapping ist nur noetig, wenn die Gateway-Feldnamen vom erwarteten `ZSCHWEIZ`-Layout abweichen.
Wichtig fuer die UI:
1. App neu starten, damit Seed/Repair laeuft.
2. `Settings -> Quellsysteme`: `SAP` sollte als `SAP OData` erscheinen.
3. `Standorte -> ZSCHWEIZ`:
- Quellsystem `SAP OData (SAP)`
- SAP Service URL Override auf den finalen OData-Service fuer `ZSCHWEIZ` setzen, falls die zentrale SAP-URL noch auf `ZPOWERBI_EINKAUF_SRV` zeigt.
- `Entity Sets refreshen`.
- Quelle `Z` soll auf `ZSCHWEIZSet` zeigen.
- `Felder aus Quellen laden`.
- Mapping kontrollieren.
ABAP / SAP:
- ABAP-Report liegt in `report.abap`.
- Report fuellt Tabelle `ZSCHWEIZ` aus Buchungskreis `1100` = Schweiz und `1200` = Oesterreich.
- `LAND1` ist Reporting-Land aus Buchungskreis.
- `CUSTOMER_LAND` ist Kundenland aus `KNA1-LAND1`.
- Upsert erfolgt per `MODIFY zschweiz FROM TABLE`.
Letzte technische Verifikation:
```text
dotnet build .\TrafagSalesExporter.csproj --no-restore -p:UseAppHost=false --verbosity minimal
dotnet test .\TrafagSalesExporter.Tests\TrafagSalesExporter.Tests.csproj --no-restore --verbosity minimal
```
Ergebnis:
- Build erfolgreich
- Tests erfolgreich, `50/50`
## Finance-Abgrenzung: Antworten Andreas 2026-05-07 ## Finance-Abgrenzung: Antworten Andreas 2026-05-07
Fachliche Vorgabe nach Rueckmeldung: Fachliche Vorgabe nach Rueckmeldung: