Kategorien
Schulung

Python: Automatisierung Belegablage

Belege scannen und archivieren ist Dauerthema in der Systementwicklung. In den Workshops taucht schon einmal die Frage nach den Diensten für automatisierte Belegverarbeitung auf. Also: Belege scannen, verbuchen und archivieren. Natürlich habe ich mich damit vor längerem beschäftigt – nehmen wir das als neuen Workshop im CCGL auf.

Ich persönlich halte nicht viel davon, da es doch sehr fehleranfällig ist. Die Systeme müssen ständig trainiert und kontrolliert werden. Auch in Top-Systemen beschäftigt sich der Buchhalter mit Korrekturbuchungen wenn die Belege tatsächlich als Papier mit der Snail-Mail im Unternehmen ankommen. Ich zeige auch warum; meine Gedanken möchten Initalfunke für den Workshop sein. In der Realität arbeiten wir immer öfter mit der eRechnung.

Zwei Wege zur automatischen Verarbeitung sehe ich. Die bekannten Dienste lesen Kreditor, Belegnummer, Belegdatum und Summe aus dem Beleg. Wie findet man die Angaben?

Die einfach Art lehnt sich an eine schon früher besprochene Vorgehensweise an (Link). Der Scan liegt da als Fließtext vor. Mit entsprechenden awk und perl Scripten können Schlüßelwörter gefiltert werden.

Die anspruchsvollere Lösung habe ich vor 15 Jahren programmiert und wurde produktiv genutzt. Es basiert auf der Vermutung, das die wesentlichen Angaben einer Rechnung oft an der selben Stelle zu finden sind. Es existiert eine Norm (Link).

Beispielrechnung mit markiertem Feld Belegart und Nummer

Schauen wir uns den Beispielbeleg an. Der Beleg hat eine Breite und eine Länge in Pixeln. Anstatt den gesamten Text zu durchsuchen, kann ich auch nur einen definierten Ausschnitt betrachten. Wird nur der Ausschnitt gelesen, haben wir Belegart und Belegnummer. Hier verwende ich Python – sehr flexibel und eigentlich selbsterklärend:

from pdf2image import convert_from_path
image = convert_from_path("test.pdf")[0]


import pytesseract
import re
snummer = re.compile("[^0-9]")
sbart = re.compile("[^a-zA-Z]")

beleg = image.crop((52,500,800,600))

text = pytesseract.image_to_string(beleg)

def sauberenummer(text):
	text = re.sub(snummer,"",text)
	return text

def sauberebeleg(text):
	text = re.sub(sbart,"",text)
	return text	

print(sauberebeleg(text))
print(sauberenummer(text))

Schauen wir in Zeile 10: direkte Position des Ausschnitts in Pixel! Also Beginn x,y und Ende x,y in absoluten Pixeln. Zum Beispiel GIMP zeigt die Cursorposition in der Statusleiste in Pixeln an. Produktiv würde ich mit dem Verhältnis zur Gesamtgröße arbeiten. pytesseract ist nicht so flexibel wie das Paket tesseract selbst, dennoch sehr schnell und sicher.

Python und tesseract lesen Belegart und Nummer

Ich wende hier zum lesen zwei verschiedene Filter an. Zeile 7 definiert einen Filter der nur Zahlen zwischen 0 und 9 zurück gibt – Zeile 8 nur Buchstaben ohne Umlaute. Die Funktionen in den Zeilen 14 und 18 wenden den Filter an und ersetzen jedes andere Zeichen durch „“ (Nichts).

Hier sehen wir die Problematik. „BarverkaufNr“ ist keine Belegart. Es müssen einige Routinen geschrieben werden um hier eine Rechnung verarbeiten zu können. Die Belegnummer kann so weiter verarbeitet werden.

Ich bin sehr gespannt auf Eure Vorschläge!

Kategorien
SAP

SAP Content Server 6.4 auf SLES 11

Die Themen Dokmentenmanagement und Dokumentenarchiv sind im SAP System extrem komplex implementiert. Ganz bestimmt kein Thema, auf das man „mal eben“ in einem Blog eingeht.

Zu den bestehenden offiziellen Installationsanleitungen ( unter anderen: LINK ), bin ich über diese Kleinigkeiten gestolpert:

VOR der Installation (!!) sollten die User angelegt werden:

sapcs ( für den Content Server ) und sapcsc ( für den Cache Server ) in Gruppe sapsys.

In deren Homeverzeichnis ist dann jeweils ein Apache2  2.2 zu compilieren. Wer mag kann andere Apacheversionen ausprobieren – habe ich gemacht und sage: Apache2 2.2

Apache2 2.2 Installation in Homedirectorys von SAPCS und SAPCSC

Zuerst das configure ausführen. In jedem Verzeichnis:

./configure –prefix=/home/sapcsc/ –enable-mods-shared=most –with-mpm=prefork –with-expat=builtin –with-included-apr –with-included-apr-util

und dann

make && make install

Im Browser sollte, nach dem Start des Servers, der Server und der Cache erreichbar sein

Schauen wir uns demnächst die vielen Möglichkeiten, den Content Server zu nutzen, an.

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
Allgemein

GoB konforme Mailarchivierung

Mails, im gewerblichen Verkehr, sind aufbewahrungspflichtige Dokumente. Es ist ein Spagat zwischen Pflichterfüllung und Geheimhaltung: Postfächer in Firmen werden mit Werbemails überschwemmt und gelegentlich werden Mails privater Natur oder mit brisantem Inhalt versendet.

Dem User kann aber nicht die Entscheidung darüber, welche Mail ist Wichtig, welche kann gelöscht werden, überlassen werden. Es muss seitens des Systems sicher gestellt sein, das eine Mail zu jeder Zeit verfügbar ist.

Es ist, genau genommen, eine Verletzung des Postgeheimnisses. Mails an einen bestimmten Empfänger, werden für Andere sicht- und lesbar. Es ist also Aufgabe des Administrators hier mit äussester Vorsicht und Verschwiegenheit, bedacht vor zu gehen.

Von Seiten des Mailservers ist es schon immer vorgesehen gewesen, Mails an einen BCC (Blind Carbon Copy) zu senden. Mit der Direktive „always_bcc = user@archiv.tld“ wird jede Mail, die rein oder raus transportiert wird, in Kopie versendet. In der Transporteinstellung ist es zu empfehlen, für das Agorumarchiv eine ausschließlich intern bekannte und erreichbare Mailadresse einzurichten, denn die Mail in einem IMAP Postfach zu lagern, macht keinen Sinn.

In der täglichen Praxis ist es so, das Sender- und Empfänger abhängig weiter geleitet wird. Auf dem aktuellen HALSYSTEM Server werden eine vielzahl an privaten und gewerblichen Mails verarbeitet; oft ist eine Archivierung weder notwendig noch gewünscht. Die Einrichtung von sender_bcc und recipient_bcc Hash Tabellen ist unablässig. Es hat sich bewährt, im Agorum für jedes Archiv einen User mit eigener ACL ein zu richten. Mit Hilfe der Mailregeln lassen sich Ordner für bestimmte Zwecke einrichten und einer oder mehreren bestimmten Gruppe Usern zur Verfügung stellen.

Innerhalb des Agorumarchivs kann es verschiedene Lösungen geben. Es ist nicht sinnvoll, das Archiv allen Usern zur Verfügung zu stellen. Wie erwähnt, verstoßen wir gegen das Postgeheimnis, sodass EINEM User – nämlich der, der die Postfächer sauber hält – Zugang gewährt wird. Wenn nötig, können bestimmte User lesenden Zugriff mit der Einrichtung entsprechender ACL, erhalten. Agorum beherrscht die Kunst, Mails untereinander in Beziehung zu stellen und auch Belege mit einer Mail zu verlinken.

So ist es ein äußerst produktiver Nebeneffekt, das zum Beispiel, eine Kundenbestellung per Mail mit der Ausgangsrechnung im Archiv miteinander verknüpft werden können. Sucht man also entsprechenden Beleg, findet man auch stets die passende Mail dazu. Da der User grundsätzlich keine Löschrechte hat und auch nichts verändern kann, ist ein solches Archiv revisionssicher.

Kategorien
Allgemein

SAP und Agorum DMS

Die SAP-Integration von agorum® core verbindet Ihr Dokumentenmanagement-System über den SAP ArchiveLink nahtlos mit Ihren Anwendungen in SAP. So nutzen Sie alle Vorteile eines systemübergreifenden Dokumentenmanagements.

Link