„Zwei Dinge können den Menschen zum Wahnsinn treiben: die Eifersucht und das Studium der Wechselkurse“
Frank Pöpsel, dt. Journalist („Capital“)
Ganz im Sinne von Frank Pöpsel überrascht SAP im Bezug auf Wechselkurse mit einem besonderen Szenario, dass wir heute vorstellen wollen. Im Fokus stehen fehlerhafte Wechselkurse, um beispielsweise Bestellfreigabegrenzen zu umgehen.
Bei der Anlage einer Bestellung in Fremdwährung werden in SAP Wechselkurse aus der Tabelle „TCURR“ für die Umrechnung des Bestellwertes in Hauswährung gezogen. Dieser vorgegebene Wert kann allerdings manuell durch den Nutzer überschrieben werden – der Betrag der Bestellung in Hauswährung also bewusst zu niedrig (oder zu hoch) ausgewiesen werden. Bei einem angenommenen gültigen Wechselkurs von 1 EURO zu 1,23456 USD liegen diesem Beispiel 2 Szenarien zu Grunde:
- Anlage einer Bestellung mit einem Wechselkurs von 1 Euro zu 111 USD und nachträglicher Änderung dieses Wechselkurses von 1 Euro zu 555 USD. Eine Bestellung i.H.v. 500.000 USD wird statt mit 405.003 EURO „nur“ mit 901 EURO im System hinterlegt.
- Anlage einer Bestellung mit einem Wechselkurs von 1 Euro zu 333 USD ohne nachträglicher Änderung. Diese Bestellung i.H.v. 500.000 USD wird also mit „nur“ 1.502 EURO im System gespeichert.
Es stellt sich damit die Frage, wo von im System hinterlegten Wechselkursen abgewichen wurde.
Erste Vermutung – in den Änderungstabellen sind diese Anpassungen ersichtlich. Dabei ist zu beachten, dass der genutzte Wechselkurs im Datenfeld „WKURS“ in der Tabelle „EKKO“ gespeichert wird. Das folgende SQL-Query gibt solche Änderungen aus:
SELECT OBJECTCLAS, OBJECTID, TABNAME, FNAME, CHNGIND, VALUE_NEW, VALUE_OLD FROM CDPOS WHERE MANDANT = 800 AND TABNAME LIKE 'EKKO' AND FNAME LIKE 'WKURS'
OBJECTCLAS | OBJECTID | TABNAME | FNAME | CHNGIND | VALUE_NEW | VALUE_OLD |
---|---|---|---|---|---|---|
EINKBELEG | 4500022429 | EKKO | WKURS | U | 555.00000 | 111.00000 |
Das Datenfeld „CHNGIND“ mit der Ausprägung „U“ weist darauf hin, dass die Bestellung mit der Nummer 4500022429 nachträglich verändert wurde – also der in der Erstellung ursprüngliche Wechselkurs 111 (Datenfeld VALUE_OLD) auf 555 (VALUE_NEW) geändert wurde.
Dieses Vorgehen bei der Analyse liefert das in Szenario a beschriebene Fallbeispiel und ist als Ergebnis leider unvollständig. Ein fehlerhafter Wechselkurs, der direkt beim Anlegen der Bestellung eingegeben wird– also Szenario b –wird nicht ausgegeben. Solche Eingaben werden in den Änderungsbelegtabellen als INSERT (CHNGIND = I) dargestellt. Dies ist insoweit logisch, da die Bestellung angelegt und nicht nachträglich geändert wurde.
Mit dieser Erkenntnis wird also im nächsten Schritt der Inhalt der Tabelle „EKKO“ im Datenfeld „WKURS“ mit dem Inhalt der Tabelle „TCURR“ verglichen. Das folgende Statement zeigt exemplarische Inhalte der Tabelle „TCURR“:
SELECT KURST, FCURR, TCURR, GDATU, UKURS FROM TCURR
KURST | FCURR | TCURR | GDATU | UKURS |
---|---|---|---|---|
EURX | EUR | USD | 79949781 | 1,23456- |
EURX | EUR | USD | 79949780 | 0,89012 |
2 Punkte fallen unmittelbar auf:
- Das Datenfeld „GDATU“ (Datum, ab dem der Kurs gültig ist) ist offensichtlich kein Datum. Die Tabelle „TCURR“ arbeitet mit einem invertierten Format als 9er-Komplement. Die Berechnung ist sehr einfach und lautet:
99999999 – (GDATU) = Datum im Format yyyymmdd
somit für den ersten Eintrag in der o.a. Tabelle 99999999 – 79949781 = 20050218, somit 18.02.2005 und für den zweiten Eintrag in der Tabelle 19.02.2005.
- Die Werte im Datenfeld „UKURS“ (Umrechnungskurs) unterscheiden sich im Format. Das nachgestellte „-“ im Feld „UKURS“ weist auf einen mengennotierten, ein fehlendes „-“ weist auf einen preisnotierten Wechselkurs hin. Mengennotierung bedeutet, dass für eine Hauswährung EURO und einen Geschäftsvorfall in USD in der Tabelle „TCURR“ im Datenfeld „UKURS“ ein Wert von „1,23456-“ steht (1 EUR = 1,23456 USD). Bei einer Preisnotierung und einem Kurs von 1 USD = 0,89012 EUR ist in der Tabelle „TCURR“ im Feld „UKURS“ Datenfeld genau dieser Wert hinterlegt. In Mengennotierung würde der Eintrag „1,12344-“ lauten.
Mit dem folgenden SQL-Statement erfolgt der Abgleich der Tabelle „EKKO“ mit der Tabelle „TCURR“:
SELECT EKKO.AEDAT, EKKO.EBELN, EKKO.WKURS, EKKO.WAERS, T001.WAERS, TCURR.UKURS,
99999999-TO_INTEGER(CONCAT(GDATU,'0')/10) FROM EKKO
LEFT JOIN T001 ON (T001.MANDT = EKKO.MANDT AND T001.BUKRS=EKKO.BUKRS)
LEFT JOIN TCURR ON (T001.MANDT LIKE TCURR.MANDT AND T001.WAERS LIKE TCURR.TCURR AND EKKO.WAERS LIKE TCURR.FCURR)
WHERE
EKKO.WAERS NOT LIKE T001.WAERS AND KURST LIKE 'EURX' AND (99999999-EKKO.AEDAT)<GDATU AND NOT EXISTS (SELECT * FROM TCURR T2 WHERE T2.MANDT=TCURR.MANDT and TCURR.FCURR=T2.FCURR and TCURR.KURST=T2.KURST AND (99999999-TO_INTEGER(CONCAT(T2.GDATU,'0')/10))<EKKO.AEDAT AND (99999999-TO_INTEGER(CONCAT(T2.GDATU,'0')/10))>(99999999-TO_INTEGER(CONCAT(TCURR.GDATU,'0')/10))) AND EKKO.WKURS NOT LIKE TCURR.UKURS
ORDER BY EKKO.AEDAT DESC
Wie ist das Query aufgebaut?
Als erstes wird mit „SELECT“ definiert, welche Felder ausgegeben werden:
SELECT EKKO.AEDAT, EKKO.EBELN, EKKO.WKURS, EKKO.WAERS, T001.WAERS AS T001_WAERS, TCURR.UKURS, 99999999-TO_INTEGER(CONCAT(GDATU,'0')/10) AS TCURR_GDATU FROM EKKO
Der Ausdruck „99999999-TO_INTEGER(CONCAT(GDATU,’0′)/10)“ mutet hier ggf. etwas kryptisch an. Hintergrund ist die oben beschriebene Umrechnung des invertierten Datums in ein lesbares Format yyyymmdd auf einer SAP HANA Datenbank. So richtig sauber funktioniert die Umrechnung dieses Feldes nicht mit Standard-SQL-Mitteln. Als Kunstgriff wird an den Wert im Datenfeld „GDATU“ eine „0“ angehängt, und dieser Wert dann durch 10 geteilt.
Mit „JOIN“ wird die Ergebnismenge um Daten aus der Buchungskreistabelle (T001) und der Währungskurstabelle (TCURR) angereichert.
LEFT JOIN T001 ON (T001.MANDT = EKKO.MANDT AND T001.BUKRS=EKKO.BUKRS)
LEFT JOIN TCURR ON (T001.MANDT LIKE TCURR.MANDT AND T001.WAERS LIKE TCURR.TCURR AND EKKO.WAERS LIKE TCURR.FCURR)
Konkret wird über die Tabelle „T001“ und die dort hinterlegten Buchungskreise, sowie die Tabelle „TCURR“ ermittelt, welche Wechselkurse für Bestellungen in Fremdwährung heranzuziehen sind.
Abschließend fokussiert die „WHERE“-Klausel auf Vorgänge in buchungskreisfremder Währung (EKKO.WAERS NOT LIKE T001.WAERS
). Der Rest in dieser Klausel stellt sicher, dass nur der im Bestellzeitpunkt gültige Wechselkurs als Vergleichsgröße herangezogen wird.
Das Ergebnis zeigt die für diesen Beitrag angelegten Bestellungen:
AEDAT | EBELN | WKURS | WAERS | T001_WAERS | UKURS | TCURR_GDATU |
---|---|---|---|---|---|---|
20180831 | 4500022429 | 555,00000 | USD | EUR | 1,12145- | 20150508 |
20180830 | 4500022428 | 333,00000 | USD | EUR | 1,12145- | 20150508 |
Das Ergebnis zeigt die betroffenen Bestellnummern (Datenfeld EBELN), den in der Bestellung manuell eingegebenen Wechselkurs (Datenfeld WKURS), den im System hinterlegten Wechselkurs mit dem dazu gehörenden gültig ab Datum (Felder UKURS und TCURR-GDATU) sowie die in der Bestellung genutzte Währung (WAERS) und die für den Buchungskreis hinterlegte Hauswährung (T001_WAERS). Es fällt auf, dass der in der Bestellung hinterlegte Wechselkurs von 555,00000 bzw. 333,00000 sehr deutlich von dem im System standardmäßig vorgegebenen Kurs von „1,12145-“ abweicht. Darüber hinaus sollten bei Bestellungen vom 30/31. August 2018 (Datenfeld AEDAT) Wechselkurse vom 08.05.2015 (Feld TCURR_GDATU) herangezogen werden. Kurzum – 2 Fragen gilt es zu klären – warum werden im System hinterlegte Kurse nicht genutzt und wie ist überhaupt der Prozess zur Pflege der Wechselkurse im SAP System aufgesetzt?
Warum lassen Sie nicht zap Audit arbeiten?
Wenn Ihnen das zu technisch ist: zap Audit enthält genau für die geschilderten Fälle der Wechselkurse bereits einen Indikator im beta Status. Probieren Sie es aus: Für kleine Buchungskreise ist zap Audit kostenfrei und wir zeigen Ihnen vorab gerne, wie Sie zu Ihren Analyseergebnissen kommen.