Kategorien
Randnotiz Schulung

Windows: Active Directory Export in LDAP

Ein Export von Daten aus dem Microsoft Active Directory im ldif Format ist in der realen Welt eigentlich unbrauchbar. Die Bezeichnung vieler Organizational Units (OU) sind nicht Standardkonform. Für den Import der Daten in ein LDAP Verzeichnis fehlen auch Angaben.

Für die Textmanipulation eignet sich ein Bash Script hervorragend. Was aber, wenn man dem User keinen Einblick gewähren möchte und die zu importierende Datei mehrere zehntausend Datensätze enthält?

Das Standard C – ANSI C – bietet eine Fülle an Werkzeugen zur Text- und Dateimanipulation. In dem Listing (Link) sind mehrere verschiedene Möglichkeiten verwendet.

Aufgabe war, eine Datei aus dem AD im ldif Format einzulesen, das Schema zu verändern und die OU sAMAAccountName, organizaltionalPerson und weitere zu ersetzen, eine gidnumber, member sowie ein userpassword einzusetzen. Das Passwort muss LDAP konform als salted SHA, mehr oder weniger, zufällig generiert werden.

Spielen wir in den nächsten Clubtreffen ein bisschen an den Befehlen die Zeichenweise (fgetc) oder Wortweise (fgets) Strings verarbeiten. Auch habe ich verschiedene Varianten des Filehandlings programmiert.

Kategorien
Randnotiz Schulung

C: SSHA1 Code mit RND SALT

Generierung von Passwörtern z.B.

SALT="$(openssl rand 3)"
SHA1="$(printf "%s%s" "$PASSWORD" "$SALT" | openssl dgst -binary -sha1)"
printf "{SSHA}%s\n" "$(printf "%s%s" "$SHA1" "$SALT" | base64)"

Mit den 3 Zufallszahlen habe ich mir keinen Gefallen getan. Mit dem zusammensetzen des Strings mit printf bewegen wir uns um lesbaren Bereich des ASCII Code!

Mit der Zeile 2 erhalten wir einen 20 Byte SHA1 Code. Wenn wir jetzt in Zeile 3 das SALT anfügen und vorher die Zufallszahlen 0 8 erzeugt wurden, bedeutet das „Backspace“ womit der SHA1 Code zerstört ist.

Es ist darauf zu achen, das wir im lesbaren Bereich bleiben oder Ziffern verwenden. Hiermit funktioniert eine Massengenerierung von LDAP SSHA1 Passwörtern

#!/usr/bin/perl
#
use Digest::SHA1;
use MIME::Base64;
my @chars = ("A".."Z", "a".."z");
my $salt;
$salt .= $chars[rand @chars] for 1..3;
$ctx = Digest::SHA1->new;
$ctx->add(@ARGV);
$ctx->add($salt);
$hashedPasswd = '{SSHA}' . encode_base64($ctx->digest . $salt);
print $hashedPasswd;
Kategorien
Allgemein Schulung

Twenex DEC System

DEC DECSystem 20

Seit simh (Link) ist es problemlos, konvertierte Reel-Tapes, Lochkarten, Paper-Tapes und Wechselplatten auf unixoiden Systemen zu simulieren.

Umfangreiche Manuals und Sammlungen an Betriebssystemen, Programmiersprachen und Programmen finden sich hier (Link)

Auch ohne eigene Server, sind die Ressourcen öffentlich nutzbar. Ich habe jeweils einen Account hier (Link) und hier (Link).

Wir werden uns intensiv mit den damals üblichen File basierten Datenbanken kümmern. Programm und Datenmigration und / oder Herstellung von Schnittstellen sind heute immernoch große Themen.

Aktuell, August 2020, beschäftige ich mich mit IBM AS/400 (i Series) und der Programmierung in RGP, PL/1 und COBOL. Da vieles von dem heute nicht mehr gelehrt wird, sind IT-Warhorses gefragt wie nie.

Kategorien
Randnotiz Schulung

Windows: Favoritenspeicher RDP Client

Nicht immer von Vorteil, wenn die letzten erfolgreichen Verbindungen des RDP Clients dauerhaft gespeichert werden.

Die Verbindungen und der angemeldete Nutzer lassen sich in der regedit löschen. Einfach aber mit einem kleinen Batchfile:

@echo off
reg delete „HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default“ /va /f
reg delete „HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers“ /f
reg add „HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers“

Kategorien
Allgemein Schulung

Excel: OLC in der Logistik

Im Vergleich zur Adresse und der Standortangabe durch Grad,Minuten und Sekunden, bezeichnet der OLC einen relativ genauen Punkt auf der Erde. Dazu werden eindeutig lesbare, einfache Kombinationen von Zahlen und Buchstaben verwendet. Eindeutig lesbar bedeutet, dass keine Zeichen verwendet werden welche verwechselt werden können. Z.B. 1 und I oder 5 und S.

Das System – erklärt in dem Link – teilt Breiten- und Längengrad in 20tel Teile. Die Wertpaare können so einfach bis zur gewünschten Genauigkeit addiert werden – bis zur theoretischen 3 x 3 Meter Auflösung.

Der Vorteil liegt ganz klar darin, das benachbarte Zellen schneller lokalisiert werden können, als wären sie im Grad, Minuten, Sekunden System oder gar als Postadresse angegeben. In der Planung von Fahrplänen, Relationen in der Logistik ergeben sich erhebliche Vereinfachung durch das logische Raster.

Kategorien
Allgemein Schulung

Postfix: AMAVIS Filter

Aus gegebenen Anlass, noch einmal die Standardlösung: Zum Internet hin, ist es ratsam nur solide und erprobte Mailserver einzusetzen. Ich kenne nur zwei: Postfix und Exim.

Sie bilden das Schutzschild und verteilen Mails sicher an alle weiteren Anwendungen. Postfix und auch Exim kann problemlos mit einem oder mehreren Spam- und Contentfiltern, Virenscannern und eigenen Transportregeln gesteuert werden.

In letzter Zeit werden bösartige Mails mit Office Dateien im Anhang verschickt. Diese Officedateien beinhalten VBA Code und können in schlecht administrierten System ausgeführt werden und so das ganze System zerstören.

Konfigurationsdatei AMAVIS Spamfilter

Ich verbiete meinem Postfix über entsprechende Regel im AMAVIS Contentfilter die Annahme solcher Mails. Es existiert nicht EIN Grund, Officedateien per Mail zu verschicken.

Kategorien
Schulung

Lexware: DATEV Export Abschlagsrechnung

Steuerprüfungen rücken schon einmal die Dinge in das „richtige“ Licht und können lehrreich sein. Auf eine Sache will ich kurz eingehen:

In Lexware Faktura kann eine Abschlagsrechnung erstellt werden, die dann nach Fertigstellung des Gewerks, in einer Rechnung verrechnet wird. So weit, so gut.

Eine Abschlagsrechnung ist als eine a Conto Zahlung auf das Debitorenkonto zu betrachten. Sie ist KEIN Umsatz, es stellt eine Verbindlichkeit gegenüber dem Debitoren dar – Also, ein Guthaben des Kunden.

Problematisch wird es dann, wenn auf der Abschlagsrechnung eine Umsatzsteuersteuer erhoben wird und die Hauptrechnung nicht in der Periode der Abschlagsrechnung erstellt wird. Die Umsatzsteuer wird dann in dieser Periode fällig gegenüber dem Fiskus.

Der DATEV Export im Lexware Faktura, exportiert nur steuerrelevante Belge des Typs Rechnung (RG) und Gutschriften (GS), eben keine Abschlagsrechnung (AR)! Das heisst, wird nach DATEV Liste gebucht, wird die Umsatzsteuer für diese Zeit bis zur Hauptrechnung möglicher Weise hinterzogen! Im DATEV Export findet man nur die Hauptrechnung mit vollem Betrag und lediglich auf dem Beleg selbst, wird die Abschlagsrechnung von der zu zahlenden Summe subtrahiert.

Das Verhalten des Lexware ist vollkommen korrekt. Die Abschlagsrechnung ist kein Beleg im steuerrechtlichen Sinn – der Benutzer begeht den Fehler, in dem er auf der Anzahlungsanforderung eine Steuer ausweist.

Kategorien
SAP Schulung

SAP und Agorum als DMS Lösung

Es sind Umstände vorstellbar, in denen die Integration von Belegen in das SAP System garnicht gewünscht sind. Große Steuerberater erhalten die Belege als Scan von ihren Mandanten und ein kopieren in das SAP eigene DMS, dem SAP Content Server, ist garnicht gewünscht. Es ist aber Standard, die Originalbelege zum Systembeleg abzulegen, zumindest eine Referenz herzustellen. Das Belegfeld „Referenznummer“ dient zur Aufnahme der Fremdbelegnummer und hat im weiteren Belegprozess eine Bedeutung. Das vermerken der Systembelegnummer auf dem Originalbeleg ist angeraten und wird in der Praxis meisst per Hand vollzogen.

Wenn ich mit meinem Lieblings-DMS, dem von Agorum, arbeite, arbeite ich auf zwei Bildschirmen. Links ist die Buchungsmaske, rechts das Dokument. Wenn ich links buche, wird eine Systembelegnummer generiert die ich rechts auf dem Originalbeleg vermerken sollte. So ist ein suchen und finden von Belegen von beiden Applikationen aus möglich.

Das gilt es zu automatisieren. Ich will dabei garnicht zu sehr ins Detail gehen, etwas Vorkenntnis setze ich voraus – im Zweifel fragen!

Möglichkeiten, in die SAP Software manipulativ einzuwirken, gibt es viele. Eine sehr schöne und einfache Möglichkeit sind BTE’s ( Business Transaction Events ).  Der Name lässt schon auf die Systematik schliessen: In den Arbeitsprozessen werden zu bestimmten Zeitpunkten, einfach gesagt, nach geschaut, ob der Kunde an diesem Punkt eigenen Programmcode ablaufen lassen möchte. Wirklich sehr einfach dargestellt!

Solche Eventtimes existieren in jedem Arbeitsprozess und zu mehreren sinnvollen Zeitpunkten. Den richtigen Zeitpunkt zu finden, kann in stundenlangen Suchorgien ausarten. Wenn man aber das Wochende mit dem austesten glücklich verbracht hat, hat man etwas gelernt. Kurz: Für unsere Zwecke hat sich der Zeitpunkt 1030 ganz anständig vorgestellt. Wir sprechen von einem Zeitpunkt im Arbeitsprozess „Beleg buchen“ welcher nach der Belegprüfung und nach dem „speichern“ aber vor dem COMMIT WORK liegt. Zu diesem Zeitpunkt steht fest, das und mit welcher Belegnummer gespeichert wird. Im Dictionary befinden sich für jeden Zeitpunkt ein beispielhafter Funktionsbaustein der in seinen Parametern nicht verändert werden darf. Dieser wird in den eigenen Namensraum kopiert. ( Listing )

Bevor es an die Programmierung geht, kurz ein Gedanke zum pro cedere. Der Buchhalter bucht, zum Beispiel, über die FB50 Belege ein. Dort stehen uns Felder für den Belegkopf zur Verfügung. Wenn wir nun eine Verbindung zu einem externen Originalbeleg herstellen wollen, bedient man sich allgemein dem Referenzfeld. Wie schon weiter oben gesagt, hat das Feld eine Aufgabe. Nämlich die, der Zuordnung beim maschinellen Ausgleich. Im Agorum DMS liegt ein File, mit einem Namen und einer Objekt ID. Hier können wir also keine einfache Verbindung zwischen Systembeleg und Originalbeleg assoziieren. Ich habe es ersteinmal so gelöst, ohne Programmierung von kundeneigenen Feldern, das Feld „Belegkopftext“ Zweck zu entfremden.

Dazu habe ich eine neue Belegart „AG“ erstellt und das Feld  „Belegkopftext“  zum Mussfeld gemacht. Damit ist zwingend das Feld mit der Objekt ID des im Agorum DMS befindlichen Originalbelegs zu befüllen.

Wenn nun die Buchung verbucht wird, kommt es zum Event 1030 zu dem die Belegkopfdaten als Notiz an den Originalbeleg im Agorum DMS hinzu gefügt werden sollen. Dazu stellt Agorum eine REST API zur Verfügung. Über URL mit POST/GET angesprochen, wird eine Antwort per XML zurück gegeben. Im SAP System bediene ich mich dazu der Klasse CL_HTTP_CLIENT. ( Listing )

Wir sehen in den Zeilen 45 bis 65 das zunächst der http Client initialisiert  und eine Session ID angefordert wird. Die lokale Variable lv_bin enthält nun die XML Antwort von Agorum als XSTRING und wird in den Zeilen 95 bis 100 in eine itab gelesen. Beim programmieren kommt man nicht ohne Debugger weiter, denn der Aufbau des XML ist nicht klar. Das Ergebnis wird schlicht als „value“ übertragen und hängt demnach von der Anforderung ab. Werden mehrer Anforderungen gestellt, heißen alle Werte „value“.

Die Zeilen 80 bis 93, das Suchen nach dem Filenamen, hat zwei Gründe: Es kann eine Tabelle aufgebaut werden, in der die Verbindung Objekt ID, Filename und Systembelegnummer protokolliert wird. Und es war nicht möglich, nach dem Abfragen der Session ID direkt die Notiz zu generieren. Es kommt ohne vorheriges GET vor dem POST zur Fehlermeldung seitens Agorum DMS.

In den Zeilen 112 bis 135 wird es haarig. Uns stehen an dieser Stelle alle Daten zur Verfügung: Objekt ID, Session ID und Belegdaten. Diese müssen als escaped JSON formatiert werden. Nach dem senden ist die Zeile 142 entscheident. Erfolgt nach dem send kein receive, wird die Notiz nicht erstellt.

Dieser neue kundeneigene Funktionsbaustein ist nun, nach dem aktivieren, dem Event zu zuordnen. Über die Transaktionen BF24 und BF34 können wir unser Produkt ersteinmal benennen, aktivieren und einem Zeitpunkt, hier 00001030, zuordnen.

Das Ergebnis ist, das wir im SAP System an der Belegart und dem Belegtext erkennen, das es einen Originalbeleg im Agorum DMS gibt. Im Agorum DMS können wir schnell an der vorhandenen Notiz erkennen, das eine Buchung im SAP System vorgenommen wurde. Im Detail können wir nach Systembelegnummern, Buchungsdatum usw. suchen.

Eine einfache und praktikable Lösung.

Kategorien
SAP Schulung

SAP Zinsrechnung – Verwendbarkeit

Kann man das Beispiel aus meinem Beitrag (Link) so übernehmen? Nein!

Natürlich darf der Code hier kopiert werden. Alle Code sind aber nur Beispiele und Arbeitsvorlagen. Nicht zuletzt existiert die Seite, weil sie auch mir als Merkhilfe für bestimmte Dinge dient.

Bei einer Zinsrechnung ist darauf zu achten, für wen ich was rechne! In unserem Beispiel wird der Zins vom Zins mit berechnet. Das ist nach §289 BGB nicht zulässig. Auch ist die Frage ob eine lineare Berechnung gefragt ist. Also, ist der Code in jedem Fall an die Bedürfnisse anzupassen und niemals blind zu kopieren und produktiv zu nutzen!

Zinsrechnung unter Beachtung 286BGB ( kein Zins vom Zins )

In dem Listing (Link) ist die Zeile 112 fraglich. Nimmt man sie heraus und bildet über das ALV eine Aggregation, ist diese Rechnung rechtlich korrekt für Kredite nach Effektivzinsmethode mit Zinsaufschlag auf den Leitzins unter Berücksichtigung, das der Zins nicht vom Zins gerechnet wird.

Aufbau des ALV mit Summenaggregation

Kategorien
SAP Schulung

SAP Zinsrechnung

Die Zinsrechnung ist weitaus mehr als Zins = Betrag * Zinssatz / 100. Es tauchen Fragen auf wie: Ist der Zins in einer Periode linear oder exponentiell verteilt. Ist der Zinssatz auf 365 oder, banküblich, auf 360 Tage zu verteilen. Und, und, und. Aus dem Schaubild der SAP geht das Prinzip hervor, wie und womit die Zinsrechnung im System realisiert wird.

SAP Zinsrechnung
Copyright by SAP

Tabelle Leitzins T056B
Tabelle Leitzins T056B

In der Realität wird zur Bestimmung eines Zinssatzes u.a. die Tabelle T056P befragt, in der auch der EZB Leitzins abgespeichert ist. In dem Schulungssystem des letzten Workshops war die Tabelle leer, weshalb ich sie mit den Echtdaten der EZB gefüllt habe.

An der Stelle ist schon der Typ des Datenelementes zu beachten: Der Zins ist vom Datentyp DEC, 10 Zeichen lang davon 7 Nachkommastellen und entspricht dem ABAP Datentyp p (packed). Das ist wichtig in Bezug auf die Nutzung der im ersten Bild angesprochenen Funktionsbausteinen, die als Importparameter für den Zinssatz den ABAP Datentyp f (float) voraus setzen! An der Stelle habe ich meinen Teilnehmern das Nachschlagen unter dem  Stichwort „Festpunktarithmetik“ anheim gestellt, denn das habe ich zur Erhöhung des Spaßfaktors deaktiviert! Die Folgen können hier nachgelesen werden. (Link).

Zunächst aber die Problematik in der Betrachtung des Zeitraums: Eine Bank rechnet nicht nach Kalendar. Ein Jahr hat für die Bank 360 Tage, ein Monat immer 30 Tage. Es hat den Vorteil, das man über Schaltjahre garnicht erst nachdenken muss. Ein Zeitraum, also die Anzahl Tage zwischen zwei Daten, ist einfach zu programmieren. Der Datentyp DATS, ABAP Datentyp d, ist ein CLIKE also ein Feld vom Typ  Like Charakter. Das Format ist „YYYYMMTT“. Es lässt sich mit den Werkzeugen der Stringmanipulation, dem Textoffset, bequem auslesen und auch Rechenoperationen sind systemseitig realisiert. So funktioniert „TAGE = DATUM2 – DATUM1“ genau so wie „Monate = DATUM2+4(2) – DATUM1+4(2)“. Genau das wird mit dem Funktionsbaustein FIMA_DAYS_BETWEEN_TWO_DATES realisiert, dem wir uns problemlos bedienen können. Die Berechnung nach Bankstandard ist auch hier Standard!

In dem Listing (Link) ist in Zeile 29 zu sehen, das der Datumswert, wie auch in der Tabelle T056P, als invertiertes

28.07.2018 und 01.01.2020 Normal und invertiert
28.07.2018 und 01.01.2020 Normal und invertiert

Datum erfasst wird. Nach der Konvertierung suchen wir aus der Tabelle den zum Startzeitpunkt gültigen Zinssatz und addieren den in Zeile 30 abgefragten Zinswert welcher über dem Leitzins errechnet werden soll.

Stehen die Parameter Basisbetrag, Startdatum und Zinssatz soweit fest, kann der Zins mit dem Funktionsbaustein FIMA_INTEREST_COMPUTE errechnet werden. Schauen wir in die Zeile 102 auf den Importparameter i_pzins. Der Datentyp ist f (float). Mit ausgeschalteter Festpunktarithmetik wird jetzt,  schon beim Casting der Werte, der Wert mit dem Typ DEC als Ganzzahl interpretiert. Wir sagten: DEC 10 Stellen, 7 Dezimal. Wenn der Wert vorher 10,1000000 war, ist er jetzt 101000000. Genau DAS passiert in Zeile 96. In Zeile 97 ist eine mögliche Korrektur, nämlich die Division mit 10000000 – das Komma um sieben Stellen verschoben. Statt solcher unschönen Klimmzügen, geben wir die Werte einem Funktionsbaustein in dessen Funktionsgruppendefinition die Festpunktarithmetik aktiviert ist. Dieser Funktionsbaustein Y_ZAHL übergibt schlicht den Wert mit dem Typ p (packed) and den Typ f (float) unter Beachtung des Dezimaltrenners.

Die Daten so, korrekt, dem Funktionsbaustein FIMA_INTEREST_COMPUTE übergeben, wird unter Beachtung der Zinsrechnungsmethode ( Standard ist die lineare Verteilung auf 360 Tage ) und des Verteilungsquotient ( Tage / Basistage ) der Zins errechnet.

entscheidende Formel im FB FIMA_INTEREST_COMPUTE
entscheidende Formel im FB FIMA_INTEREST_COMPUTE

In Zeile 115 bauen wir so unsere Tabelle auf, die durch den Loop in den Zeilen 45 bis 121, maximal soviele Zeilen aufweist wie auch Zinssätze in der Tabelle T056P vorhanden sind. Im Echtsystem ist das Vorgehen so nicht empfehlenswert, da die Tabelle im Normalfall mehr als 88.000 Einträge hat.