Entdecken Sie eBooks
Kategorien
Entdecken Sie Hörbücher
Kategorien
Entdecken Sie Zeitschriften
Kategorien
Entdecken Sie Dokumente
Kategorien
Analyse, Design und Implementierung einer Softwarekomponente als Schnittstelle einer Schlagdokumentationssoftware zur Datenbermittlung an Bio mit Gesicht.
Zur Erlangung des akademischen Grades eines Bachelor of Science - Wirtschaftsinformatik-
Fakultt Informatik Referent: Prof. Dr. Oliver Braun Koreferent: Prof. Dr. Dietmar Beyer eingereicht von: Alexander Bonin Matr.-Nr. 280395 Hans-Loch-Strae 38 99099 Erfurt Schmalkalden, den 29.09.2011
Zusammenfassung Warenrckverfolgbarkeit bei Lebensmitteln welches mit zunehmender Komplexitt der Warenstrme und den steigenden Anforderungen des Gesetzgebers immer wichtiger wird. Im Rahmen dieser Arbeit soll eine Mglichkeit geschaen werden Landwirten, ber eine Schlagdokumentationssoftware, die Teilnahme an einem solchen System zur Warenrckverfolgung zu ermglichen.
Danksagung An dieser Stelle mchte ich mich bei allen bedanken, die mich bei der Anfertigung dieser Bachelor-Thesis untersttzt haben. Zunchst mein Dank den beiden Korrektoren Prof. Dr. Oliver Braun und Prof. Dr. Dietmar Beyer, die dieses Thema problemlos und unkompliziert von einem anderen Professor bernommen haben. Des weiteren mchte ich mich bei Eckehart Klingner, Andrea Mckel und Marko Espig von der Ibykus AG bedanken welche mir diese Arbeit ermglicht, und mich ber den gesamten Zeitraum betreut und untersttzt haben. Nicht zuletzt mchte ich mich bei meinen Eltern bedanken die mir das Studium ermglicht und mich moralisch untersttzt haben.
Inhaltsverzeichnis
1 Grundlagen 1.1 berblick . . . . . . . . 1.2 Schlagdokumentation . . 1.3 Warenrckverfolgbarkeit 1.4 Bio mit Gesicht . . . . . 1.5 XML . . . . . . . . . . . 1.6 Webservice . . . . . . . . 1.7 SOAP . . . . . . . . . . 1.8 AgroXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 1 1 2 2 3 3 5 6 6 6 6 7 7 8 8 8 8 10 10 10 11 11 12 12 13 13 14 14 15 15
2 Anforderungsdenition der Software 2.1 funktionale Anforderungen . . . . . 2.1.1 Technische Spezikation . . 2.1.2 Programmablauf . . . . . . 2.2 Nicht funktionale Anforderungen . 2.3 Wirtschaftlichlichkeitsbetrachtung . 3 Entwurf 3.1 Architektur . . . . . . . . . . . . 3.2 Verwendete Werkzeuge . . . . . . 3.3 Verwendetes Framework . . . . . 3.4 Kommunikationsschnittstellen . . 3.4.1 Auth - Login . . . . . . . 3.4.2 Auth - Logout . . . . . . . 3.4.3 Daten - Synchronisierung . 3.4.4 Daten - Senden . . . . . . 3.4.5 Daten - Lschen . . . . . . 3.5 Struktur der Daten in Elsa-ko . 3.6 Flussdiagramme . . . . . . . . . . 3.6.1 Anmeldediagramm . . . . 3.6.2 Abmeldediagramm . . . . 3.6.3 Synchronisationsdiagramm 3.6.4 bertragungsdiagramm . . 3.6.5 Lschdiagram . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
Alexander Bonin
IV
Inhaltsverzeichnis
4.2
4.1.3 GetFunction . . . . . . . . . . . . . . . 4.1.4 test_bmg . . . . . . . . . . . . . . . . 4.1.5 sync_bmg . . . . . . . . . . . . . . . . 4.1.6 send_bmg . . . . . . . . . . . . . . . . 4.1.7 del_bmg . . . . . . . . . . . . . . . . . 4.1.8 sendmarked_bmg . . . . . . . . . . . . DLL-interne Funktionen und Methoden . . . . 4.2.1 XML Builds . . . . . . . . . . . . . . . 4.2.2 XML Response . . . . . . . . . . . . . 4.2.3 XML Transfer . . . . . . . . . . . . . . 4.2.4 XML in String Umwandlung . . . . . . 4.2.5 String in XML Umwandlung . . . . . . 4.2.6 Netzverfgbarkeit . . . . . . . . . . . . 4.2.7 Mapping von Einheiten . . . . . . . . . 4.2.8 Prfen auf Verfgbarkeit eines Wertes 4.2.9 Suchen der Bio mit Gesicht ID . . . . .
5 Fazit Literaturverzeichnis A Quellcodelistings A.1 BMGModul.h . A.2 BMGModul.cpp A.3 functions.h . . . A.4 functions.cpp . A.5 structs.h . . . . A.6 xml_builds.h . A.7 xml_builds.cpp A.8 xml_results.h . A.9 xml_results.cpp
B Anhang 90 B.1 Telefonprotokoll Bio mit Gesicht . . . . . . . . . . . . . . . . . . . . . 90 B.2 Bio-mit-Gesicht Schnittstellenbeschreibung . . . . . . . . . . . . . . . 90 Eidesstattliche Erklrung 95
Alexander Bonin
1 Grundlagen
Diese Arbeit soll den Analyse-, Design- und Entstehungsprozess eines Plugins dokumentieren, welches eine Schlagdokumentationssoftware um eine Schnittstelle an ein Warenrckverfolgbarkeitssystem erweitert.
1.1 berblick
Im ersten Kapitel werden die Grundbegrie geklrt, die diese Arbeit betreen. Dazu zhlen die grundstzlich eingesetzten Technologien, sowie die Begriserklrungen aus dem Umfeld, in dem die Schnittstelle laufen soll. Kapitel zwei gibt einen berblick ber die funktionalen und nicht funktionalen Anforderungen, die an die Schnittstelle gestellt werden, sowie eine kurze wirtschaftliche Betrachtung des Sachverhalts. Der Entwurf in Kapitel drei, stellt die Architektur der Schnittstelle dar, sowie alle in Verbindung mit der Schnittstelle verwendeten Technologien. Das Kapitel vier beschftigt sich ausschlielich mit der Implementierung der Schnittstelle. Hier werden zur Erluterung Quellcodelistings der entworfenen Funktionen der Schnittstelle herangezogen. Im Folgenden werden die Grundlagen zu dieser Arbeit geklrt.
1.2 Schlagdokumentation
Unter einer Schlagdokumentation oder einer elektronischen Schlagkartei versteht man die Aufzeichnungen aller Manahmen auf einem Schlag1 (Feld- oder Wiese) und ber die Ergebnisse der Bodenuntersuchungen. Damit kann der Landwirt den weiteren Anbau planen und nach der Ernte eine entsprechende Erfolgskontrolle vornehmen.2
1.3 Warenrckverfolgbarkeit
Warenrckverfolgbarkeit ist ein Begri der in der Gesamten Lebensmittelwirtschaft Verwendung ndet. Die Rckverfolgbarkeit dieser Waren bildet allerdings meist nur den Vorgang im Unternehmen selbst ab. Ziel einer vollstndigen Warenrckverfolgbarkeit ist die Abbildung der gesamten Wertschpfungskette. Eine Abbildung vom Hersteller zum Konsumenten bezeichnet man als Downstream Tracking oder auch
1 2
Eine zusammengehrige Ackerche, die mit nur einer Feldfrucht bestellt ist. http://www.agrilexikon.de/index.php?id=973
Alexander Bonin
Seite 1 von 95
1. Grundlagen
abwrtsgerichtete Verfolgung. Die Abbildung der Wertschpfungskette vom Konsumenten bis zum Erzeuger wird als Upstream Tracking oder aufwrtsgerichtete Rckverfolgung bezeichnet. Ziel dieser Abbildungen ist es jede Phase des Inverkehrbringens von Waren verfolgen zu knnen. Dies erleichtert zum einen die Qualittssicherung und den Warenrckruf. Hat der Endverbraucher die Mglichkeit die Wertschpfungskette einzusehen so strkt dies das Vertrauen in das jeweilige Produkt.3
1.5 XML
Mit XML5 ist ein Format geschaen worden das Informationen durch Auszeichnungselemente kennzeichnet, und sich so hervorragend fr den universellen Datenaustausch eignet.6 Diese 1998 von der W3C7 , in der Version 1.0, verabschiedeten Spezikation ist sowohl mensch- als auch maschinenlesbar. XML gibt keine Auszeichnungselemente vor. Jeder kann seine Auszeichnungselemente selbst denieren. Jedoch gibt XML eine klare Struktur vor, an die man sich beim Denieren eigener Auszeichnungselemente halten muss. Dieses Vorgehen reduziert die Komplexitt des Codes und die Mglichkeit Fehler zu beheben. Im Folgenden Listing 1.1 bendet sich ein Beispiel: Listing 1.1: XML Beispiel <Nachricht> < U e b e r s c h r i f t > E i n f a c h e s Dokument< / U e b e r s c h r i f t > <Text >Dies i s t der < u n t e r s t r i c h e n > w i c h t i g e < / u n t e r s t r i c h e n > I n h a l t . < / Text > < / Nachricht>
3 4
Vgl. [Ges] Vgl. [Bio] 5 EXtensible Markup Language 6 Vgl. [Bec09] 7 W3C - World Wide Web Consortium
Alexander Bonin
Seite 2 von 95
1. Grundlagen
Der Tag <Nachricht> markiert den Beginn und der Tag </Nachricht> das Ende des gesamten Dokuments. Hierbei muss darauf geachtet werden, dass jeder genete Tag auch wieder geschlossen wird. Die Tags <Ueberschrift> und <Text> sind beide direkte Unterelemente von <Nachricht>, wobei der Tag <Text> seinerseits ein weiteres Unterelement namens <unterstrichen> enthlt. Alles was zwischen dem nenden und schlieenden Tag steht, ist Inhalt dieses Tags. Auch wenn das Wort wichtig mit dem Tag <unterstrichen> umgeben ist, heit das nicht, dass es auch unterstrichen dargestellt wird. Wie der Inhalt dieses und aller weiteren Tags wiedergegeben bzw. verarbeitet wird, obliegt allein der Interpretation der Maschine oder des Menschen.8
1.6 Webservice
Web-Services sind selbstbeschreibende, gekapselte Software-Komponenten, die eine Schnittstelle anbieten, ber die ihre Funktionen entfernt aufgerufen, und die lose durch den Austausch von Nachrichten miteinander gekoppelt werden knnen. Zur Erreichung universeller Interoperabilitt9 werden fr die Kommunikation die herkmmlichen Kanle des Internets verwendet. Web-Services basieren auf den drei Standards WSDL10 , SOAP und UDDI: Mit WSDL wird die Schnittstelle eines Web-Services speziziert, via SOAP werden Prozedurfernaufrufe bermittelt und mit UDDI11 , einem zentralen Verzeichnisdienst fr angebotene We- Services, knnen andere Web-Services aufgefunden werden. 12
1.7 SOAP
Im Rahmen der zu entwickelnden Schnittstelle ndet ein SOAP13 Webservice seine Anwendung. Im Listing 1.2 ist ein Beispiel eines SOAP Requests abgebildet. Listing 1.2: XML Beispiel eines SOAP Requests <?xml version=1.0 encoding=utf -8 ?> <SOAP ENV:Envelope xmlns:SOAPENC=" http: // schemas . xmlsoap . org / soap / encoding /" xmlns:SOAPENV=" http: // schemas . xmlsoap . org / soap / envelope /" x m l n s : a x i s 2 =" http: // webservice / bmg / blitz / net /" xmlns:ns0=" http: // data . bmg . blitz . net / xsd " xmlns:ns1=" http: // webservice / bmg / blitz / net / xsd " xmlns:ns2=" http: // entity . bmg . blitz . net / xsd " xmlns:wsaw=" http: // www .w3. org /2006/05/ addressing / wsdl " x m l n s : w s d l =" http: // schemas . xmlsoap . org / wsdl /" x m l n s : x s ="
Vgl. Seite 2 - 6 [T.R01] Die Fhigkeit unabhngiger Systeme mglichst nahtlos zusammenzuarbeiten. 10 WebService Description Language - ein platformunabhnige Beschreibungssprache frWebServices 11 Universal Description, Discovery and Integration 12 Quelle: Seite 40 [Fin09] 13 SOAP- Single Object Access Protocol
9 8
Alexander Bonin
Seite 3 von 95
1. Grundlagen
http: // www .w3. org /2001/ XMLSchema " x m l n s : x s i =" http: // www . w3. org /2001/ XMLSchema - instance "> <SOAP ENV:Body> <ns1:sendIncomings xmlns:ns1=" http: // webservice / bmg / blitz / net / xsd "> < n s 1 : t i c k e t I d x s i : t y p e =" xs:string ">927794510< / ns1:ticketId> < n s1 : in c om in g s > < ns1:charge > < n s 1 : a r t i c l e x s i : t y p e =" xs:string ">Spargel < / ns1:article> <ns1:bmgnumber x s i : t y p e =" xs:string ">8009029< / ns1:bmgnumber> < n s 1 : b m g r o o t i d x s i : t y p e =" xs:string ">40328000010< / ns1:bmgrootid> < n s 1 : l a b e l s t a n d a r d s L a b e l i d x s i : t y p e =" xs:short "> 103< / n s 1 : l a b e l s t a n d a r d s L a b e l i d > < n s 1 : p r i n t c o d e x s i : t y p e =" xs:string " / > < n s 1 : s e l l e r x s i : t y p e =" xs:string ">1479< / n s 1 : s e l l e r > < n s 1 : s p e z i e s x s i : t y p e =" xs:string " / > < n s 1 : t y p e x s i : t y p e =" xs:string ">Auslagerung< / ns1:type> < / ns1:charge > <ns1:info> < n s 1 : b u y er x s i : t y p e =" xs:string ">1500< / n s 1 : b u y er > < n s 1 : c h a r g e I d x s i : t y p e =" xs:string ">03052011< / ns1:chargeId> < n s 1 : q u a n t i t y U n i t i d x s i : t y p e =" xs:short ">13< / ns1:quantityUnitid> < n s 1 : q u a n t i t y V a l u e x s i : t y p e =" xs:string ">40< / ns1:quantityValue> </ ns1:info> < / n s1 : in c om i ng s > < / ns1:sendIncomings> < /SOAP ENV:Body> < /SOAP ENV:Envelope> Eine SOAP Nachricht unterteilt sich prinzipiell in drei Teile: Zum ersten das allumfassende SOAP-ENV:Envelope Element in dem die Namensrume fr alle weiteren Elemente deniert werden. Zweitens gibt es als Unterelement von SOAP-ENV:Envelope einen SOAPENV:Header, der optional und auch im oben stehenden Listing nicht vorhanden ist.
Alexander Bonin
Seite 4 von 95
1. Grundlagen
Drittens gibt es das SOAP-ENV:Body Element in welchem alle zu bertragenden Informationen untergebracht sind Das Soap-ENV:Body Element ist, im Gegensatz zum SOAP-ENV:Header, zwingend erforderlich. Die Informationen im Soap-ENV:Body sind abhngig von der Funktion, die beim Webservice angesprochen werden soll. In diesem Fall wird ein Element ns1:sendIncommings deniert welches die Unterelemente ns1:ticketId und ns1:incommings enthlt. Das ns1:incommings Element wiederum enthlt selbst noch die Unterelemente ns1:charge und ns1:info. Diese zwei Elemente enthalten wiederum eine Reihe von Unterelementen die ihre Eigenschaften denieren.
1.8 AgroXML
AgroXML ist ein XML Standard zum Datenaustausch in der Landwirtschaft. Dieser Standard ist recht komplex und bildet viele Bereiche der Landwirtschaft ab. Alle in diesem Webservice verwendeten XML Dokumente basieren auf diesem Standard. Vom Entwickler wird AgroXML wie folgt beschrieben: agroXML erleichtert dem Landwirt den Datenaustausch. Momentan bestehen zwischen dem Betriebsrechner des Landwirts und den Empfngern (Behrde, Handel, Bndler) eine Vielzahl individueller Schnittstellen, die fr jeden Austauschprozess jeweils eine spezielle Datenaufbereitung erfordern. Mit agroXML soll ein Softwarestandard eingefhrt werden, der die Kommunikation der Programme aller Akteure untereinander ermglicht. 14 .
14
[Kur]
Alexander Bonin
Seite 5 von 95
2.1.2 Programmablauf
Nach dem Start hat der Nutzer die Mglichkeit, seine Zugangsdaten einzugeben, und festzulegen ob die Kommunikation automatisch stattnden soll und ob der Nutzer jeder Kommunikation explizit gefragt werden mchte. Danach ist eine Synchronisierung mit Bio mit Gesicht notwendig. Entsprechend den gesetzten Parametern wird an den entsprechenden Stellen in Elsa-ko die Kommunikation selbststndig von der
Alexander Bonin
Seite 6 von 95
Schnittstelle realisiert. Das heit, die Schnittstelle bernimmt selbst die Entscheidung ob ein Datensatz bertragen werden kann und bertrgt ihn dann auch. Wird ein Datensatz gelscht, so lscht die Schnittstelle eigenstndig einen mglicherweise verbunden Eintrag beim Webservice mit.
2.3 Wirtschaftlichlichkeitsbetrachtung
Eine wirtschaftliche Betrachtung ist an dieser Stelle nur hinsichtlich des Mehrwertes, welchen das Plugin fr die Vermarktung von Elsa-ko bietet, mglich. Informationen zu dieser Betrachtung stammen aus dem, im Anhang bendlichen Telefonprotokol, B.1 auf Seite 90, mit dem Bio mit Gesicht Geschftsfhrer Frank Wrner. Im Verlauf dieses Gesprches stellte sich neben einigen grundlegenden technischen Fragen heraus, dass zwar Kontakt zu Mitbewerbern im Bereich elektronische Schlagdokumentation hergestellt wurde, jedoch bisher niemand die Anbindung dieses Webservices umgesetzt hat. Dementsprechend ergibt sich, bei Elsa-ko im Falle einer Umsetzung, ein Alleinstellungsmerkmal, das die Elsa-ko Software gegen alle anderen derzeit am Markt bendlichen elektronische Schlagdokumentationen im kologischen Bereich abgrenzt. Dieses kann vorteilhaft zu Marketingzwecken eingesetzt werden.
Alexander Bonin
Seite 7 von 95
3 Entwurf
Im Kapitel Entwurf erfolgt die endgltige Festlegung der Entwicklungsumgebung, des verwendeten Frameworks, der Hardwareumgebung sowie eine Beschreibung der Schnittstellen und einer Abbildung dieser als Flussdiagramm.
3.1 Architektur
Die Anforderungen an die Umgebung, unter welcher die Schnittstelle laufen muss, entsprechen den Anforderung der Elsa-ko Software. Diese sind wie folgt festgelegt: Untersttzte Betriebssysteme: WindowsXP, Windows Vista, Windows 7 Computer/Prozessor: Pentium ab 1GHz (oder kompatibel) Bildschirm / Grakkarte: mind. 1024 x 768 Pixel Ausung und 16 Bit Farbtiefe
1
Die zu implementierende Schnittstelle darf diese Angaben keinesfalls nach oben verndern.
Alexander Bonin
Seite 8 von 95
3. Entwurf
AlchemySoap Sta
Beschreibung Das Microsoft .net Framework bietet neben vielem anderen auch eine vollstndige Soap / WSDL Untersttzung. Vorgnger von Microsofts .net welcher nicht mehr weiterentwickelt wird open source C and C++ software development toolkit for SOAP/XML Web services and generic (non-SOAP) C/C++ XML data bindings C++ SOAP STACK Supporting SOAP 1.1 and 1.2 Ist ein Open source Web Services Framework fr C++ und basiert auf Axis2/C C++ Webservice Client Bibliothek Client/Server SOAP Bibliothek in reinem C Framework mit umfassenden Bibliotheken zu XML und Netzverbindungen. Bietet in der kostenpichtigen Version volle WSDL Untersttzung.
Lizenz -
Last Release V4
gSOAP Public License 1.3 LGPL Apache Licence 2.0 LGPL LGPL Boost Software License
28.02.2005 18.04.2011
07.02.2007 16.02.2011
Alexander Bonin
Seite 9 von 95
3. Entwurf
3.4 Kommunikationsschnittstellen
Kommunikationsschnittstellen sind alle bergabestellen in denen zwei interagierende Systeme miteinander kommunizieren.4 Grundstzlich gibt es in diesem Fall zwei Schnittstellen, die sich durch ihre Endpunkte und ihren Funktionsumfang unterscheiden. Zum einen die Schnittstelle zur Authentizierung, die die Funktionen Login und Logout umfasst. Zum anderen die BMG Schnittstelle zur Datenbertragung. Diese hlt die Funktionen Daten synchronisieren, Daten senden und Daten lschen bereit. An dieser Stelle erfolgt eine Beschreibung der Schnittstellen hinsichtlich Ihrer Endpunkte, ihrer Technik, und der Auslser. Zu jeder Schnittstellenbeschreibung bendet sich im Kapitel 3.6 ein Datenussdiagramm. Alle Informationen die Schnittstelle betreend, haben ihre Grundlage im Anhang B.2 der Schnittstellenbeschreibung von Bio mit Gesicht.
Woher: Elsa-ko Stammdaten Wohin: Bio mit Gesicht Logindaten Beschreibung: Authentizierung gegenber Bio mit Gesicht. Datenelemente: - Bio mit Gesicht Kundennummer - Passwort - SessionID Schnittstellentechnik: XML per Http Auslser(Ereignis): Vor dem Start jeder Datenkomunikation Tabelle 3.2: Schnittstellenbeschreibung Login
Alexander Bonin
Seite 10 von 95
3. Entwurf
Woher: Elsa-ko SessionID Wohin: Bio mit Gesicht-mit-Gesicht Beenden einer Session mit Bio mit Gesicht. Datenelemente: - SessionID - Wahrheitswert Schnittstellentechnik: XML per Http Auslser(Ereignis): Beenden einer Datenkommunikation Tabelle 3.3: Schnittstellenbeschreibung Logout Woher: Elsa-ko Wohin: Bio mit Gesicht Daten Synchronisieren ruft die bei Bio mit Gesicht hinterlegten Masterdaten ab. Dazu Zhlen die zugelassenen Kufer, Artikel, die Liste der Einheiten und die Liste der Anbaustandards. - buyer Liste - article Liste - unit Liste - SessionID - Standard Liste Schnittstellentechnik: XML per Http Periodizitt: Bei Einrichtung oder Stammdatennderung bei Bio mit Gesicht Auslser(Ereignis): nach Nutzeranforderung Tabelle 3.4: Schnittstellenbeschreibung Synchronisieren
Alexander Bonin
Seite 11 von 95
3. Entwurf
Woher: Elsa-ko Wohin: Bio mit Gesicht Beschreibung: bertragen von Chargendaten an Bio mit Gesicht. - info Datensatz - BMGID - charge Datensatz Schnittstellentechnik: XML per Http Auslser(Ereignis): Buchen einer BMG gltigen Auslagerung Tabelle 3.5: Schnittstellenbeschreibung Senden Woher: Elsa-ko Wohin: Bio mit Gesichtlo Beschreibung: Stornieren bertragener Chargendaten von Bio mit Gesicht wenn die Buchung in Elsa-ko storniert wird. - Charge - BMGID Schnittstellentechnik: XML per Http Auslser(Ereignis): Stornieren einer bertragenen Auslagerung in Elsa-ko. Tabelle 3.6: Schnittstellenbeschreibung Lschen werden an Bio mit Gesicht bertragen worauf von Bio mit Gesicht eine eindeutige ID fr diese bertragung zurckgegeben wird.
Alexander Bonin
Seite 12 von 95
3. Entwurf
man also die DataList in der gesucht werden soll. Weiterhin bentigt man den DataRecord, also die Zeile, in der die Daten stehen. Zum Schluss braucht man noch den Bezeichner der der DataValue, analog den Spaltenbezeichnern.
3.6 Flussdiagramme
Im Folgenden gibt es fnf Flussdiagramme. Fr die Authorisierung bei Bio mit Gesicht"die Vorgnge: Anmeldung und Abmeldung, die Voraussetzung fr die drei weiteren Flussdiagramme sind. Danach die Diagramme zu den Vorfllen: Synchronisierung, bertragung und Lschen. Mit diesen Flussdiagrammen soll das System allgemein Veranschaulicht, und eine Kommunikationsbasis fr alle Entwicklungsprozesse geschaen werden.5
3.6.1 Anmeldediagramm
In Abbildung 3.2 ist der Loginvorgang bei Bio mit Gesicht, als Flussdiagramm zu sehen. Dieses veranschaulicht den Prozess der Anmeldung, angefangen vom Prfen der Netzverfgbarkeit ber das Vorhandensein von Nutzerdaten bis hin zum Senden der Loginanfrage und dem Empfangen der Antwort auf diese.
Alexander Bonin
Seite 13 von 95
3. Entwurf
3.6.2 Abmeldediagramm
In Abbildung 3.3 wird der Abmeldevorgang bei Bio mit Gesicht als Flussdiagramm dargestellt.
3.6.3 Synchronisationsdiagramm
Das Synchronisationsdiagramm in Abbildung 3.4 stellt den Ablauf der Synchronisation von Stammdaten, die beim Webservice hinterlegt sind, dar. Wie im vorangegangenen Diagramm wird als erstes die Netzverfgbarkeit geprft. Anschlieend das Senden der XML Anfrage und das Empfangen und Auswerten der XML Antwort. Jeweils mit den zwei mglichen Endpunkten erfolgreich und nicht erfolgreich.
Alexander Bonin
Seite 14 von 95
3. Entwurf
3.6.4 bertragungsdiagramm
Im bertragungsdiagramm 3.5 wird das Vorgehen zum Einreichen von Daten am Webservice abgebildet. Es beginnt mit der Prfung ob das Produkt und der Kufer in der BMG Liste vorhanden sind und demnach bertragen werden knnen. Als nchstes werden alle Daten der Buchung ausgelesen und in ein XML Dokument integriert. Danach erfolgt das Prfen der Netzverfgbarkeit sowie das Senden und Auswerten der Antwort. Wurden alle Schritte erfolgreich abgearbeitet, erfolgt das Markieren der Buchung als gesendet.
3.6.5 Lschdiagramm
Um bertragene Daten auch wieder lschen zu knnen, wird noch das Lschdiagramm aus Abbildung 3.6 bentigt. Es beschreibt den Lschvorgang. Dazu wird die entsprechende BMG Nummer aus den Buchungsdaten ausgelesen und im nchsten Schritt mit allen relevanten Daten ein Lschdokument generiert. Hinterher erfolgt die bliche Prfung auf Netzverfg-
Alexander Bonin
Seite 15 von 95
3. Entwurf
barkeit und am Ende das Absenden des Requests und die Auswertung der Antwort.
Alexander Bonin
Seite 16 von 95
4 Implementierung
Im Kapitel Implementierung werden ausgewhlte Funktionen betrachtet. Sie stellen jedoch nicht den gesamten Umfang aller Funktionen dar. Alle Funktionen mit einem hnlichen Ablauf, sowie die vollstndigen Quellcodelistings der hier behandelten Funktionen, benden sich im Anhang A.
4.1.1 Initialize
In der Funktion 4.1 werden alle Punkte abgearbeitet welche beim ersten Aufrufen der DLL wichtig sind. In diesem Fall ist das lediglich die Angabe der Sprachdatei welche spter in der Lage ist Mehrsprachigkeit zu untersttzen. Listing 4.1: Initiale Aktionen beim Laden der DLL IBKBMGMODUL_EXT_API bool Initialize () { // return CADSMessageHandler :: GetInstance () -> LoadFile (" BmgModulMessage . zip " ,0 ," BmgModul ") ; return true ; }
4.1.2 GetParameter
Auf die DLL Funktion GetParameter() soll in diesem Abschnitt nher eingegangen werden. Sie ist dafr verantwortlich, dem Hauptprogramm alle wichtigen Informationen ber das Modul bekannt zu geben. Das folgende Listing 4.2 zeigt den Aufbau der GetParameter() Funktion. Daraus ist ersichtlich das die Informationen Name, FunctionList, Version, DemoDays, Points, ValidEnd und RegType vom Modul abgefragt werden knnen. Listing 4.2: Funktion zum Bekanntmachen der Modulinformationen IBKBMGMODUL_EXT_API LPCTSTR GetParameter ( LPCTSTR pParameter ) {
Alexander Bonin
Seite 17 von 95
4. Implementierung
if (! strcmp ( pParameter , " Name " ) ) return " BMG - Modul " ; else if (! strcmp ( pParameter , " FunctionList " ) ) return " test_bmg , sync_bmg , send_bmg , del_bmg " ; // , send_bmg , del_bmg else if (! strcmp ( pParameter , " Version " ) ) return " 1.0.0 " ; // OnNewRelease else if (! strcmp ( pParameter , " DemoDays " ) ) return " 100 " ; else if (! strcmp ( pParameter , " Points " ) ) return " 10 " ; else if (! strcmp ( pParameter , " ValidEnd " ) ) return " 2012 -12 -31 " ; else if (! strcmp ( pParameter , " RegType " ) ) return " No " ; // No , Modul , Bundle else return NULL ; } Der Parameter Name liefert dem Hauptprogramm die exakte Bezeichnung des Moduls. Der Parameter FunctionList gibt dem Hauptprogramm alle Funktionen des Moduls zurck die vom Hauptprogramm aus direkt aufgerufen werden knnen. Der Parameter DemoDays gibt die kostenlose Demo Laufzeit in Tagen zurck und abschlieend gibt der Parameter RegType die Art der Registrierung des Moduls an.
4.1.3 GetFunction
Die Funktion GetFunction in Listing 4.3 gibt die genaue Funktionsbezeichnung entsprechend der, in Listing 4.2 angegebenen, FunctionList zurck sowie den Wert TRUE fr den Returncode. Sollte keine bereinstimmung gefunden werden wird als Returncode FALSE zurckgegeben und die Funktion beendet. Listing 4.3: Verentlichen von Modulinformationen IBKBMGMODUL_EXT_API bool GetFunction ( LPCTSTR pType , CString & zFunction , CValuePairArray & arrValues ) { bool bRetcode = true ; // Reference um warnung zu umgehen arrValues ; zFunction ; pType ; if ( ! strcmp ( pType , " test_bmg " ) ) { zFunction = " test_bmg " ; } else if (! strcmp ( pType , " sync_bmg " ) ) { zFunction = " sync_bmg " ; } else if (! strcmp ( pType , " send_bmg " ) ) { zFunction = " send_bmg " ; } else if (! strcmp ( pType , " del_bmg " ) ) { zFunction = " del_bmg " ; } else {
Alexander Bonin
Seite 18 von 95
4. Implementierung
4.1.4 test_bmg
Die Funktion testbmg aus Listing 4.4 macht nichts anderes als auf Basis der eingegebenen Zugangsdaten zu testen ob sich eine Verbindung zu Bio mit Gesicht aufbauen lsst oder nicht. Hierzu beschat sie sich aus dem Datastore die DataListe BMG_CONF um von dieser die DataValues BMGNR fr die Zugangsnummer, sowie BMGPW fr das Passwort abzurufen. Danach wird mit diesen Daten ein Login bei Bio mit Gesicht angestoen, die zurckgelieferte TicketID in eine Variable geschrieben und ein LogoutRequest gesendet. Wenn jetzt in der Variable ticket_id ein beliebiger Wert steht war der Verbindungsversuch erfolgreich und die Funktion wird mit TRUE beendet. Ist die Variable jedoch leer, so war mit den angegebenen Zugangsdaten keine Verbindung mglich und die Funktion wird mit dem Rckgabewert FALSE beendet. Listing 4.4: Funktion zum Verbindungstest mit Bio mit Gesicht. IBKBMGMODUL_EXT_API bool test_bmg ( CADSModulPara & recModulPara ) { std :: string bmg_user ; std :: string bmg_pass ; CADSDataList * pDataList ; CADSDataRecord * pDataRecord ; pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG_CONF " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; bmg_user = pDataRecord - > GetDataValue ( " BMGNR " ) -> GetStringValue () ; bmg_pass = pDataRecord - > GetDataValue ( " BMGPW " ) -> GetStringValue () ; std :: string ticket_id = login_response ( transfer_bmg ( login_bmg ( bmg_user , bmg_pass ) , true ) ) ; logout_response ( transfer_bmg ( logout_bmg ( ticket_id ) , true ) ) ; if ( ticket_id != " " ) { return true ; } else { return false ; } }
Alexander Bonin
Seite 19 von 95
4. Implementierung
4.1.5 sync_bmg
Die Funktion sync_bmg wird gerufen, wenn die Masterdaten von Bio mit Gesicht abgerufen werden sollen. Dazu werden, analog zur Funktion test_bmg, die Zugangsdaten von Bio mit Gesicht abgerufen. Auerdem wird ein leeres XML Dokument angelegt. Poco :: AutoPtr < Poco :: XML :: Document > main_document = new Poco :: XML :: Document ; Als Nchstes wird ein getMatserdata Request an Bio mit Gesicht generiert und gesendet. die Anwort wird in das leere XML Dokument geschrieben. Danach ist die Komunikation mit Bio mit Gesicht beendet und es wird nur noch mit dem XML Dokument gearbeitet. Dieses wird nacheinander jeweils den Funktionen getmasterdata_response_buyer, die in Kapitel 4.2.2 beschrieben ist zum Auslesen der Kufer und getmasterdata_response_us zum Auslesen der Units und Standards bergeben. Gleichzeitig werden die entsprechenden DataListen aus dem DataRecord geholt und mit an die Funktionen bergeben. Listing 4.5: Funktion zum Holen der Bio mit Gesicht Masterdaten. IBKBMGMODUL_EXT_API bool sync_bmg ( CADSModulPara & recModulPara ) { if (! checknet ( " http :// demo . bio - mit - gesicht . de / services / AuthService " ) ) { WriteMessage ( " Es besteht keine Netzverbindung . " ) ; return false ; } Poco :: AutoPtr < Poco :: XML :: Document > main_document = new Poco :: XML :: Document ; // definiere Variablen zum auslesen der Elsa daten CADSDataStore * pDataStore = CADSDataStore :: GetDataStore () ; CADSDataList * pDataList ; CADSDataRecord * pDataRecord ; CADSDataValue * pDataValue ;
// auslesen der BMG Konfigurationsdaten std :: string bmg_user ; std :: string bmg_pass ; pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG_CONF " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; bmg_user = pDataRecord - > GetDataValue ( " BMGNR " ) -> GetStringValue () ;
Alexander Bonin
Seite 20 von 95
4. Implementierung
bmg_pass = pDataRecord - > GetDataValue ( " BMGPW " ) -> GetStringValue () ; std :: string ticket_id = login_response ( transfer_bmg ( login_bmg ( bmg_user , bmg_pass ) , true ) ) ; main_document = transfer_bmg ( getmasterdata_bmg ( ticket_id ) , false ) ; logout_response ( transfer_bmg ( logout_bmg ( ticket_id ) , TRUE ) ) ; pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " PI " , true ) ; getmasterdata_response_buyer ( main_document , pDataList ) ; pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG " , true ) ; getmasterdata_response_us ( main_document , pDataList ); return true ; }
4.1.6 send_bmg
Die Funktion send_bmg wird aufgerufen wenn im Hauptprogramm eine Lagerausbuchung initiiert wird. Send_bmg prft dabei, ob die aktuelle Lagerausbuchung an Bio mit Gesicht zu bertragen ist und startet , wenn dies gegeben ist, die Datenbertragung. Nach erfolgreicher bertragung markiert die Funktion die aktuelle Buchung als bertragen. Listing 4.6: Funktion zum bertragen der Bewegungsdaten. IBKBMGMODUL_EXT_API bool send_bmg ( CADSModulPara & recModulPara ) { // definiere Variablen zum auslesen der Elsa daten CADSDataStore * pDataStore = CADSDataStore :: GetDataStore () ; ... struct charge_st charge ; struct info_st info ; // auslesen der BMG Konfigurationsdaten pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG_CONF " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ;
Alexander Bonin
Seite 21 von 95
4. Implementierung
bmg_user = pDataRecord - > GetDataValue ( " BMGNR " ) -> GetStringValue () ; bmg_pass = pDataRecord - > GetDataValue ( " BMGPW " ) -> GetStringValue () ; bmg_transfer = pDataRecord - > GetDataValue ( " BMGTRANS " ) -> GetStringValue () ; bmg_ask = pDataRecord - > GetDataValue ( " BMGASKUSER " ) -> GetStringValue () ; // bmgnummer und sellernummer - charge charge . seller = pDataRecord - > GetDataValue ( " BMGMID " ) -> GetStringValue () ; // auslesen der Anbauverband pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " UI " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; searchDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG " , true ) ; charge . lablestandard = searchDataList - > FindDataRecord ( " BMGBEZ " , pDataRecord - > GetDataValue ( " ANBVERB " ) -> GetStringValue () ) -> GetDataValue ( " BMGID " ) -> GetStringValue () ; // auslagerungs informationen auslesen pDataRecord = recModulPara . pMODDataRecord ; ... // Einheit der Ware - info ( findunit -> einheitenmapping ) info . quantityUnitID = findid ( findunit ( pDataRecord - > GetDataValue ( " AL_EINH " , true ) -> GetStringValue () ) ," BMG " ," BMGBEZ " ," BMGID " ) ; // Menge - info // info . quantityValue = sprintf (( pDataRecord - > GetDataValue (" AL_MNG " , true ) -> GetFloatValue () ) ; CString qValue ; qValue . Format ( " %.2 f " , pDataRecord - > GetDataValue ( " AL_MNG " , true ) -> GetFloatValue () ) ; info . quantityValue = qValue ; ... // prfen der Daten auf vollstndigkeit if ( charge . bmgrootid == " " || charge . lablestandard == " " || charge . seller == " " ) { return false ;} if ( info . buyer == " " || info . quantityUnitID == " " || info . quantityValue == " " ) { return false ;}
Alexander Bonin
Seite 22 von 95
4. Implementierung
if (! strcmp ( bmg_ask . c_str () ," J " ) ) { if ( AskUser ( " Aktuelle Auslagerung an Bio mit Gesicht bertragen ? " , MB_YESNO | MB_ICONQUESTION ) != IDYES ) { return false ; } } // Prfen auf netzverfgbarkeit wenn kein netz zum bertragen vormerken if (! checknet ( " http :// demo . bio - mit - gesicht . de / services / AuthService " ) ) { ... } // login senden std :: string ticket_id = login_response ( transfer_bmg ( login_bmg ( bmg_user , bmg_pass ) , true ) ) ; // bmg nummer reservieren bmgnumber = getbmgnumbers_response ( transfer_bmg ( getbmgnumbers_bmg ( ticket_id ) , false ) ) ; charge . bmgnumber = bmgnumber . c_str () ; // bertragung senden std :: string incomming_id = sendincommings_response ( transfer_bmg ( sendincommings_bmg ( ticket_id , charge , info ) , false ) ) ; // logout senden logout_response ( transfer_bmg ( logout_bmg ( ticket_id ) , TRUE ) ) ; // BMG Nummer an auslagerung schreiben if (! strcmp ( bmgnumber . c_str () , incomming_id . c_str () ) ) { pDataRecord - > GetDataValue ( " BMGNR " ) -> SetStringValue ( bmgnumber . c_str () ) ; } return true ; } Um diese Funktionalitt sicher zu stellen, werden wie in Listing 4.6 zu sehen, zunchst alle erforderlichen Variablen deniert. Dazu gehren auch zwei strukturierte Datentypen, welche alle die Buchung betreenden Informationen aufnehmen. Der Aufbau dieser zwei strukturierten Datentypen ist in Listing 4.7 abgebildet.
Alexander Bonin
Seite 23 von 95
4. Implementierung
Listing 4.7: Strukturierte Datentypen der sendbmg Funktion. typedef struct info_st { std :: string buyer ; std :: string chargeid ; std :: string quantityUnitID ; std :: string quantityValue ; } info_st ; typedef struct charge_st { std :: string article ; std :: string bmgnumber ; std :: string bmgrootid ; std :: string lablestandard ; std :: string printcode ; std :: string seller ; std :: string spezies ; std :: string type ; } charge_st ; Diese zwei Datentypen werden im Verlauf der Funktion mit den entsprechenden Daten aus den der Buchung zugehrigen DataRecords befllt. Einige Daten knnen nicht direkt in die Listen umgewandelt werden weil eine entsprechende von Bio mit Gesicht vergebene Indexnummer erwartet wird. Als Beispiel die Zeilen, // auslesen der Anbauverband pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " UI " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; searchDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG " , true ) ; charge . lablestandard = searchDataList - > FindDataRecord ( " BMGBEZ " , pDataRecord - > GetDataValue ( " ANBVERB " ) -> GetStringValue () ) -> GetDataValue ( " BMGID " ) -> GetStringValue () ; in denen der Labelstandard beziehungsweise die ID des Labelstandards, oder auch des Anbauverbandes, in das XML Dokument integriert wird. Im Einzelnen passiert an dieser Stelle Folgendes: Aus dem DataRecord der DataListe UI wird der Wert des Anbauverbandes geholt. Auf der zu durchsuchenden DataListe wird die interne Funktion FindDataRecord gerufen, die als Parameter den Bezeichner in dem gesucht werden soll, sowie den Wert der vorher vom Anbauverband ermittelt wurde, erwartet. Diese gibt den entsprechenden DataRecord zurck, von dem aus man mit den Funktionen GetDataValue die Value auswhlen kann um danach mit GetStringValue den Wert der Value auszulesen. Eine weitere Besonderheit ist das Aunden der Units, also der Einheiten der zu bermittelnden Ware. Das Problem an dieser Stelle ist, das genau
Alexander Bonin
Seite 24 von 95
4. Implementierung
so wie beim Anbauverband zur entsprechenden Einheit eine zugehrige ID ermittelt werden muss. Darber hinaus stimmen aber auch die Schreibweisen der Einheiten auf Bio mit Gesicht und Elsa-ko Seite nicht miteinander berein. Das Auslesen und Umsetzen dieser Problematik wird in den folgenden Zeilen realisiert. // Einheit der Ware - info ( findunit -> einheitenmapping ) info . quantityUnitID = findid ( findunit ( pDataRecord - > GetDataValue ( " AL_EINH " , true ) -> GetStringValue () ) ," BMG " ," BMGBEZ " ," BMGID " ) ; Hier wird auf zwei Hilfsfunktionen zurckgegrien. Zum einen die Funktion ndunitus Kapitel 4.2.7 welche die externe Bezeichnung von Bio mit Gesicht zur in Elsa-ko vorliegenden internen Bezeichnung heraussucht. Zum anderen die Funktion ndid aus Kapitel 4.2.9 welche diese zurckgegebene Bezeichnung mit der Stammdatentabelle abgleicht und die entsprechende ID von Bio mit Gesicht zurck gibt. Da alle Daten unabhngig in welcher Form sie innerhalb von Elsa-ko vorliegen, als String an den Webservice bergeben werden, ergibt sich noch eine Hrde beim Auslesen und bergeben der Menge, der zu bertragenden Buchung. Diese liegt als oat-Wert vor und muss in einen Wert vom Typ String umgewandelt werden. Das wird mit folgenden Zeilen realisiert wird. CString qValue ; qValue . Format ( " %.2 f " , pDataRecord - > GetDataValue ( " AL_MNG " , true ) -> GetFloatValue () ) ; info . quantityValue = qValue ; Als erstes wird eine Variable vom Typ String bzw CString erstellt. Danach wird auf die Format Funktion von CStrings zurckgegrien, in der als erster Parameter der Datentyp der Eingangsdaten bergeben wird. In diesem Fall steht %.2f fr einen Float Datentyp. Als zweiter Parameter werden die Daten, die in einen String umformatiert werden sollen, bergeben. Zuletzt werden alle Daten auf Vollstndigkeit geprft und die Netzverbindung sichergestellt. Sollte keine Netzverbindung verfgbar sein, wird an dieser Stelle der Buchungssatz zum bertragen vorgemerkt und die weitere Ausfhrung der Funktion abgebrochen. Ist eine Netzverbindung verfgbar, wird zunchst die Loginfunktion aufgerufen. Als nchstes wird eine BMG-Nummer reserviert und danach sofort den Buchungsdaten hinzugefgt. Damit sind alle Daten der Buchung komplett. Anschlieend werden die Buchungsdaten bertragen, und die zur Besttigung zurckgemeldete BMG-Nummer wird dem Buchungsdatensatz in Elsa-ko zur spteren Verwendung hinzugefgt. Die Funktion wird an dieser Stelle mit return TRUE beendet.
4.1.7 del_bmg
Die Funktion del_bmg aus Listing 4.8 ist fr den Lschvorgang verantwortlich. Wird diese gerufen, wird wie bei jeder Funktion zunchst die Netzverbindung geprft und anschlieend die bentigten Variablen deklariert. Aus der Konguration werden die Logindaten abgerufen. Jetzt werden die Daten der Charge analog zur Funktion
Alexander Bonin
Seite 25 von 95
4. Implementierung
send_bmg eingelesen. Mit diesen Daten wird nun ein XML Request zum Lschen formuliert und dieser abgesendet. Die Rckgabe dieses Requests ist die gelschte BMG-Nummer, welche mit der gesendeten BMG-Nummer verglichen wird. Wenn diese bereinstimmen, wird der Funktionsaufruf mit True ansonsten mit False beendet. Listing 4.8: Funktion zum stornieren von Bewegungsdaten. IBKBMGMODUL_EXT_API bool del_bmg ( CADSModulPara & recModulPara ) { if (! checknet ( " http :// demo . bio - mit - gesicht . de / services / AuthService " ) ) { WriteMessage ( " Es besteht keine Internetverbindung ."); return false ; } std :: string bmg_user ; ... struct charge_st charge ; pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG_CONF " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; bmg_user = pDataRecord - > GetDataValue ( " BMGNR " ) -> GetStringValue () ; bmg_pass = pDataRecord - > GetDataValue ( " BMGPW " ) -> GetStringValue () ; charge . seller = pDataRecord - > GetDataValue ( " BMGMID " ) -> GetStringValue () ; // auslesen der Anbauverband ... charge . lablestandard = searchDataList - > FindDataRecord ( " BMGBEZ " , pDataRecord - > GetDataValue ( " ANBVERB " ) -> GetStringValue () ) -> GetDataValue ( " BMGID " ) -> GetStringValue () ;
pDataRecord = recModulPara . pMODDataRecord ; charge . bmgnumber = pDataRecord - > GetDataValue ( " BMGNR " ) -> GetStringValue () ; // artikel und Auslagerungsart - charge charge . article = pDataRecord - > GetDataValue ( " AL_BEZWARE " , true ) -> GetStringValue () ; charge . type = " Auslagerung " ;
Alexander Bonin
Seite 26 von 95
4. Implementierung
// suche Rootid zum Artikel aus der BMG Liste - charge charge . bmgrootid = findid ( pDataRecord - > GetDataValue ( " AL_BEZWARE " ) -> GetStringValue () ," BMG " ," BMGBEZ " ," BMGID " ) ;
std :: string temp_str ; ticket_id = login_response ( transfer_bmg ( login_bmg ( bmg_user , bmg_pass ) , true ) ) ; temp_str = sendcancellations_response ( transfer_bmg ( sendCancellations_bmg ( ticket_id , charge ) , false ) ) ; logout_response ( transfer_bmg ( logout_bmg ( ticket_id ) , true ) ) ; if (! strcmp ( temp_str . c_str () , charge . bmgnumber . c_str () )){ return true ; } else { return false ;} }
4.1.8 sendmarked_bmg
Die Funktion sendmarked_bmg macht im Grunde das Gleiche, wie die Funktion send_bmg. Es gibt jedoch einen Unterschied. Bei send_bmg wird immer der aktuelle Buchungsdatensatz eingelesen und, sofern dies mglich ist, an Bio mit Gesicht gesendet. Sendmarked_bmg bearbeitet diese Buchungsdatenstze, die aus irgendwelchen Grnden, z.B. fehlendes Netz, nicht zugestellt werden konnten und zum Senden markiert wurden. Listing 4.9: Funktion zum senden aller markierten Bewegungsdaten. IBKBMGMODUL_EXT_API bool sendmarked_bmg ( CADSModulPara & recModulPara ) { if (! checknet ( " http :// demo . bio - mit - gesicht . de / services / AuthService " ) ) { WriteMessage ( " Es besteht keine Netzverbindung . " ) ; return false ; } // definiere Variablen zum auslesen der Elsa daten CADSDataStore * pDataStore = CADSDataStore :: GetDataStore () ; ... struct info_st info ; // auslesen der BMG Konfigurationsdaten pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG_CONF " , true ) ; ...
Alexander Bonin
Seite 27 von 95
4. Implementierung
// bmgnummer und sellernummer - charge charge . seller = pDataRecord - > GetDataValue ( " BMGMID " ) -> GetStringValue () ; // auslesen der Anbauverband ... // Record aller Auslagerungen holen pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " LBU " , true ) ; for ( int i = 0; pDataList - > GetDataRecordCount () ; i ++) { pDataRecord = pDataList - > GetDataRecord ( i ) ; if (! strcmp ( pDataRecord - > GetDataValue ( " BMGCANSEND " , true ) -> GetStringValue () ," Y " ) ) { // empfnger info . buyer = findid ( pDataRecord - > GetDataValue ( " AL_EMPF " ) -> GetStringValue () ," PI " ," NAME " , " BMGNR " ) ; ... // prfen der Daten auf Vollstndigkeit ... // login senden std :: string ticket_id = login_response ( transfer_bmg ( login_bmg ( bmg_user , bmg_pass ) , true ) ) ; // bmg nummer reservieren ... // bertragung senden std :: string incomming_id = sendincommings_response ( transfer_bmg ( sendincommings_bmg ( ticket_id , charge , info ) , false ) ) ; // logout senden logout_response ( transfer_bmg ( logout_bmg ( ticket_id ) , TRUE ) ) ; // BMG Nummer an auslagerung schreiben if (! strcmp ( bmgnumber . c_str () , incomming_id . c_str () ) ) { pDataRecord - > GetDataValue ( " BMGNR " ) -> SetStringValue ( bmgnumber . c_str () ) ;
Alexander Bonin
Seite 28 von 95
4. Implementierung
Fachhochschule Schmalkalden SS 2011 pDataRecord - > GetDataValue ( " BMGCANSEND " ) -> SetStringValue ( " " ) ;
} } } return true ; } Die Funktion holt sich also zuerst einmal alle Buchungsdatenstze die existieren. Dies wird mit folgenden Zeilen realisiert. pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " LBU " , true ) ; Als nchstes wird begonnen, mit Hilfe einer for-Schleife durch alle Buchungsdatenstze zu iterieren. Dabei wird die DataValue BMGCANSEND geprft. for ( int i = 0; pDataList - > GetDataRecordCount () ; i ++) { pDataRecord = pDataList - > GetDataRecord ( i ) ; if (! strcmp ( pDataRecord - > GetDataValue ( " BMGCANSEND " , true ) -> GetStringValue () ," Y " ) ) Enthlt diese den Wert Y wird der Buchungssatz entsprechend der Funktion send_bmg aufbereitet und gesendet. Sollte die DataValue einen anderen Wert enthalten wird der Buchungsdatensatz ignoriert und mit dem nchsten Buchungsdatensatz weitergemacht.
Alexander Bonin
Seite 29 von 95
4. Implementierung
// neues Document Anlegen Poco :: AutoPtr < Poco :: XML :: Document > pDoc = new Poco :: XML :: Document ; Poco :: AutoPtr < Poco :: XML :: ProcessingInstruction > pXMLHeader = pDoc - > createProcessingInstruction ( " xml " , " version = 1.0 encoding = utf -8 " ) ; pDoc - > appendChild ( pXMLHeader ) ; // documentenEnvelope anlegen - haengt direkt an pDoc also direktes unterelement des Dokuments Poco :: AutoPtr < Poco :: XML :: Element > pUri_def = pDoc - > createElement ( " SOAP - ENV : Envelope " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENV " ," http :// schemas . xmlsoap . org / soap / envelope / " ) ; .... pUri_def - > setAttribute ( " xmlns : xsi " ," http :// www . w3 . org /2001/ XMLSchema - instance " ) ; pDoc - > appendChild ( pUri_def ) ; Poco :: AutoPtr < Poco :: XML :: Element > pBody = pDoc - > createElement ( " SOAP - ENV : Body " ) ; pUri_def - > appendChild ( pBody ) ;
// sendIncomings Element als unterElement vom Body anlegen Poco :: AutoPtr < Poco :: XML :: Element > pfunction = pDoc - > createElement ( " ns1 : sendIncomings " ) ; pfunction - > setAttribute ( " xmlns : ns1 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pBody - > appendChild ( pfunction ) ; // ticket_id wird bergeben Poco :: AutoPtr < Poco :: XML :: Element > ptid = pDoc - > createElement ( " ns1 : ticketId " ) ; ptid - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > ptid_text = pDoc - > createTextNode ( ticket_id ) ; ptid - > appendChild ( ptid_text ) ; pfunction - > appendChild ( ptid ) ; // incomings container wird bergeben Poco :: AutoPtr < Poco :: XML :: Element > pinco = pDoc - > createElement ( " ns1 : incomings " ) ; pfunction - > appendChild ( pinco ) ;
Alexander Bonin
Seite 30 von 95
4. Implementierung
// charge feld anlegen Poco :: AutoPtr < Poco :: XML :: Element > pcharge = pDoc - > createElement ( " ns1 : charge " ) ; pinco - > appendChild ( pcharge ) ; ... // charge -> spezies Poco :: AutoPtr < Poco :: XML :: Element > pcharge7 = pDoc - > createElement ( " ns1 : spezies " ) ; pcharge7 - > setAttribute ( " xsi : type " ," xs : string " ) ; if ( charge . spezies != " " ) { Poco :: AutoPtr < Poco :: XML :: Text > pcharge7_text = pDoc - > createTextNode ( charge . spezies ) ; pcharge7 - > appendChild ( pcharge7_text ) ; } pcharge - > appendChild ( pcharge7 ) ; ... // info feld anlegen Poco :: AutoPtr < Poco :: XML :: Element > pinfo = pDoc - > createElement ( " ns1 : info " ) ; pinco - > appendChild ( pinfo ) ; // info -> buyer ... // info -> quantityValue ... return pDoc ; } Alle Funktionen, die ein XML Dokument bauen, besitzen als Rckgabewert einen automatischen Zeiger auf ein XML Dokument( Poco::AutoPTR<Poco::XML::Document>). Innerhalb der Funktion wird ein neues XML Dokument generiert. Hierbei ist AutoPtr<Poco::XML::ProcessingInstruction> pXMLHeader fr die Headerinformationen des Dokumentes verantwortlich, in diesem Fall der Dokumententyp XML in der Version 1 mit der Zeichenkodierung UTF-8. Danach wird der Body des XML Dokuments erstellt und ein erstes Unterelement ns1:sendIncomings angehangen. Unter diesem wird als nchstes Unterelement die TicketID bergeben. Danach werden als weitere Unterelemente von ns1:sendIncomings die Elemente Charge und Info mit Ihren jeweiligen Merkmalen angehangen. Die Daten, die je nach zu bertragendem Produkt und Kufer in die XML Datei geschrieben werden, bekommt die Funktion in Form eines strukturierten Datentypes als Parameter bergeben. Die Denition der Datentypen erfolgt wie in Listing 4.11 abgebildet. Listing 4.11: Strukturierte Datentypen fr sendIncommings typedef struct info_st { std :: string buyer ; std :: string chargeid ;
Alexander Bonin
Seite 31 von 95
4. Implementierung std :: string quantityUnitID ; std :: string quantityValue ; } info_st ; typedef struct charge_st { std :: string article ; std :: string bmgnumber ; std :: string bmgrootid ; std :: string lablestandard ; std :: string printcode ; std :: string seller ; std :: string spezies ; std :: string type ; } charge_st ;
Fr die XML Blcke, Charge und Info, wird jeweils ein strukturierter Datentyp erstellt, der alle erforderlichen Informationen in Form von Strings aufnehmen kann. Als Beispiel fr ein Unterelement von Charge werden folgende Zeilen nher erlutern. Poco :: AutoPtr < Poco :: XML :: Element > pcharge7 = pDoc - > createElement ( " ns1 : spezies " ) ; pcharge7 - > setAttribute ( " xsi : type " ," xs : string " ) ; if ( charge . spezies != " " ) { Poco :: AutoPtr < Poco :: XML :: Text > pcharge7_text = pDoc - > createTextNode ( charge . spezies ) ; pcharge7 - > appendChild ( pcharge7_text ) ; } pcharge - > appendChild ( pcharge7 ) ; Zunchst wird pcharge7 als XML Element angelegt und ihm der Bezeichner ns1:spezies zugewiesen. Als nchstes wird der Elemententyp im XML Dokument bestimmt, in diesem Fall ein String. Danach kommt eine Abfrage, ob der Inhalt des Struct Elementes Text enthlt oder nicht. Diese Abfrage ndet nur bei den Elementen statt, die im XML Dokument optional sind. Sollte also im denierten strukturierten Datentypen das Feld charge.spezies leer sein wird das gesamte Element ns1:spezies nicht ins XML Dokument eingebunden. Analog zur Einbindung von Elementen im Chargeblock funktioiert auch die Einbindung des Infoblockes. Nach der erfolgreichen Generierung wird das Dokument pDoc mit Return pdoc als Funktionsrckgabewert an den aufrufenden Programmteil zurckgegeben.
Alexander Bonin
Seite 32 von 95
4. Implementierung
auslesen. Veranschaulicht wird das im Codelisting 4.12 der Funktion getmasterdata_response_buyer, die die Buyerdaten aus dem Antwortdokument eines erfolgreichen GetMasterdata Requests ausliest. Listing 4.12: Auslesen der Buyer Information aus dem Masterdata XML bool getmasterdata_response_buyer ( Poco :: AutoPtr < Poco :: XML :: Document > req , CADSDataList * pDataList ) { int counter = pDataList - > GetDataRecordCount () ; Poco :: XML :: NodeIterator it ( req , Poco :: XML :: NodeFilter :: SHOW_ELEMENT ) ; Poco :: XML :: Node * pNode = it . nextNode () ; // starte zaehlschleife fr eintraege try { std :: vector < buyer > buyer_vec ; buyer temp_buyer ; while ( pNode ) { // liest die buyer tabelle aus if ( pNode - > nodeName () == " ns : city " & pNode - > parentNode () -> nodeName () == " ns : buyer " ) { // std :: cout << " Stadt : " << pNode - > innerText () << std :: endl ; temp_buyer . city = pNode - > innerText () ; // pDataValue = pDataRecord - > GetDataValue (" ORT ") ; } ... pNode = it . nextNode () ; } // vector zu datavalues schreiben CADSDataRecord * pDataRecord ; // CADSDataValue * pDataValue ; CString bmg = " bmg_ " ; int writecount =0; for ( std :: vector < buyer >:: size_type i = 0; i < buyer_vec . size () ; i ++ ) { if (! existDataValue ( pDataList , " PNR " , bmg + buyer_vec [ i ]. holdingnumber . c_str () ) ) { pDataList - > AddDataRecord ( counter +
Alexander Bonin
Seite 33 von 95
4. Implementierung
Fachhochschule Schmalkalden SS 2011 writecount ) ; pDataRecord = pDataList - > GetDataRecord ( counter + writecount ) ; pDataRecord - > GetDataValue ( " PNR " ) -> SetStringValue ( bmg + buyer_vec [ i ]. holdingnumber . c_str () ) ; pDataRecord - > GetDataValue ( " BMGNR " ) -> SetStringValue ( buyer_vec [ i ]. holdingnumber . c_str () ) ; pDataRecord - > GetDataValue ( " ORT " ) -> SetStringValue ( buyer_vec [ i ]. city . c_str () ) ; pDataRecord - > GetDataValue ( " NAME " ) -> SetStringValue ( buyer_vec [ i ]. name . c_str () ) ; pDataRecord - > GetDataValue ( " PLZ " ) -> SetStringValue ( buyer_vec [ i ]. postalcode . c_str () ) ; pDataRecord - > GetDataValue ( " STR_NR " ) -> SetStringValue ( buyer_vec [ i ]. street . c_str () ) ; pDataRecord - > GetDataValue ( " STELLUNG " ) -> SetStringValue ( " P " ) ; writecount ++;
} } return true ; } catch ( Poco :: Exception error ) { return false ; } } Der bergabeparameter ist in diesem Fall ein XML Dokument. Da die ausgelesenen Daten innerhalb der Funktion direkt an die vorgesehenen Stellen geschrieben werden, ist der Rckgabewert lediglich ein boolscher Wert. Dieser kennzeichnet ob die Funktion erfolgreich ausgefhrt wurde oder nicht. Im Grunde wird in dieser Funktion durch alle Elemente des XML Dokumentes iteriert und der Wert der entsprechend wichtigen Elemente in einen vorbereiteten Vector geschrieben. Der in dieser Funktion verwendete Vector buyervec ist vom Typ buyer, ein vorher angelegter, strukturierter Datentyp, der folgendermaen aussieht: Listing 4.13: Aufbau des Vectors fr Buyer Informationen typedef struct buyer { std :: string city ; std :: string countrycode ;
Alexander Bonin
Seite 34 von 95
4. Implementierung std :: string std :: string std :: string std :: string std :: string std :: string } buyer ;
An dieser Stelle wurde ein Vector verwendet, da diesem beliebig Elemente angehangen werden knnen, ohne das der Umfang vorher bekannt sein muss. Man htte das Ganze auch mit einem Array vom Typ buyer lsen knnen, in dem man die enthaltenen Elemente erst zhlt und anschlieend das Array zur Laufzeit mit der ermittelten Gre erstellt. Nachdem nun alle Elemente des XML Dokuments durchlaufen und alle Informationen in den Vector geschrieben wurden, wird nun damit begonnen, die Informationen aus dem Vector an das Host-Programm zu bergeben. Alternativ htte man auch den Vector als Rckgabewert denieren knnen und in einer weiteren Funktion, das Schreiben der Informationen in das Host-Programm realisieren knnen. Zum Schreiben wird eine neue Schleife gestartet, welche die Durchlaufanzahl entsprechend der Gre des Vectors besitzt. Pro Durchlauf wird jetzt ein kompletter Datensatz in die Elsa-ko Datenbasis geschrieben. Innerhalb der Schleife wird zunchst die entsprechende DataList aufgerufen und als erstes anhand des Eintrags Holdingnumber geprft, ob der Datensatz schon existiert. Ist dies nicht der Fall, muss zunchst die Position an der der neue Datensatz erstellt werden soll ermittelt werden. Dazu wurde zu Beginn bereits die Anzahl der bereits vorhandenen Datenstze mit folgenden Zeilen ermittelt: int counter = pDataList - > GetDataRecordCount () ; Dieser Wert zusammen mit dem Wert writecount, welcher die Anzahl der aktuell geschriebenen Datenstze enthlt, ergibt die Position an welche der aktuelle Datensatz geschrieben wird. Ist die Position ermittelt, werden auf die einzelnen DataValues die entsprechenden Werte aus dem buyer-Struct des aktuellen Vectorelements geschrieben. Dies wird solange wiederholt, bis das Ende des Vectors erreicht ist. Anschlieend wird die Funktion mit TRUE fr alles in Ordnung oder FALSE wenn Fehler aufgetreten sind beendet.
Alexander Bonin
Seite 35 von 95
4. Implementierung
// http - client zur Datenbertragung an BMG Poco :: URI uri ; // URL einlesen und in path und host zerlegen if ( auth_id ) uri = " http :// demo . bio - mit - gesicht . de / services / AuthService " ; else uri = " http :// demo . bio - mit - gesicht . de / services / BmgService " ; std :: string path ( uri . getPathAndQuery () ) ; if ( path . empty () ) path = " / " ;
try { // httpclient verbindung aufbauen Poco :: Net :: HTTPClientSession bmg_session ( uri . getHost () , uri . getPort () ) ; // Proxyeinstellungen wenn notwendig bmg_session . setProxy ( " 192.168.10.10 " ,8080) ; // request Http_post mit zu string konvertiertem XML dokument erstellen und senden . Poco :: Net :: HTTPRequest request ( Poco :: Net :: HTTPRequest :: HTTP_POST , path , Poco :: Net :: HTTPMessage :: HTTP_1_1 ) ; // chunk -> false request . setChunkedTransferEncoding ( FALSE ) ; // lnge des Inhaltes ( xml - string ) setzen -> ansonsten EOF Error request . setContentLength ( node2str ( req ) . length () ) ; // und raus damit bmg_session . sendRequest ( request ) << node2str ( req ) ; // antwort von http Server abwarten und einlesen . Poco :: Net :: HTTPResponse response ; std :: istream & rs = bmg_session . receiveResponse ( response ) ; std :: string temp_string ; // antwort in einen string kopieren und zurckgeben Poco :: StreamCopier :: copyToString ( rs , temp_string ) ;
Alexander Bonin
Seite 36 von 95
4. Implementierung
return str2node ( temp_string ) ; } catch ( Poco :: Exception error ) { WriteMessage ( error . displayText () ) ; Poco :: AutoPtr < Poco :: XML :: Document > error_doc = new Poco :: XML :: Document ; return error_doc ; } } Die Funktion transfer_bmg bekommt als bergabeparameter zum einen ein beliebiges zu sendendes XML Dokument vom Typ Document. Zum anderen wird ihr ein boolscher Wert bergeben. Dieser Wert regelt, ob die bertragung ein Login/Logout Vorgang oder ein Datenbertragungsvorgang an Bio mit Gesicht ist. Fr den Fall, das der bergeben Wert True ist wird der Funktionsaufruf als Login/Logout Vorgang interpretiert und die Endpunkt Adresse auf http://demo.bio-mitgesicht.de/services/AuthService gesetzt. Ist der Wert FALSE, so wird ein Datenbertragungsvorgang vorbereitet, indem die Endpunktadresse auf http://demo.biomit-gesicht.de/services/BmgService gesetzt wird. Im Folgenden try-Block ndet die eigentliche bertragung statt. Zum einen wird die Endpunktadresse sinnvoll zerlegt, zum anderen werden einige Einstellungen wie ProxySettings ContentLenght und ChunkTransferEncoding gesetzt. Der eigentliche Sendevorgang ndet in der folgende Zeile statt. bmg_session . sendRequest ( request ) << node2str ( req ) ; Hier wird das in einen String umgewandelte XML Dokument (req) an den vorbereiteten Sende-Request bergeben und damit bertragen. Als Nchstes wird noch auf die Reaktion des Webservices gewartet. std :: istream & rs = bmg_session . receiveResponse ( response ) ; Der empfangene Stringstream wird zunchst wieder in einen String und von diesem String in ein XML Dokument umgewandelt und zurckgegeben. Sollte whrend einem dieser Vorgnge ein Fehler auftreten, wird automatisch der Catch-teil ausgefhrt. Dieser gibt den Fehler in Form eines XML Dokuments ber die Funktionsrckgabe zurck. Gleichzeitig wird mit der Funktion WriteMessage der Fehler aufbereitet und innerhalb der Wirtssoftware dargestellt, um den Nutzer ber diesen Vorgang in Kenntnis zu setzen.
Alexander Bonin
Seite 37 von 95
4. Implementierung
std :: string node2str ( Poco :: AutoPtr < Poco :: XML :: Document > node ) { std :: strstream sss ; Poco :: XML :: XMLString temp_str ; Poco :: UTF8Encoding utf8encoding ; Poco :: XML :: DOMWriter writer ; writer . setEncoding ( " UTF -8 " , utf8encoding ) ; writer . setOptions ( Poco :: XML :: XMLWriter :: PRETTY_PRINT ) ; writer . setNewLine ( " \ n " ) ; writer . writeNode ( sss , node ) ; sss << \0 ; temp_str = sss . str () ; Poco :: trimInPlace ( temp_str ) ; Poco :: XML :: toXMLString ( temp_str ) ; return temp_str ; } Zuerst werden einige Variablen deniert. Eine Variable vom Typ Stringstream, eine Variable fr das TextEncoding und natrlich wird der eigentlich Writer angelegt. Danach wird dem Writer zunchst das Zeichenencoding, in diesem Fall UTF-8 1 , per setEncoding bergeben. Spter folgt das Setzen der Ausgabeoption PRETTY_PRINT, die den Writer dazu bewegt das gesamte XML Dokument inklusive der XML Deklaration auszugeben. Hinterher wird der XML Writer per writenode dazu veranlasst, alle XML Daten aus dem bergabeparameter Node in den Stringstream sss zu schreiben. Anschlieend wird das ende des Stringstreams mit 0 markiert. Dann wird, per sss.str(), der Stringstream in eine Variable vom Typ String geschrieben. Mit der Funktion trimInPlace werden danach alle berssigen Leerzeichen entfernt. Zum Schluss wird der fertige String ber den Funktionsnamen zurckgegeben.
UTF-8 ist ein 8 bit Universal Character Set Transofmration Format und eine der am weitesten verbreitete Kodierung fr Unicode-Zeichen.
Alexander Bonin
Seite 38 von 95
4. Implementierung
Poco :: AutoPtr < Poco :: XML :: Document > str2node ( std :: string response_string ) { std :: istringstream istr ( response_string ) ; Poco :: XML :: InputSource src ( istr ) ; Poco :: XML :: DOMParser parser ; Poco :: AutoPtr < Poco :: XML :: Document > pDoc = parser . parse (& src ) ; return pDoc ; } Die eigentliche Umwandlung bernimmt der Befehl parser.parse(&src). Dieser gibt ein XML Dokument zurck, das anschlieend ber den Funktionsnamen zurckgegeben wird.
4.2.6 Netzverfgbarkeit
Zum Prfen der Netzverfgbarkeit wird auf die Funktion InternetGetConnectedState aus der Wininet.h zurckgegrien. Diese liefert als Wahrheitswert True zurck, wenn eine Netzverbindung vorhanden ist. Wenn die Bedingung der Netzverfgbarkeit erfllt ist, wird als nchster Schritt der Endpunkt, der als Paramter URL bergeben wird, geprft. Dazu wird mit InternetCheckConnection eine Verbindung zum bergebenen Endpunkt aufgebaut. Ist dies erfolgreich, so wird True zurckgegeben und damit die Funktion beendet, ansonsten wird die Funktion mit False als Rckgabewert beendet. Listing 4.17: Prfen auf Netzverfgbarkeit bool checknet ( LPCTSTR url ) { DWORD dwFlags ; if ( InternetGetConnectedState (& dwFlags , 0) ) { if ( InternetCheckConnection ( url , FLAG_ICC_FORCE_CONNECTION ,0) ) { return true ;} else { return false ;} } else { return false ; } return true ; }
Alexander Bonin
Seite 39 von 95
4. Implementierung
welche per GetMasterData synchronisiert wurde, entnommen werden. Diese Liste beinhaltet beispielsweise folgendes: Listing 4.18: Beispiel fr einen Unit Eintrag < n s : u n i t t y p e =" net . blitz . bmg . entity . Quantity "> <ns:name>Dezitonne< / ns:name> < n s : u n i t i d >12< / n s : u n i t i d > Das heit: Bio mit Gesicht erwartet fr Chargen, die in der Einheit Dezitonne bertragen werden als EinheitenID den Wert 12. In Elsa-ko wird die Einheit Dezitonne aber mit dt bezeichnet. Aus diesem Grund ist es notwendig, den String dt auf den String Dezitonne zu mappen. Nur auf diese Art kann eine Verbindung zwischen dem String dt und der Einheitenid 12 herzustellen. Listing 4.19: Mappen unterschiedlicher Einheitenbezeichner std :: string findunit ( std :: string data ) { std :: string einhvgl [8][2]={ { " dt " ," Dezitonne " } , { " Stk " ," Stck " } , { " Stk . " ," Stck " } , { " kg " ," Kilogramm " } , { " g " ," Gramm " } , { " l " ," Liter " } , { " t " ," Tonne " } , }; for ( int i =0; i < sizeof ( einhvgl ) ; i ++) { if (! strcmp ( data . c_str () , einhvgl [ i ][0]. c_str () ) ) { return einhvgl [ i ][1]; } } return " " ; } Dazu wird ein mehrdimensionales String Array einhvgl angelegt, bestehend aus acht Zeilen und zwei Spalten. Pro Zeile beinhaltet es als ersten Wert den Einheitenbezeichner in Elsa-ko und als zweiten Wert den Einheitenbezeichner von Bio mit Gesicht. Wird diese Funktion nun aufgerufen, durchluft sie alle Zeilen des String Arrays und sucht in der ersten Spalte nach bereinstimmungen mit dem bergabeparameter der Funktion. Wenn sie eine bereinstimmung festgestellt hat, gibt sie den Inhalt der zweiten Spalte der betreenden Zeile ber den Funktionsnamen zurck und wird beendet. Wird sie nicht fndig gibt Sie einen Leerstring zurck und beendet sich auch.
Alexander Bonin
Seite 40 von 95
4. Implementierung
gefunden, wird False zurckgegeben. Auf die Struktur der Datenhaltung in Elsako wurde in Kapitel 3.5 schon eingegangen. Als bergabeparameter bekommt die Funktion die Bezeichner der Datalist und Datavalue, sowie den Inhalt nach dem in den Datavalues zu suchen ist. Nun wird die DataList aus dem gesamten Datenbestand geholt und anschlieend mit einer for-Schleife durch alle in dieser Liste vorhanden DataRecords iteriert. Whrend jedes Schleifendurchlaufes wird im aktuellen Record der Wert, der im angegebenen DataValue hinterlegt ist mit dem Suchstring verglichen, dazu wird die Funktion strcmp benutzt.Ist der Vergleich erfolgreich wird die Funktion sofort mit return true beendet wird die Schleife komplett durchlaufen ohne das der Vergleich erfolgreich war, wird die Funktoin mit return false beendet. Listing 4.20: Aunden eines Wertes in den Gesamtdaten bool existDataValue ( CADSDataList * pDataList , CStringValue , CString searchstring ) { CADSDataRecord * pDataRecord ; CADSDataValue * pDataValue ; // pDataList - > FindDataRecord ( // iterator durch data record for ( int i = 0; i < pDataList - > GetDataRecordCount () ; i ++) { pDataRecord = pDataList - > GetDataRecord ( i ) ; pDataValue = pDataRecord - > GetDataValue ( Value ) ; // wenn suchwert schon existiert bende funktion mit rckgabewert true if (! strcmp ( pDataValue - > GetStringValue () , searchstring ) ) { return true ;} } return false ; }
Alexander Bonin
Seite 41 von 95
4. Implementierung
Zuerst wird die DataList mit dem bergebenen Bezeichner geladen und die Lnge dieser ausgelesen. Danach wird mit einer Schleife die gesamte Datenliste durchlaufen und im bergebenen Valuefeld nach dem bergebenen Wert gesucht. Sollte dieser gefunden werden, wird der Inhalt des ReturnValue Feldes zurckgegeben und die Funktion beendet. Wenn die Suche erfolglos ist, wird ein Leerstring zurckgegeben und die Funktion ebenfalls beendet. Listing 4.21: Auslesen der ID Werte von Bio mit Gesicht CString findid ( CString data , CString DataList , CString searchValue , CString returnvalue ) { CADSDataList * searchDataList = CADSDataStore :: GetDataStore () -> GetDataList ( DataList , true ) ; CADSDataRecord * searchDataRecord ; for ( int i = 0; i < searchDataList - > GetDataRecordCount () ; i ++) { searchDataRecord = searchDataList - > GetDataRecord ( i ); if (! strcmp ( searchDataRecord - > GetDataValue ( searchValue ) -> GetStringValue () , data ) ) { return searchDataRecord - > GetDataValue ( returnvalue ) -> GetStringValue () ; } } return " " ; }
Alexander Bonin
Seite 42 von 95
5 Fazit
Das Ziel der vorliegenden Arbeit war es ein Plugin mit einer Schnittstelle zu entwickeln. Diese Schnittstelle sollte den Webservice Bio mit Gesicht an die Schlagdokumentationssoftware Elsa-ko anbinden. Zu diesem Zweck wurde der Funktionsumfang des Webservices geprft. Daraufhin mussten auf Bio mit Gesicht Seite einige nderungen vorgenommen werden, da die Schnittstellenbeschreibung nicht dem tatschlichen Funktionsumfang entsprach. Nach dieser nderung konnte der Webservice als Plugin unter Elsa-ko implementiert werden. Im Laufe der Entwicklung ergab sich die Ntzlichkeit einer weiteren, ber welche in Zukunft nachgedacht werden sollte. Das Anbieten eines Anmeldeassistenten um den Kunden die Anmeldung bei Bio mit Gesicht zu erleichtern. Des Weiteren wrde dies Probleme mit mglicherweise unterschiedlichen Schreibweisen zwischen Bio mit Gesicht und Elsa-ko, verhindern. In wie weit das Plugin Zuspruch beim Kunden ndet ist zu diesem Zeitpunkt nicht zu sagen. Dennoch ist diese Erweiterung ein Alleinstellungsmerkmal gegenber allen anderen elektronischen Schlagdokumentationen, und aus diesem Grund ein ntzliches Marketinginstrument.
Alexander Bonin
Seite 43 von 95
Literaturverzeichnis
[App] Applied Informatics Software Engineering GmbH (Hrsg.): Poco C++ Libraries. http://pocoproject.org/, Abruf: 24. August. 2011 [Bec09] Becher, M.: XML. W3L GmbH, 2009. ISBN 9783937137698 [Bio] Bio mit Gesicht GmbH (Hrsg.): Sehen wos herkommt. http://www. bio-mit-gesicht.de/6484.html, Abruf: 24. August. 2011 [Bh02] Bhm, Fuchs E. Rolf: System-Entwicklung in der Wirtschaftsinformatik. vdf Hochschulverlag AG, 2002. ISBN 9783728127624 [Fin09] Finger, Zeppenfeld Prof. Dr. K. Patrik: Informatik im Fokus - SOA und WebServices. Springer Verlag, 2009. ISBN 9783540769903 [Ges] Geschftsstelle Bundesprogramm kologischer Landbau und andere Formen nachaltiger Landwirtschaft in der Bundesanstalt fr Landwirtschaft und Ernhrung (Hrsg.): Warenrckverfolgbarkeit - Einfhrung. http://www. oekolandbau.de/verarbeiter/qualitaet/warenrueckverfolgbarkeit/ warenrueckverfolgbarkeit-einfuehrung/, Abruf: 24. August. 2011 [Iby] Ibykus AG (Hrsg.): Was wird bentigt, um ELSA-agrar R , ELSA-wein und ELSA-ko nutzen zu knnen? http://www.elsa-agrar.de/content/view/ 25/40/, Abruf: 24. August. 2011 [Kur] Kuratorium fr Technik und Bauwesen in der Landwirtschaft e. V. (Hrsg.): Die Landwirtschaft spricht AgroXML. http://www.agroxml. de/index.php, Abruf: 24. August. 2011 [T.R01] T.Ray, Brodacki O. Erik: Einfhrung in XML. OREILLY Verlag GmbH, 2001. ISBN 9783897212862
Alexander Bonin
44
A Quellcodelistings
Appendix
A.1 BMGModul.h
Listing A.1: Inhalt der BMGModul Headerdatei # pragma once # ifdef _AFXDLL # pragma message ( " _AFXDLL " ) # ifdef IBKBMGMODUL # pragma message ( " IBKBMGMODUL " ) # define IBKBMGMODUL_EXT_DATA __declspec ( dllexport ) # define IBKBMGMODUL_EXT_CLASS __declspec ( dllexport ) # define IBKBMGMODUL_EXT_API extern " C " __declspec ( dllexport ) # else # pragma todo ( " no IBKBMGMODUL " ) # define IBKBMGMODUL_EXT_DATA __declspec ( dllimport ) # define IBKBMGMODUL_EXT_CLASS __declspec ( dllimport ) # define IBKBMGMODUL_EXT_API __declspec ( dllimport ) # endif IBKBMGMODUL # else # pragma todo ( " no _AFXDLL " ) # define IBKBMGMODUL_EXT_DATA # define IBKBMGMODUL_EXT_CLASS # define IBKBMGMODUL_EXT_API # endif _AFXDLL IBKBMGMODUL_EXT_API bool Initialize () ; IBKBMGMODUL_EXT_API bool RegistrationFinished ( CADSModulRegistration * pModulRegistration ) ; IBKBMGMODUL_EXT_API bool CheckModulVersion ( LPCTSTR pType , int nStoredVersion , int & nCurrentVersion ) ;
Alexander Bonin
45
A. Quellcodelistings
IBKBMGMODUL_EXT_API bool GetFunction ( LPCTSTR pType , CString & zFunction , CValuePairArray & arrValues ) ; IBKBMGMODUL_EXT_API LPCTSTR GetParameter ( LPCTSTR pParameter ) ; IBKBMGMODUL_EXT_API bool test_bmg ( CADSModulPara & recModulPara ) ; IBKBMGMODUL_EXT_API bool sync_bmg ( CADSModulPara & recModulPara ) ; IBKBMGMODUL_EXT_API bool send_bmg ( CADSModulPara & recModulPara ) ; IBKBMGMODUL_EXT_API bool del_bmg ( CADSModulPara & recModulPara ) ; IBKBMGMODUL_EXT_API bool sendmarked_bmg ( CADSModulPara & recModulPara ) ;
A.2 BMGModul.cpp
Listing A.2: Inhalt der BMGModul.cpp // BmgModul . cpp : Defines the entry point for the DLL application . // # include " stdafx . h " # include < ADSbase .h > # include < ADSdia .h > # include " v :\ source \ ADSdia \ MainFrm . h " # include " poco \ poco . h " # include " structs . h " # include " BmgModul . h " # include " functions . h " # include " xml_builds . h " # include " xml_results . h " # include < string >
# include " ..\..\ Exe \ basis \ ELSAAction . h " # include " ..\..\ Exe \ basis \ ELSAProject . h "
# ifdef _DEBUG # define new DEBUG_NEW # undef THIS_FILE static char THIS_FILE [] = __FILE__ ; # endif
Alexander Bonin
46
A. Quellcodelistings
# ifdef _AFXDLL # include < afxdllx .h > BOOL APIENTRY DllMain ( HANDLE /* hModule */ , DWORD ul_reason_for_call , LPVOID /* lpReserved */ ) { switch ( ul_reason_for_call ) { case DLL_PROCESS_ATTACH : case DLL_THREAD_ATTACH : case DLL_THREAD_DETACH : case DLL_PROCESS_DETACH : break ; } return TRUE ; } # endif _AFXDLL
// aktionen modulinitialisierung IBKBMGMODUL_EXT_API bool Initialize () { // return CADSMessageHandler :: GetInstance () -> LoadFile (" BmgModulMessage . zip " ,0 ," BmgModul ") ; return true ; } IBKBMGMODUL_EXT_API bool CheckModulVersion ( LPCTSTR pType , int nStoredVersion , int & nCurrentVersion ) { // if (! pType ) return false ; // nCurrentVersion = 1; // if ( nStoredVersion >= 0 && nStoredVersion <= nCurrentVersion ) { // return true ; // } else { // return false ; // }
Alexander Bonin
47
IBKBMGMODUL_EXT_API bool RegistrationFinished ( CADSModulRegistration * pModulRegistration ) { // Die Funktion wird nach dem Laden aller Module und dem Berechnen der // Registrierungen bzw . nach dem Eintrag eines neuen Schlssels aufgerufen // Reference um warnung zu umgehen pModulRegistration ; bool bRetcode = true ; // WriteMessage (" Modul offensichtlich geladen .") ; return bRetcode ; } IBKBMGMODUL_EXT_API LPCTSTR GetParameter ( LPCTSTR pParameter ) { if (! strcmp ( pParameter , " Name " ) ) return " BMG - Modul " ; else if (! strcmp ( pParameter , " FunctionList " ) ) return " test_bmg , sync_bmg , send_bmg , del_bmg , sendmarked_bmg " ; // , send_bmg , del_bmg else if (! strcmp ( pParameter , " Version " ) ) return " 1.0.0 " ; // OnNewRelease else if (! strcmp ( pParameter , " DemoDays " ) ) return " 100 " ; else if (! strcmp ( pParameter , " Points " ) ) return " 10 " ; else if (! strcmp ( pParameter , " ValidEnd " ) ) return " 2012 -12 -31 " ; else if (! strcmp ( pParameter , " RegType " ) ) return " No " ; // No , Modul , Bundle else return NULL ; }
IBKBMGMODUL_EXT_API bool GetFunction ( LPCTSTR pType , CString & zFunction , CValuePairArray & arrValues ) { bool bRetcode = true ; // Reference um warnung zu umgehen arrValues ; zFunction ; pType ;
Alexander Bonin
48
A. Quellcodelistings
if ( ! strcmp ( pType , " test_bmg " ) ) { zFunction = " test_bmg " ; } else if (! strcmp ( pType , " sync_bmg " ) ) { zFunction = " sync_bmg " ; } else if (! strcmp ( pType , " send_bmg " ) ) { zFunction = " send_bmg " ; } else if (! strcmp ( pType , " del_bmg " ) ) { zFunction = " del_bmg " ; } else if (! strcmp ( pType , " sendmarked_bmg " ) ) { zFunction = " sendmarked_bmg " ; } else { bRetcode = false ; // wenn funktion nicht gefunden } return bRetcode ; } IBKBMGMODUL_EXT_API bool test_bmg ( CADSModulPara & recModulPara ) { if (! checknet ( " http :// demo . bio - mit - gesicht . de / services / AuthService " ) ) { WriteMessage ( " Es besteht keine Internetverbindung ."); return false ; } std :: string bmg_user ; std :: string bmg_pass ; CADSDataList * pDataList ; CADSDataRecord * pDataRecord ; pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG_CONF " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; bmg_user = pDataRecord - > GetDataValue ( " BMGNR " ) -> GetStringValue () ; bmg_pass = pDataRecord - > GetDataValue ( " BMGPW " ) -> GetStringValue () ; std :: string ticket_id = login_response ( transfer_bmg ( login_bmg ( bmg_user , bmg_pass ) , true ) ) ; logout_response ( transfer_bmg ( logout_bmg ( ticket_id ) , true ) ) ; if ( ticket_id != " " ) { return true ; } else { return false ; } }
Alexander Bonin
49
A. Quellcodelistings
IBKBMGMODUL_EXT_API bool sync_bmg ( CADSModulPara & recModulPara ) { if (! checknet ( " http :// demo . bio - mit - gesicht . de / services / AuthService " ) ) { WriteMessage ( " Es besteht keine Netzverbindung . " ) ; return false ; } // TODO recaction input output mitgeben lassen !!!! Poco :: AutoPtr < Poco :: XML :: Document > main_document = new Poco :: XML :: Document ; // definiere Variablen zum auslesen der Elsa daten CADSDataStore * pDataStore = CADSDataStore :: GetDataStore () ; CADSDataList * pDataList ; CADSDataRecord * pDataRecord ; // CADSDataValue * pDataValue ;
// auslesen der BMG Configurationsdaten std :: string bmg_user ; std :: string bmg_pass ; pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG_CONF " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; bmg_user = pDataRecord - > GetDataValue ( " BMGNR " ) -> GetStringValue () ; bmg_pass = pDataRecord - > GetDataValue ( " BMGPW " ) -> GetStringValue () ; std :: string ticket_id = login_response ( transfer_bmg ( login_bmg ( bmg_user , bmg_pass ) , true ) ) ; main_document = transfer_bmg ( getmasterdata_bmg ( ticket_id ) , false ) ; logout_response ( transfer_bmg ( logout_bmg ( ticket_id ) , TRUE ) ) ; pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " PI " , true ) ; getmasterdata_response_buyer ( main_document , pDataList ) ; pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG " , true ) ;
Alexander Bonin
50
A. Quellcodelistings
IBKBMGMODUL_EXT_API bool send_bmg ( CADSModulPara & recModulPara ) { // definiere Variablen zum auslesen der Elsa daten CADSDataStore * pDataStore = CADSDataStore :: GetDataStore () ; CADSDataList * pDataList ; CADSDataRecord * pDataRecord ; CADSDataList * searchDataList ; std :: string bmg_user ; std :: string bmg_pass ; std :: string bmg_transfer ; std :: string bmg_ask ; std :: string bmgnumber ; CString temp ; struct charge_st charge ; struct info_st info ; // auslesen der BMG Configurationsdaten pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG_CONF " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; bmg_user = pDataRecord - > GetDataValue ( " BMGNR " ) -> GetStringValue () ; bmg_pass = pDataRecord - > GetDataValue ( " BMGPW " ) -> GetStringValue () ; bmg_transfer = pDataRecord - > GetDataValue ( " BMGTRANS " ) -> GetStringValue () ; bmg_ask = pDataRecord - > GetDataValue ( " BMGASKUSER " ) -> GetStringValue () ; // bmgnummer und sellernummer - charge charge . seller = pDataRecord - > GetDataValue ( " BMGMID " ) -> GetStringValue () ; // auslesen der Anbauverband pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " UI " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ;
Alexander Bonin
51
A. Quellcodelistings
searchDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG " , true ) ; charge . lablestandard = searchDataList - > FindDataRecord ( " BMGBEZ " , pDataRecord - > GetDataValue ( " ANBVERB " ) -> GetStringValue () ) -> GetDataValue ( " BMGID " ) -> GetStringValue () ; // auslagerungs informationen auslesen pDataRecord = recModulPara . pMODDataRecord ; // empfnger info . buyer = findid ( pDataRecord - > GetDataValue ( " AL_EMPF " ) -> GetStringValue () ," PI " ," NAME " ," BMGNR " ) ; // Einheit der Ware - info ( findunit -> einheitenmapping ) info . quantityUnitID = findid ( findunit ( pDataRecord - > GetDataValue ( " AL_EINH " , true ) -> GetStringValue () ) ," BMG " ," BMGBEZ " ," BMGID " ) ; // Menge - info // info . quantityValue = sprintf (( pDataRecord - > GetDataValue (" AL_MNG " , true ) -> GetFloatValue () ) ; CString qValue ; qValue . Format ( " %.2 f " , pDataRecord - > GetDataValue ( " AL_MNG " , true ) -> GetFloatValue () ) ; info . quantityValue = qValue ; // artikel und Auslagerungsart - charge charge . article = pDataRecord - > GetDataValue ( " AL_BEZWARE " , true ) -> GetStringValue () ; charge . type = " Auslagerung " ; // suche Rootid zum Artikel aus der BMG Liste - charge charge . bmgrootid = findid ( pDataRecord - > GetDataValue ( " AL_BEZWARE " ) -> GetStringValue () ," BMG " ," BMGBEZ " ," BMGID " ) ; // prfen der Daten auf vollstndigkeit if ( charge . bmgrootid == " " || charge . lablestandard == " " || charge . seller == " " ) { return false ;} if ( info . buyer == " " || info . quantityUnitID == " " || info . quantityValue == " " ) { return false ;} if (! strcmp ( bmg_ask . c_str () ," J " ) ) {
Alexander Bonin
52
A. Quellcodelistings
if ( AskUser ( " Aktuelle Auslagerung an Bio mit Gesicht bertragen ? " , MB_YESNO | MB_ICONQUESTION ) != IDYES ) { return false ; } } // Prfen auf netzverfgbarkeit wenn kein netz zum bertragen vormerken if (! checknet ( " http :// demo . bio - mit - gesicht . de / services / AuthService " ) ) { pDataRecord - > GetDataValue ( " BMGCANSEND " ) -> SetStringValue ( " Y " ) ; WriteMessage ( " Es besteht keine Netzverbindung .\ nDer Datensatz wurde zum senden vorgemerkt . " ) ; return false ; } // login senden std :: string ticket_id = login_response ( transfer_bmg ( login_bmg ( bmg_user , bmg_pass ) , true ) ) ; // bmg nummer reservieren bmgnumber = getbmgnumbers_response ( transfer_bmg ( getbmgnumbers_bmg ( ticket_id ) , false ) ) ; charge . bmgnumber = bmgnumber . c_str () ; // bertragung senden std :: string incomming_id = sendincommings_response ( transfer_bmg ( sendincommings_bmg ( ticket_id , charge , info ) , false ) ) ; // logout senden logout_response ( transfer_bmg ( logout_bmg ( ticket_id ) , TRUE ) ) ; // BMG Nummer an auslagerung schreiben if (! strcmp ( bmgnumber . c_str () , incomming_id . c_str () ) ) { pDataRecord - > GetDataValue ( " BMGNR " ) -> SetStringValue ( bmgnumber . c_str () ) ; } return true ; }
Alexander Bonin
53
A. Quellcodelistings
IBKBMGMODUL_EXT_API bool del_bmg ( CADSModulPara & recModulPara ) { if (! checknet ( " http :// demo . bio - mit - gesicht . de / services / AuthService " ) ) { WriteMessage ( " Es besteht keine Internetverbindung ."); return false ; } std :: string bmg_user ; std :: string bmg_pass ; std :: string ticket_id ; CADSDataList * pDataList ; CADSDataList * searchDataList ; CADSDataRecord * pDataRecord ; struct charge_st charge ; pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG_CONF " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; bmg_user = pDataRecord - > GetDataValue ( " BMGNR " ) -> GetStringValue () ; bmg_pass = pDataRecord - > GetDataValue ( " BMGPW " ) -> GetStringValue () ; charge . seller = pDataRecord - > GetDataValue ( " BMGMID " ) -> GetStringValue () ; // auslesen der Anbauverband pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " UI " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; searchDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG " , true ) ; charge . lablestandard = searchDataList - > FindDataRecord ( " BMGBEZ " , pDataRecord - > GetDataValue ( " ANBVERB " ) -> GetStringValue () ) -> GetDataValue ( " BMGID " ) -> GetStringValue () ;
pDataRecord = recModulPara . pMODDataRecord ; charge . bmgnumber = pDataRecord - > GetDataValue ( " BMGNR " ) -> GetStringValue () ; // artikel und Auslagerungsart - charge charge . article = pDataRecord - > GetDataValue ( " AL_BEZWARE " , true ) -> GetStringValue () ;
Alexander Bonin
54
// suche Rootid zum Artikel aus der BMG Liste - charge charge . bmgrootid = findid ( pDataRecord - > GetDataValue ( " AL_BEZWARE " ) -> GetStringValue () ," BMG " ," BMGBEZ " ," BMGID " ) ;
std :: string temp_str ; ticket_id = login_response ( transfer_bmg ( login_bmg ( bmg_user , bmg_pass ) , true ) ) ; temp_str = sendcancellations_response ( transfer_bmg ( sendCancellations_bmg ( ticket_id , charge ) , false ) ) ; logout_response ( transfer_bmg ( logout_bmg ( ticket_id ) , true ) ) ; if (! strcmp ( temp_str . c_str () , charge . bmgnumber . c_str () )){ return true ; } else { return false ;} } IBKBMGMODUL_EXT_API bool sendmarked_bmg ( CADSModulPara & recModulPara ) { if (! checknet ( " http :// demo . bio - mit - gesicht . de / services / AuthService " ) ) { WriteMessage ( " Es besteht keine Internetverbindung ."); return false ; } // definiere Variablen zum auslesen der Elsa daten CADSDataStore * pDataStore = CADSDataStore :: GetDataStore () ; CADSDataList * pDataList ; CADSDataRecord * pDataRecord ; CADSDataList * searchDataList ; std :: string bmg_user ; std :: string bmg_pass ; std :: string bmg_transfer ; std :: string bmg_ask ; std :: string bmgnumber ; CString temp ; struct charge_st charge ; struct info_st info ; // auslesen der BMG Configurationsdaten
Alexander Bonin
55
A. Quellcodelistings
pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG_CONF " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; bmg_user = pDataRecord - > GetDataValue ( " BMGNR " ) -> GetStringValue () ; bmg_pass = pDataRecord - > GetDataValue ( " BMGPW " ) -> GetStringValue () ; bmg_transfer = pDataRecord - > GetDataValue ( " BMGTRANS " ) -> GetStringValue () ; bmg_ask = pDataRecord - > GetDataValue ( " BMGASKUSER " ) -> GetStringValue () ; // bmgnummer und sellernummer - charge charge . seller = pDataRecord - > GetDataValue ( " BMGMID " ) -> GetStringValue () ; // auslesen der Anbauverband pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " UI " , true ) ; pDataRecord = pDataList - > GetDataRecord (0) ; searchDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " BMG " , true ) ; charge . lablestandard = searchDataList - > FindDataRecord ( " BMGBEZ " , pDataRecord - > GetDataValue ( " ANBVERB " ) -> GetStringValue () ) -> GetDataValue ( " BMGID " ) -> GetStringValue () ;
// auslagerungs informationen auslesen pDataList = CADSDataStore :: GetDataStore () -> GetDataList ( " LBU " , true ) ; for ( int i = 0; i < pDataList - > GetDataRecordCount () ; i ++) { pDataRecord = pDataList - > GetDataRecord ( i ) ; charge . article = " " ; charge . bmgnumber = " " ; info . buyer = " " ; info . quantityUnitID = " " ; info . quantityValue = " " ; info . chargeid = " " ; if (! strcmp ( pDataRecord - > GetDataValue ( " BMGCANSEND " , true ) -> GetStringValue () ," Y " ) ) { // empfnger
Alexander Bonin
56
A. Quellcodelistings
info . buyer = findid ( pDataRecord - > GetDataValue ( " AL_EMPF " ) -> GetStringValue () ," PI " ," NAME " , " BMGNR " ) ; // Menge - info // info . quantityValue = sprintf (( pDataRecord - > GetDataValue (" AL_MNG " , true ) -> GetFloatValue () ) ; CString qValue ; qValue . Format ( " %.2 f " , pDataRecord - > GetDataValue ( " AL_MNG " , true ) -> GetFloatValue () ) ; info . quantityValue = qValue ; // artikel und Auslagerungsart - charge charge . article = pDataRecord - > GetDataValue ( " AL_BEZWARE " , true ) -> GetStringValue () ; // Einheit der Ware - info ( findunit -> einheitenmapping ) std :: string temp_einh = findid ( charge . article . c_str () ," LL " ," INH " ," EINH " ) ; info . quantityUnitID = findid ( findunit ( temp_einh . c_str () ) ," BMG " ," BMGBEZ " ," BMGID " ) ; charge . type = " Auslagerung " ; // suche Rootid zum Artikel aus der BMG Liste - charge charge . bmgrootid = findid ( pDataRecord - > GetDataValue ( " AL_BEZWARE " ) -> GetStringValue () ," BMG " ," BMGBEZ " ," BMGID " ) ; // prfen der Daten auf vollstndigkeit if ( charge . bmgrootid == " " || charge . lablestandard == " " || charge . seller == " " ) { return false ;} if ( info . buyer == " " || info . quantityUnitID == " " || info . quantityValue == " " ) { return false ;} // login senden std :: string ticket_id = login_response ( transfer_bmg ( login_bmg ( bmg_user , bmg_pass ) , true ) ) ;
Alexander Bonin
57
A. Quellcodelistings
// bmg nummer reservieren bmgnumber = getbmgnumbers_response ( transfer_bmg ( getbmgnumbers_bmg ( ticket_id ) , false ) ) ; charge . bmgnumber = bmgnumber . c_str () ; // bertragung senden std :: string incomming_id = sendincommings_response ( transfer_bmg ( sendincommings_bmg ( ticket_id , charge , info ) , false ) ) ; // logout senden logout_response ( transfer_bmg ( logout_bmg ( ticket_id ) , TRUE ) ) ; // BMG Nummer an auslagerung schreiben pDataRecord - > GetDataValue ( " BMGNR " ) -> SetStringValue ( charge . bmgnumber . c_str () ) ; pDataRecord - > GetDataValue ( " BMGCANSEND " ) -> SetStringValue ( " " ) ; } } return true ; }
A.3 functions.h
Listing A.3: Inhalt der functions Headerdatei # include < ADSbase .h > # include " Poco / DOM / DocumentType . h " # include " Poco / DOM / Document . h " # include " Poco / DOM / Element . h " # include " Poco / DOM / Text . h " // # include " Poco / DOM / AutoPtr . h " # include # include # include # include # include " Poco / DOM / DOMWriter . h " " Poco / XML / XMLWriter . h " " Poco / DOM / DOMParser . h " " Poco / XML / XMLStream . h " " Poco / SAX / InputSource . h "
Alexander Bonin
58
A. Quellcodelistings
" Poco / URI . h " " Poco / StreamCopier . h " " Poco / Net / HTTPRequestHandlerFactory . h " " Poco / Net / HTTPServerRequest . h " " Poco / Net / HTTPServerResponse . h " " Poco / Net / HTTPClientSession . h " " Poco / AutoPtr . h "
# include " Poco / String . h " # include " Poco / UTF8Encoding . h " # include " Poco / Exception . h " // Einheitenvergleich CString findunit ( CString data ) ; // BMG ID finden CString findid ( CString data , CString DataList , CString searchValue , CString returnvalue ) ; // string dataValue exist bool existDataValue ( CADSDataList * pDataList , CString Value , CString searchstring ) ; // String 2 int int str2int ( std :: string conv_string ) ; std :: string int2str ( int number ) ; // XML Parser Poco :: AutoPtr < Poco :: XML :: Document > str2node ( std :: string response_string ) ; // XMLDocument in String Konvertieren std :: string node2str ( Poco :: AutoPtr < Poco :: XML :: Document > node ) ; /* bertrgt ein XML Document an BMG und gibt die antwort als Document zurck auth_id sagt der funktion ob das xml Dokument an die Auth schnittstelle auth_id = true oder an die BMGService Schnittstelle gehen soll auth_id = false */
Alexander Bonin
59
A. Quellcodelistings
Poco :: AutoPtr < Poco :: XML :: Document > transfer_bmg ( Poco :: AutoPtr < Poco :: XML :: Document > req , bool auth_id ) ; /* Netzverbindung prfen */ bool checknet ( LPCTSTR url ) ;
A.4 functions.cpp
Listing A.4: Inhalt der functions.cpp # include " stdafx . h " # include " functions . h " // # include < Wininet .h > # include < afxinet .h >
CString findunit ( CString data ) { if (! strcmp ( data , " " ) ) { return " " ;} CString einhvgl [7][2]={ { " dt " ," Dezitonne " } , { " Stk " ," Stck " } , { " Stk . " ," Stck " } , { " kg " ," Kilogramm " } , { " g " ," Gramm " } , { " l " ," Liter " } , { " t " ," Tonne " } }; for ( int i =0; i < sizeof ( einhvgl ) ; i ++) { if (! strcmp ( data , einhvgl [ i ][0]) ) { return einhvgl [ i ][1]; } } return " " ; } CString findid ( CString data , CString DataList , CString searchValue , CString returnvalue ) { if (! strcmp ( data , " " ) ) { return " " ;} CADSDataList * searchDataList = CADSDataStore :: GetDataStore () -> GetDataList ( DataList , true ) ; CADSDataRecord * searchDataRecord ; int j = searchDataList - > GetDataRecordCount () ; for ( int i = 0; i < searchDataList - > GetDataRecordCount () ; i ++) {
Alexander Bonin
60
A. Quellcodelistings
searchDataRecord = searchDataList - > GetDataRecord ( i ); if (! strcmp ( searchDataRecord - > GetDataValue ( searchValue ) -> GetStringValue () , data ) ) { return searchDataRecord - > GetDataValue ( returnvalue ) -> GetStringValue () ; } } return " " ; } // string dataValue exist bool existDataValue ( CADSDataList * pDataList , CString Value , CString searchstring ) { CADSDataRecord * pDataRecord ; CADSDataValue * pDataValue ; // pDataList - > FindDataRecord ( // iterator durch data record for ( int i = 0; i < pDataList - > GetDataRecordCount () ; i ++) { pDataRecord = pDataList - > GetDataRecord ( i ) ; pDataValue = pDataRecord - > GetDataValue ( Value ) ; // wenn suchwert schon existiert bende funktion mit rckgabewert true if (! strcmp ( pDataValue - > GetStringValue () , searchstring ) ) { return true ;} } return false ; } // StringtoInt konverter int str2int ( std :: string conv_string ) { std :: istringstream isst ; int strnumber =0; isst . str ( conv_string ) ; isst >> strnumber ; return strnumber ; } std :: string int2str ( int number ) { std :: stringstream ss ; // create a stringstream ss << number ; // add number to the stream return ss . str () ; // return a string with the contents of the stream }
Alexander Bonin
61
A. Quellcodelistings
// XML Parser Poco :: AutoPtr < Poco :: XML :: Document > str2node ( std :: string response_string ) { std :: istringstream istr ( response_string ) ; Poco :: XML :: InputSource src ( istr ) ; Poco :: XML :: DOMParser parser ; Poco :: AutoPtr < Poco :: XML :: Document > pDoc = parser . parse (& src ) ; return pDoc ; } // XMLDocument in String Konvertieren std :: string node2str ( Poco :: AutoPtr < Poco :: XML :: Document > node ) { std :: strstream sss ; Poco :: XML :: XMLString temp_str ; Poco :: UTF8Encoding utf8encoding ; Poco :: XML :: DOMWriter writer ; writer . setEncoding ( " UTF -8 " , utf8encoding ) ; writer . setOptions ( Poco :: XML :: XMLWriter :: PRETTY_PRINT ) ; writer . setNewLine ( " \ n " ) ; writer . writeNode ( sss , node ) ; sss << \0 ; temp_str = sss . str () ; Poco :: trimInPlace ( temp_str ) ; Poco :: XML :: toXMLString ( temp_str ) ; return temp_str ; }
// bertrgt ein XML Document an BMG und gibt die antwort als Document zurck Poco :: AutoPtr < Poco :: XML :: Document > transfer_bmg ( Poco :: AutoPtr < Poco :: XML :: Document > req , bool auth_id ) {
// http - client zur Datenbertragung an BMG Poco :: URI uri ; // URL einlesen und in path und host zerlegen
Alexander Bonin
62
A. Quellcodelistings
if ( auth_id ) uri = " http :// demo . bio - mit - gesicht . de / services / AuthService " ; else uri = " http :// demo . bio - mit - gesicht . de / services / BmgService " ; std :: string path ( uri . getPathAndQuery () ) ; if ( path . empty () ) path = " / " ;
try { // httpclient verbindung aufbauen Poco :: Net :: HTTPClientSession bmg_session ( uri . getHost () , uri . getPort () ) ; // Proxyeinstellungen wenn notwendig bmg_session . setProxy ( " 192.168.10.10 " ,8080) ; // request Http_post mit zu string konvertiertem XML dokument erstellen und senden . Poco :: Net :: HTTPRequest request ( Poco :: Net :: HTTPRequest :: HTTP_POST , path , Poco :: Net :: HTTPMessage :: HTTP_1_1 ) ; // keine bertragung in chunks request . setChunkedTransferEncoding ( FALSE ) ; // lnge des Inhaltes ( xml - string ) setzen -> ansonsten EOF Error request . setContentLength ( node2str ( req ) . length () ) ; // und raus damit bmg_session . sendRequest ( request ) << node2str ( req ) ; // antwort von http Server abwarten und einlesen . Poco :: Net :: HTTPResponse response ; std :: istream & rs = bmg_session . receiveResponse ( response ) ; std :: string temp_string ; // antwort in einen string kopieren und zurckgeben Poco :: StreamCopier :: copyToString ( rs , temp_string ) ; return str2node ( temp_string ) ; } catch ( Poco :: Exception error )
Alexander Bonin
63
A. Quellcodelistings {
// std :: cout << "( Error : " << error . displayText () << ) << std :: endl ; Poco :: AutoPtr < Poco :: XML :: Document > error_doc = new Poco :: XML :: Document ; return error_doc ; }
} bool checknet ( LPCTSTR url ) { DWORD dwFlags ; if ( InternetGetConnectedState (& dwFlags , 0) ) { if ( InternetCheckConnection ( url , FLAG_ICC_FORCE_CONNECTION ,0) ) { return true ;} else { return false ;} } else { return false ; } return true ; }
A.5 structs.h
Listing A.5: Denition der strukturierten Datentypen typedef struct buyer { std :: string city ; std :: string countrycode ; std :: string holdingnumber ; std :: string name ; std :: string name2 ; std :: string postalcode ; std :: string street ; std :: string type_id ; } buyer ; typedef struct product { CString artikel ; CString bmgrootid ; CString tid ;
Alexander Bonin
64
A. Quellcodelistings } product ; typedef struct us_liste { CString id ; CString name ; CString tid ; } us_liste ; typedef struct unit { std :: string name ; std :: string unitid ; } unit ;
typedef struct info_st { std :: string buyer ; std :: string chargeid ; std :: string quantityUnitID ; std :: string quantityValue ; } info_st ; typedef struct charge_st { std :: string article ; std :: string bmgnumber ; std :: string bmgrootid ; std :: string lablestandard ; std :: string printcode ; std :: string seller ; std :: string spezies ; std :: string type ; } charge_st ;
A.6 xml_builds.h
Listing A.6: Funktionen zum generieren von XML Dokumenten Headerdatei # include < ADSbase .h > // includes fr XML generierung # include " Poco / DOM / ProcessingInstruction . h "
Alexander Bonin
65
A. Quellcodelistings # include # include # include # include " Poco / DOM / Document . h " " Poco / DOM / Element . h " " Poco / DOM / Text . h " " Poco / DOM / AutoPtr . h "
// Ausnahmebehandlung # include " Poco / Exception . h " // # include // # include // # include // # include " Poco / DOM / DOMWriter . h " " Poco / XML / XMLWriter . h " " Poco / DOM / DOMParser . h " " Poco / XML / XMLStream . h "
// includes zum navigieren durch XML Doumente // # include " Poco / DOM / NodeIterator . h " // # include " Poco / DOM / NodeFilter . h " // inputsource 2 xml parser include // # include " Poco / SAX / InputSource . h " // includes fr Http verbindung /* # include " Poco / Net / DNS . h " # include " Poco / URI . h " # include " Poco / StreamCopier . h " # include " Poco / Net / HTTPRequestHandlerFactory . h " # include " Poco / Net / HTTPServerRequest . h " # include " Poco / Net / HTTPServerResponse . h " # include " Poco / Net / HTTPClientSession . h " # include " Poco / String . h " # include " Poco / UTF8Encoding . h " */
// generiert das logindokument Poco :: AutoPtr < Poco :: XML :: Document > login_bmg ( Poco :: XML :: XMLString bmg_uname , Poco :: XML :: XMLString bmg_passwd ) ; // logout Dokument generieren Poco :: AutoPtr < Poco :: XML :: Document > logout_bmg ( Poco :: XML :: XMLString ticket_id ) ; // getMasterdata Dokument
Alexander Bonin
66
A. Quellcodelistings
Poco :: AutoPtr < Poco :: XML :: Document > getmasterdata_bmg ( Poco :: XML :: XMLString ticket_id ) ; // sendIncommings Dokument Poco :: AutoPtr < Poco :: XML :: Document > sendincommings_bmg ( Poco :: XML :: XMLString ticket_id , struct charge_st charge , struct info_st info ) ; // Dokument zum Reservieren von BMG Nummern Poco :: AutoPtr < Poco :: XML :: Document > getbmgnumbers_bmg ( Poco :: XML :: XMLString ticket_id ) ; // Dokument zum Lschen von Chargen Poco :: AutoPtr < Poco :: XML :: Document > sendCancellations_bmg ( Poco :: XML :: XMLString ticket_id , struct charge_st charge );
A.7 xml_builds.cpp
Listing A.7: Funktionen zum generieren von XML Dokumenten # include " stdafx . h " # include " structs . h " # include " xml_builds . h " // c ++ Includes /* # include < iostream > # include < sstream > # include < fstream > # include < strstream > # include < stdio .h > # include < tchar .h > # include < string .h > /* !!! Login Dokument */
!!!
Poco :: AutoPtr < Poco :: XML :: Document > login_bmg ( Poco :: XML :: XMLString bmg_uname , Poco :: XML :: XMLString bmg_passwd ) { // BMG Login XML bauen . // neues Document Anlegen Poco :: AutoPtr < Poco :: XML :: Document > pDoc = new Poco :: XML :: Document ;
Alexander Bonin
67
A. Quellcodelistings
Poco :: AutoPtr < Poco :: XML :: ProcessingInstruction > pXMLHeader = pDoc - > createProcessingInstruction ( " xml " , " version = 1.0 encoding = utf -8 " ) ; pDoc - > appendChild ( pXMLHeader ) ; // documentenEnvelope anlegen - haengt direkt an pDoc also direktes unterelement des Dokuments Poco :: AutoPtr < Poco :: XML :: Element > pUri_def = pDoc - > createElement ( " SOAP - ENV : Envelope " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENV " ," http :// schemas . xmlsoap . org / soap / envelope / " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENC " ," http :// schemas . xmlsoap . org / soap / encoding / " ) ; pUri_def - > setAttribute ( " xmlns : axis2 " ," http :// webservice / bmg / blitz / net / " ) ; pUri_def - > setAttribute ( " xmlns : ns0 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : ns1 " ," http :// org . apache . axis2 / xsd " ) ; pUri_def - > setAttribute ( " xmlns : wsaw " ," http :// www . w3 . org /2006/05/ addressing / wsdl " ) ; pUri_def - > setAttribute ( " xmlns : wsdl " ," http :// schemas . xmlsoap . org / wsdl / " ) ; pUri_def - > setAttribute ( " xmlns : xs " ," http :// www . w3 . org /2001/ XMLSchema " ) ; pUri_def - > setAttribute ( " xmlns : xsi " ," http :// www . w3 . org /2001/ XMLSchema - instance " ) ; pDoc - > appendChild ( pUri_def ) ; Poco :: AutoPtr < Poco :: XML :: Element > pBody = pDoc - > createElement ( " SOAP - ENV : Body " ) ; pUri_def - > appendChild ( pBody ) ; // login Element als unterElement vom Body anlegen Poco :: AutoPtr < Poco :: XML :: Element > pLogin = pDoc - > createElement ( " ns1 : logIn " ) ; pLogin - > setAttribute ( " xmlns : ns1 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pBody - > appendChild ( pLogin ) ; // Kommentar einfgen funtkioniert bisher nciht // AutoPtr < Comment > pComm1 = pDoc - > createComment (" OPTIONAL ") ; // pComm1 - > appendChild ( pLogin ) ;
Alexander Bonin
68
A. Quellcodelistings
// Username und passwd werden als unterelemente von LogIn angelegt Poco :: AutoPtr < Poco :: XML :: Element > pUsern = pDoc - > createElement ( " ns1 : username " ) ; pUsern - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pUsern_text = pDoc - > createTextNode ( bmg_uname ) ; pUsern - > appendChild ( pUsern_text ) ; pLogin - > appendChild ( pUsern ) ; Poco :: AutoPtr < Poco :: XML :: Element > pPasswd = pDoc - > createElement ( " ns1 : passwd " ) ; pPasswd - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pPasswd_text = pDoc - > createTextNode ( bmg_passwd ) ; pPasswd - > appendChild ( pPasswd_text ) ; pLogin - > appendChild ( pPasswd ) ; return pDoc ; } /* !!! Logout Dokument */
!!!
Poco :: AutoPtr < Poco :: XML :: Document > logout_bmg ( Poco :: XML :: XMLString ticket_id ) { // BMG Login XML bauen . // neues Document Anlegen Poco :: AutoPtr < Poco :: XML :: Document > pDoc = new Poco :: XML :: Document ; Poco :: AutoPtr < Poco :: XML :: ProcessingInstruction > pXMLHeader = pDoc - > createProcessingInstruction ( " xml " , " version = 1.0 encoding = utf -8 " ) ; pDoc - > appendChild ( pXMLHeader ) ; // documentenEnvelope anlegen - haengt direkt an pDoc also direktes unterelement des Dokuments Poco :: AutoPtr < Poco :: XML :: Element > pUri_def = pDoc - > createElement ( " SOAP - ENV : Envelope " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENV " ," http :// schemas . xmlsoap . org / soap / envelope / " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENC " ," http :// schemas . xmlsoap . org / soap / encoding / " ) ; pUri_def - > setAttribute ( " xmlns : axis2 " ," http :// webservice / bmg / blitz / net / " ) ;
Alexander Bonin
69
A. Quellcodelistings
pUri_def - > setAttribute ( " xmlns : ns0 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : ns1 " ," http :// org . apache . axis2 / xsd " ) ; pUri_def - > setAttribute ( " xmlns : wsaw " ," http :// www . w3 . org /2006/05/ addressing / wsdl " ) ; pUri_def - > setAttribute ( " xmlns : wsdl " ," http :// schemas . xmlsoap . org / wsdl / " ) ; pUri_def - > setAttribute ( " xmlns : xs " ," http :// www . w3 . org /2001/ XMLSchema " ) ; pUri_def - > setAttribute ( " xmlns : xsi " ," http :// www . w3 . org /2001/ XMLSchema - instance " ) ; pDoc - > appendChild ( pUri_def ) ; Poco :: AutoPtr < Poco :: XML :: Element > pBody = pDoc - > createElement ( " SOAP - ENV : Body " ) ; pUri_def - > appendChild ( pBody ) ; // logout Element als unterElement vom Body anlegen Poco :: AutoPtr < Poco :: XML :: Element > pLogout = pDoc - > createElement ( " ns1 : logOut " ) ; pLogout - > setAttribute ( " xmlns : ns1 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pBody - > appendChild ( pLogout ) ; // ticket_id werden als unterelemente von Logout angelegt Poco :: AutoPtr < Poco :: XML :: Element > ptid = pDoc - > createElement ( " ns1 : ticketId " ) ; ptid - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > ptid_text = pDoc - > createTextNode ( ticket_id ) ; ptid - > appendChild ( ptid_text ) ; pLogout - > appendChild ( ptid ) ; return pDoc ; } /* !!! get master Data dokument !!! */ Poco :: AutoPtr < Poco :: XML :: Document > getmasterdata_bmg ( Poco :: XML :: XMLString ticket_id ) { // BMG Login XML bauen . // neues Document Anlegen Poco :: AutoPtr < Poco :: XML :: Document > pDoc = new Poco :: XML :: Document ;
Alexander Bonin
70
A. Quellcodelistings
Poco :: AutoPtr < Poco :: XML :: ProcessingInstruction > pXMLHeader = pDoc - > createProcessingInstruction ( " xml " , " version = 1.0 encoding = utf -8 " ) ; pDoc - > appendChild ( pXMLHeader ) ; // documentenEnvelope anlegen - haengt direkt an pDoc also direktes unterelement des Dokuments Poco :: AutoPtr < Poco :: XML :: Element > pUri_def = pDoc - > createElement ( " SOAP - ENV : Envelope " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENV " ," http :// schemas . xmlsoap . org / soap / envelope / " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENC " ," http :// schemas . xmlsoap . org / soap / encoding / " ) ; pUri_def - > setAttribute ( " xmlns : axis2 " ," http :// webservice / bmg / blitz / net / " ) ; pUri_def - > setAttribute ( " xmlns : ns0 " ," http :// data . bmg . blitz . net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : ns1 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : ns2 " ," http :// entity . bmg . blitz . net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : wsaw " ," http :// www . w3 . org /2006/05/ addressing / wsdl " ) ; pUri_def - > setAttribute ( " xmlns : wsdl " ," http :// schemas . xmlsoap . org / wsdl / " ) ; pUri_def - > setAttribute ( " xmlns : xs " ," http :// www . w3 . org /2001/ XMLSchema " ) ; pUri_def - > setAttribute ( " xmlns : xsi " ," http :// www . w3 . org /2001/ XMLSchema - instance " ) ; pDoc - > appendChild ( pUri_def ) ; Poco :: AutoPtr < Poco :: XML :: Element > pBody = pDoc - > createElement ( " SOAP - ENV : Body " ) ; pUri_def - > appendChild ( pBody ) ; // getMasterData Element als unterElement vom Body anlegen Poco :: AutoPtr < Poco :: XML :: Element > pfunction = pDoc - > createElement ( " ns1 : getMasterData " ) ; pfunction - > setAttribute ( " xmlns : ns1 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pBody - > appendChild ( pfunction ) ; // ticket_id wird bergeben
Alexander Bonin
71
A. Quellcodelistings
Poco :: AutoPtr < Poco :: XML :: Element > ptid = pDoc - > createElement ( " ns1 : ticketId " ) ; ptid - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > ptid_text = pDoc - > createTextNode ( ticket_id ) ; ptid - > appendChild ( ptid_text ) ; pfunction - > appendChild ( ptid ) ; return pDoc ; } /* !!! get BMG Numbers Dokument !!! */ Poco :: AutoPtr < Poco :: XML :: Document > getbmgnumbers_bmg ( Poco :: XML :: XMLString ticket_id ) { // BMG Login XML bauen . // neues Document Anlegen Poco :: AutoPtr < Poco :: XML :: Document > pDoc = new Poco :: XML :: Document ; Poco :: AutoPtr < Poco :: XML :: ProcessingInstruction > pXMLHeader = pDoc - > createProcessingInstruction ( " xml " , " version = 1.0 encoding = utf -8 " ) ; pDoc - > appendChild ( pXMLHeader ) ; // documentenEnvelope anlegen - haengt direkt an pDoc also direktes unterelement des Dokuments Poco :: AutoPtr < Poco :: XML :: Element > pUri_def = pDoc - > createElement ( " SOAP - ENV : Envelope " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENV " ," http :// schemas . xmlsoap . org / soap / envelope / " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENC " ," http :// schemas . xmlsoap . org / soap / encoding / " ) ; pUri_def - > setAttribute ( " xmlns : axis2 " ," http :// webservice / bmg / blitz / net / " ) ; pUri_def - > setAttribute ( " xmlns : ns0 " ," http :// data . bmg . blitz . net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : ns1 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : ns2 " ," http :// entity . bmg . blitz . net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : wsaw " ," http :// www . w3 . org /2006/05/ addressing / wsdl " ) ; pUri_def - > setAttribute ( " xmlns : wsdl " ," http :// schemas . xmlsoap . org / wsdl / " ) ;
Alexander Bonin
72
A. Quellcodelistings
pUri_def - > setAttribute ( " xmlns : xs " ," http :// www . w3 . org /2001/ XMLSchema " ) ; pUri_def - > setAttribute ( " xmlns : xsi " ," http :// www . w3 . org /2001/ XMLSchema - instance " ) ; pDoc - > appendChild ( pUri_def ) ; Poco :: AutoPtr < Poco :: XML :: Element > pBody = pDoc - > createElement ( " SOAP - ENV : Body " ) ; pUri_def - > appendChild ( pBody ) ; // getMasterData Element als unterElement vom Body anlegen Poco :: AutoPtr < Poco :: XML :: Element > pfunction = pDoc - > createElement ( " ns1 : getBmgNumbers " ) ; pfunction - > setAttribute ( " xmlns : ns1 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pBody - > appendChild ( pfunction ) ; // ticket_id wird bergeben Poco :: AutoPtr < Poco :: XML :: Element > ptid = pDoc - > createElement ( " ns1 : ticketId " ) ; ptid - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > ptid_text = pDoc - > createTextNode ( ticket_id ) ; ptid - > appendChild ( ptid_text ) ; pfunction - > appendChild ( ptid ) ; // quantity wird bergeben Poco :: AutoPtr < Poco :: XML :: Element > pquan = pDoc - > createElement ( " ns1 : quantity " ) ; pquan - > setAttribute ( " xsi : type " ," xs : int " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pquan_text = pDoc - > createTextNode ( " 1 " ) ; pquan - > appendChild ( pquan_text ) ; pfunction - > appendChild ( pquan ) ; return pDoc ; }
/* !!! send Incommings Dokument !!! */ Poco :: AutoPtr < Poco :: XML :: Document > sendincommings_bmg ( Poco :: XML :: XMLString ticket_id , struct charge_st charge , struct info_st info ) {
Alexander Bonin
73
A. Quellcodelistings
// neues Document Anlegen Poco :: AutoPtr < Poco :: XML :: Document > pDoc = new Poco :: XML :: Document ; Poco :: AutoPtr < Poco :: XML :: ProcessingInstruction > pXMLHeader = pDoc - > createProcessingInstruction ( " xml " , " version = 1.0 encoding = utf -8 " ) ; pDoc - > appendChild ( pXMLHeader ) ; // documentenEnvelope anlegen - haengt direkt an pDoc also direktes unterelement des Dokuments Poco :: AutoPtr < Poco :: XML :: Element > pUri_def = pDoc - > createElement ( " SOAP - ENV : Envelope " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENV " ," http :// schemas . xmlsoap . org / soap / envelope / " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENC " ," http :// schemas . xmlsoap . org / soap / encoding / " ) ; pUri_def - > setAttribute ( " xmlns : axis2 " ," http :// webservice / bmg / blitz / net / " ) ; pUri_def - > setAttribute ( " xmlns : ns0 " ," http :// data . bmg . blitz . net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : ns1 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : ns2 " ," http :// entity . bmg . blitz . net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : wsaw " ," http :// www . w3 . org /2006/05/ addressing / wsdl " ) ; pUri_def - > setAttribute ( " xmlns : wsdl " ," http :// schemas . xmlsoap . org / wsdl / " ) ; pUri_def - > setAttribute ( " xmlns : xs " ," http :// www . w3 . org /2001/ XMLSchema " ) ; pUri_def - > setAttribute ( " xmlns : xsi " ," http :// www . w3 . org /2001/ XMLSchema - instance " ) ; pDoc - > appendChild ( pUri_def ) ; Poco :: AutoPtr < Poco :: XML :: Element > pBody = pDoc - > createElement ( " SOAP - ENV : Body " ) ; pUri_def - > appendChild ( pBody ) ;
// sendIncomings Element als unterElement vom Body anlegen Poco :: AutoPtr < Poco :: XML :: Element > pfunction = pDoc - > createElement ( " ns1 : sendIncomings " ) ; pfunction - > setAttribute ( " xmlns : ns1 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pBody - > appendChild ( pfunction ) ;
Alexander Bonin
74
A. Quellcodelistings
// ticket_id wird bergeben Poco :: AutoPtr < Poco :: XML :: Element > ptid = pDoc - > createElement ( " ns1 : ticketId " ) ; ptid - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > ptid_text = pDoc - > createTextNode ( ticket_id ) ; ptid - > appendChild ( ptid_text ) ; pfunction - > appendChild ( ptid ) ; // incomings container wird bergeben Poco :: AutoPtr < Poco :: XML :: Element > pinco = pDoc - > createElement ( " ns1 : incomings " ) ; pfunction - > appendChild ( pinco ) ; // charge feld anlegen Poco :: AutoPtr < Poco :: XML :: Element > pcharge = pDoc - > createElement ( " ns1 : charge " ) ; pinco - > appendChild ( pcharge ) ; // charge -> article Poco :: AutoPtr < Poco :: XML :: Element > pcharge1 = pDoc - > createElement ( " ns1 : article " ) ; pcharge1 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pcharge1_text = pDoc - > createTextNode ( charge . article ) ; pcharge1 - > appendChild ( pcharge1_text ) ; pcharge - > appendChild ( pcharge1 ) ; // charge -> bmgnumber Poco :: AutoPtr < Poco :: XML :: Element > pcharge2 = pDoc - > createElement ( " ns1 : bmgnumber " ) ; pcharge2 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pcharge2_text = pDoc - > createTextNode ( charge . bmgnumber ) ; pcharge2 - > appendChild ( pcharge2_text ) ; pcharge - > appendChild ( pcharge2 ) ; // charge -> bmgrootid Poco :: AutoPtr < Poco :: XML :: Element > pcharge3 = pDoc - > createElement ( " ns1 : bmgrootid " ) ; pcharge3 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pcharge3_text = pDoc - > createTextNode ( charge . bmgrootid ) ; pcharge3 - > appendChild ( pcharge3_text ) ; pcharge - > appendChild ( pcharge3 ) ; // charge -> labelstandartsLabelid Poco :: AutoPtr < Poco :: XML :: Element > pcharge4 = pDoc - > createElement ( " ns1 : labelstandardsLabelid " ) ;
Alexander Bonin
75
A. Quellcodelistings
pcharge4 - > setAttribute ( " xsi : type " ," xs : short " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pcharge4_text = pDoc - > createTextNode ( charge . lablestandard ) ; pcharge4 - > appendChild ( pcharge4_text ) ; pcharge - > appendChild ( pcharge4 ) ; // charge -> printcode Poco :: AutoPtr < Poco :: XML :: Element > pcharge5 = pDoc - > createElement ( " ns1 : printcode " ) ; pcharge5 - > setAttribute ( " xsi : type " ," xs : string " ) ; if ( charge . printcode != " " ) { Poco :: AutoPtr < Poco :: XML :: Text > pcharge5_text = pDoc - > createTextNode ( charge . printcode ) ; pcharge5 - > appendChild ( pcharge5_text ) ; } pcharge - > appendChild ( pcharge5 ) ; // charge -> seller Poco :: AutoPtr < Poco :: XML :: Element > pcharge6 = pDoc - > createElement ( " ns1 : seller " ) ; pcharge6 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pcharge6_text = pDoc - > createTextNode ( charge . seller ) ; pcharge6 - > appendChild ( pcharge6_text ) ; pcharge - > appendChild ( pcharge6 ) ; // charge -> spezies Poco :: AutoPtr < Poco :: XML :: Element > pcharge7 = pDoc - > createElement ( " ns1 : spezies " ) ; pcharge7 - > setAttribute ( " xsi : type " ," xs : string " ) ; if ( charge . spezies != " " ) { Poco :: AutoPtr < Poco :: XML :: Text > pcharge7_text = pDoc - > createTextNode ( charge . spezies ) ; pcharge7 - > appendChild ( pcharge7_text ) ; } pcharge - > appendChild ( pcharge7 ) ;
// charge -> type Poco :: AutoPtr < Poco :: XML :: Element > pcharge8 = pDoc - > createElement ( " ns1 : type " ) ; pcharge8 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pcharge8_text = pDoc - > createTextNode ( charge . type ) ; pcharge8 - > appendChild ( pcharge8_text ) ; pcharge - > appendChild ( pcharge8 ) ; // info feld anlegen
Alexander Bonin
76
A. Quellcodelistings
Poco :: AutoPtr < Poco :: XML :: Element > pinfo = pDoc - > createElement ( " ns1 : info " ) ; pinco - > appendChild ( pinfo ) ; // info -> buyer Poco :: AutoPtr < Poco :: XML :: Element > pinfo1 = pDoc - > createElement ( " ns1 : buyer " ) ; pinfo1 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pinfo1_text = pDoc - > createTextNode ( info . buyer ) ; pinfo1 - > appendChild ( pinfo1_text ) ; pinfo - > appendChild ( pinfo1 ) ; // info -> chargeId Poco :: AutoPtr < Poco :: XML :: Element > pinfo2 = pDoc - > createElement ( " ns1 : chargeId " ) ; pinfo2 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pinfo2_text = pDoc - > createTextNode ( info . chargeid ) ; pinfo2 - > appendChild ( pinfo2_text ) ; pinfo - > appendChild ( pinfo2 ) ; // info -> quantityUnitid Poco :: AutoPtr < Poco :: XML :: Element > pinfo3 = pDoc - > createElement ( " ns1 : quantityUnitid " ) ; pinfo3 - > setAttribute ( " xsi : type " ," xs : short " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pinfo3_text = pDoc - > createTextNode ( info . quantityUnitID ) ; pinfo3 - > appendChild ( pinfo3_text ) ; pinfo - > appendChild ( pinfo3 ) ; // info -> quantityValue Poco :: AutoPtr < Poco :: XML :: Element > pinfo4 = pDoc - > createElement ( " ns1 : quantityValue " ) ; pinfo4 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pinfo4_text = pDoc - > createTextNode ( info . quantityValue ) ; pinfo4 - > appendChild ( pinfo4_text ) ; pinfo - > appendChild ( pinfo4 ) ; return pDoc ; } Poco :: AutoPtr < Poco :: XML :: Document > sendCancellations_bmg ( Poco :: XML :: XMLString ticket_id , struct charge_st charge ){ // neues Document Anlegen Poco :: AutoPtr < Poco :: XML :: Document > pDoc = new Poco :: XML :: Document ;
Alexander Bonin
77
A. Quellcodelistings
Poco :: AutoPtr < Poco :: XML :: ProcessingInstruction > pXMLHeader = pDoc - > createProcessingInstruction ( " xml " , " version = 1.0 encoding = utf -8 " ) ; pDoc - > appendChild ( pXMLHeader ) ; // documentenEnvelope anlegen - haengt direkt an pDoc also direktes unterelement des Dokuments Poco :: AutoPtr < Poco :: XML :: Element > pUri_def = pDoc - > createElement ( " SOAP - ENV : Envelope " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENC " ," http :// schemas . xmlsoap . org / soap / encoding / " ) ; pUri_def - > setAttribute ( " xmlns : SOAP - ENV " ," http :// schemas . xmlsoap . org / soap / envelope / " ) ; pUri_def - > setAttribute ( " xmlns : axis2 " ," http :// webservice / bmg / blitz / net / " ) ; pUri_def - > setAttribute ( " xmlns : ns0 " ," http :// data . bmg . blitz . net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : ns1 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : ns2 " ," http :// entity . bmg . blitz . net / xsd " ) ; pUri_def - > setAttribute ( " xmlns : wsaw " ," http :// www . w3 . org /2006/05/ addressing / wsdl " ) ; pUri_def - > setAttribute ( " xmlns : wsdl " ," http :// schemas . xmlsoap . org / wsdl / " ) ; pUri_def - > setAttribute ( " xmlns : xs " ," http :// www . w3 . org /2001/ XMLSchema " ) ; pUri_def - > setAttribute ( " xmlns : xsi " ," http :// www . w3 . org /2001/ XMLSchema - instance " ) ; pDoc - > appendChild ( pUri_def ) ; Poco :: AutoPtr < Poco :: XML :: Element > pBody = pDoc - > createElement ( " SOAP - ENV : Body " ) ; pUri_def - > appendChild ( pBody ) ;
// sendCancellations Element als unterElement vom Body anlegen Poco :: AutoPtr < Poco :: XML :: Element > pfunction = pDoc - > createElement ( " ns1 : sendCancellations " ) ; pfunction - > setAttribute ( " xmlns : ns1 " ," http :// webservice / bmg / blitz / net / xsd " ) ; pBody - > appendChild ( pfunction ) ; // ticket_id wird bergeben
Alexander Bonin
78
A. Quellcodelistings
Poco :: AutoPtr < Poco :: XML :: Element > ptid = pDoc - > createElement ( " ns1 : ticketId " ) ; ptid - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > ptid_text = pDoc - > createTextNode ( ticket_id ) ; ptid - > appendChild ( ptid_text ) ; pfunction - > appendChild ( ptid ) ; // incomings container wird bergeben Poco :: AutoPtr < Poco :: XML :: Element > pinco = pDoc - > createElement ( " ns1 : cancellations " ) ; pfunction - > appendChild ( pinco ) ; // charge feld anlegen Poco :: AutoPtr < Poco :: XML :: Element > pcharge = pDoc - > createElement ( " ns0 : charge " ) ; pinco - > appendChild ( pcharge ) ; // charge -> article Poco :: AutoPtr < Poco :: XML :: Element > pcharge1 = pDoc - > createElement ( " ns2 : article " ) ; pcharge1 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pcharge1_text = pDoc - > createTextNode ( charge . article ) ; pcharge1 - > appendChild ( pcharge1_text ) ; pcharge - > appendChild ( pcharge1 ) ; // charge -> bmgnumber Poco :: AutoPtr < Poco :: XML :: Element > pcharge2 = pDoc - > createElement ( " ns2 : bmgnumber " ) ; pcharge2 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pcharge2_text = pDoc - > createTextNode ( charge . bmgnumber ) ; pcharge2 - > appendChild ( pcharge2_text ) ; pcharge - > appendChild ( pcharge2 ) ; // charge -> bmgrootid Poco :: AutoPtr < Poco :: XML :: Element > pcharge3 = pDoc - > createElement ( " ns2 : bmgrootid " ) ; pcharge3 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pcharge3_text = pDoc - > createTextNode ( charge . bmgrootid ) ; pcharge3 - > appendChild ( pcharge3_text ) ; pcharge - > appendChild ( pcharge3 ) ; // charge -> labelstandartsLabelid Poco :: AutoPtr < Poco :: XML :: Element > pcharge4 = pDoc - > createElement ( " ns2 : labelstandardsLabelid " ) ; pcharge4 - > setAttribute ( " xsi : type " ," xs : short " ) ;
Alexander Bonin
79
A. Quellcodelistings
Poco :: AutoPtr < Poco :: XML :: Text > pcharge4_text = pDoc - > createTextNode ( charge . lablestandard ) ; pcharge4 - > appendChild ( pcharge4_text ) ; pcharge - > appendChild ( pcharge4 ) ; // charge -> printcode Poco :: AutoPtr < Poco :: XML :: Element > pcharge5 = pDoc - > createElement ( " ns2 : printcode " ) ; pcharge5 - > setAttribute ( " xsi : type " ," xs : string " ) ; if ( charge . printcode != " " ) { Poco :: AutoPtr < Poco :: XML :: Text > pcharge5_text = pDoc - > createTextNode ( charge . printcode ) ; pcharge5 - > appendChild ( pcharge5_text ) ; } pcharge - > appendChild ( pcharge5 ) ; // charge -> seller Poco :: AutoPtr < Poco :: XML :: Element > pcharge6 = pDoc - > createElement ( " ns2 : seller " ) ; pcharge6 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pcharge6_text = pDoc - > createTextNode ( charge . seller ) ; pcharge6 - > appendChild ( pcharge6_text ) ; pcharge - > appendChild ( pcharge6 ) ; // charge -> spezies Poco :: AutoPtr < Poco :: XML :: Element > pcharge7 = pDoc - > createElement ( " ns2 : spezies " ) ; pcharge7 - > setAttribute ( " xsi : type " ," xs : string " ) ; if ( charge . spezies != " " ) { Poco :: AutoPtr < Poco :: XML :: Text > pcharge7_text = pDoc - > createTextNode ( charge . spezies ) ; pcharge7 - > appendChild ( pcharge7_text ) ; } pcharge - > appendChild ( pcharge7 ) ; // charge -> type Poco :: AutoPtr < Poco :: XML :: Element > pcharge8 = pDoc - > createElement ( " ns2 : type " ) ; pcharge8 - > setAttribute ( " xsi : type " ," xs : string " ) ; Poco :: AutoPtr < Poco :: XML :: Text > pcharge8_text = pDoc - > createTextNode ( charge . type ) ; pcharge8 - > appendChild ( pcharge8_text ) ; pcharge - > appendChild ( pcharge8 ) ; return pDoc ; }
Alexander Bonin
80
A. Quellcodelistings
A.8 xml_results.h
Listing # include # include # include A.8: Funktionen zum Auswerten der SOAP Response Headerdatei < ADSbase .h > " functions . h " " Poco / AutoPtr . h "
// Ausnahmebehandlung # include " Poco / Exception . h " # include # include # include # include # include # include # include # include " Poco / DOM / DOMWriter . h " " Poco / XML / XMLWriter . h " " Poco / DOM / DOMParser . h " " Poco / XML / XMLStream . h " " Poco / DOM / ProcessingInstruction . h " " Poco / DOM / Document . h " " Poco / DOM / Element . h " " Poco / DOM / Text . h "
// includes zum navigieren durch XML Doumente # include " Poco / DOM / Node . h " # include " Poco / DOM / NodeIterator . h " # include " Poco / DOM / NodeFilter . h " // inputsource 2 xml parser include # include " Poco / SAX / InputSource . h " // gibt die Ticketid der Antwort auf Login zurck std :: string login_response ( Poco :: AutoPtr < Poco :: XML :: Document > req ) ; // gibt die Antwort auf logout zurck std :: string logout_response ( Poco :: AutoPtr < Poco :: XML :: Document > req ) ; // gibt die Antwort auf getMasterData zurck bool getmasterdata_response_us ( Poco :: AutoPtr < Poco :: XML :: Document > req , CADSDataList * pDataList ) ; bool getmasterdata_response_buyer ( Poco :: AutoPtr < Poco :: XML :: Document > req , CADSDataList * pDataList ) ; // gibt die Antwort auf sendIncommings zurck std :: string sendincommings_response ( Poco :: AutoPtr < Poco :: XML :: Document > req ) ;
Alexander Bonin
81
A. Quellcodelistings
// gibt die Antwort auf sendCancellations zurck std :: string sendcancellations_response ( Poco :: AutoPtr < Poco :: XML :: Document > req ) ; // gibt die Antwort auf getbmgnumbers zurck std :: string getbmgnumbers_response ( Poco :: AutoPtr < Poco :: XML :: Document > req ) ;
A.9 xml_results.cpp
Listing A.9: Funktionen zum Auswerten der SOAP Response # include " stdafx . h " # include " xml_results . h " # include " structs . h " # include " functions . h "
std :: string login_response ( Poco :: AutoPtr < Poco :: XML :: Document > req ) { std :: string return_string = " " ; Poco :: XML :: NodeIterator it ( req , Poco :: XML :: NodeFilter :: SHOW_ELEMENT ) ; Poco :: XML :: Node * pNode = it . nextNode () ; while ( pNode ) { if ( pNode - > nodeName () == " ns : return " ) { return_string = pNode - > innerText () ; } pNode = it . nextNode () ; } return return_string ; } std :: string logout_response ( Poco :: AutoPtr < Poco :: XML :: Document > req ) { std :: string return_string = " " ; Poco :: XML :: NodeIterator it ( req , Poco :: XML :: NodeFilter :: SHOW_ELEMENT ) ; Poco :: XML :: Node * pNode = it . nextNode () ; while ( pNode ) { if ( pNode - > nodeName () == " ns : return " ) {
Alexander Bonin
82
A. Quellcodelistings
bool getmasterdata_response_us ( Poco :: AutoPtr < Poco :: XML :: Document > req , CADSDataList * pDataList ) {
Poco :: XML :: NodeIterator it ( req , Poco :: XML :: NodeFilter :: SHOW_ELEMENT ) ; Poco :: XML :: Node * pNode = it . nextNode () ; int counter = pDataList - > GetDataRecordCount () ;
std :: vector < us_liste > us_vec ; us_liste temp_us ; try { while ( pNode ) { // liest die standard Tabelle aus if (( pNode - > nodeName () == " ns : name " || pNode - > nodeName () == " ns : labelid " ) & pNode - > parentNode () -> nodeName () == " ns : standard " ) { if ( pNode - > nodeName () == " ns : labelid " ) { temp_us . id = pNode - > innerText () . c_str () ; // pDataValue = pDataRecord - > GetDataValue (" BMGID ") ; } if ( pNode - > nodeName () == " ns : name " ) { temp_us . name = pNode - > innerText () . c_str () ; // pDataValue = pDataRecord - > GetDataValue (" BMGBEZ ") ; temp_us . tid = " s " ; // pDataValue = pDataRecord - > GetDataValue (" BMTID ") ;
Alexander Bonin
83
A. Quellcodelistings
} // liest die unit Tabelle aus if (( pNode - > nodeName () == " ns : name " || pNode - > nodeName () == " ns : unitid " ) & pNode - > parentNode () -> nodeName () == " ns : unit " ) { if ( pNode - > nodeName () == " ns : name " ) { temp_us . name = pNode - > innerText () . c_str () ; } if ( pNode - > nodeName () == " ns : unitid " ) { temp_us . id = pNode - > innerText () . c_str () ; temp_us . tid = " u " ; us_vec . push_back ( temp_us ) ; } } // liest die Artikel Tabelle aus if ( pNode - > nodeName () == " ns : artikel " & pNode - > parentNode () -> nodeName () == " ns : product " ) { temp_us . name = pNode - > innerText () . c_str () ; } if ( pNode - > nodeName () == " ns : bmgrootid " & pNode - > parentNode () -> nodeName () == " ns : product " ) { temp_us . id = pNode - > innerText () . c_str () ; temp_us . tid = " p " ; us_vec . push_back ( temp_us ) ; } pNode = it . nextNode () ; } // vector zu datavalues schreiben CADSDataRecord * pDataRecord ; int writecount =0; for ( std :: vector < us_liste >:: size_type i = 0; i < us_vec . size () ; i ++ ) { if (! existDataValue ( pDataList , " BMGID " , us_vec [ i ]. id ) ) {
Alexander Bonin
84
A. Quellcodelistings
Fachhochschule Schmalkalden SS 2011 pDataList - > AddDataRecord ( counter + writecount ) ; pDataRecord = pDataList - > GetDataRecord ( counter + writecount ) ; pDataRecord - > GetDataValue ( " BMGID " ) -> SetStringValue ( us_vec [ i ]. id ) ; pDataRecord - > GetDataValue ( " BMGBEZ " ) -> SetStringValue ( us_vec [ i ]. name ) ; pDataRecord - > GetDataValue ( " BMGTID " ) -> SetStringValue ( us_vec [ i ]. tid ) ; writecount ++;
} } return true ; } catch ( Poco :: Exception error ) { return false ; } } bool getmasterdata_response_buyer ( Poco :: AutoPtr < Poco :: XML :: Document > req , CADSDataList * pDataList ) { int counter = pDataList - > GetDataRecordCount () ; Poco :: XML :: NodeIterator it ( req , Poco :: XML :: NodeFilter :: SHOW_ELEMENT ) ; Poco :: XML :: Node * pNode = it . nextNode () ; // starte zaehlschleife fr eintraege try { std :: vector < buyer > buyer_vec ; buyer temp_buyer ; while ( pNode ) { // liest die buyer tabelle aus if ( pNode - > nodeName () == " ns : city " & pNode - > parentNode () -> nodeName () == " ns : buyer " ) { // std :: cout << " Stadt : " << pNode - > innerText () << std :: endl ; temp_buyer . city = pNode - > innerText () ; // pDataValue = pDataRecord - > GetDataValue (" ORT ") ; }
Alexander Bonin
85
A. Quellcodelistings
if ( pNode - > nodeName () == " ns : countrycode " & pNode - > parentNode () -> nodeName () == " ns : buyer " ) { // std :: cout << " Staedecode : " << pNode - > innerText () << std :: endl ; temp_buyer . countrycode = pNode - > innerText () ; } if ( pNode - > nodeName () == " ns : holdingnumber " & pNode - > parentNode () -> nodeName () == " ns : buyer " ) { temp_buyer . holdingnumber = pNode - > innerText () ; } if ( pNode - > nodeName () == " ns : name " & pNode - > parentNode () -> nodeName () == " ns : buyer " ) { temp_buyer . name = pNode - > innerText () ; } if ( pNode - > nodeName () == " ns : name2 " & pNode - > parentNode () -> nodeName () == " ns : buyer " ) { temp_buyer . name2 = pNode - > innerText () ; } if ( pNode - > nodeName () == " ns : postalcode " & pNode - > parentNode () -> nodeName () == " ns : buyer " ) { temp_buyer . postalcode = pNode - > innerText () ; } if ( pNode - > nodeName () == " ns : street " & pNode - > parentNode () -> nodeName () == " ns : buyer " ) { temp_buyer . street = pNode - > innerText () ; } if ( pNode - > nodeName () == " ns : typeid " & pNode - > parentNode () -> nodeName () == " ns : buyer " ) { temp_buyer . type_id = pNode - > innerText () ; buyer_vec . push_back ( temp_buyer ) ; } pNode = it . nextNode () ; } // vector zu datavalues schreiben CADSDataRecord * pDataRecord ; // CADSDataValue * pDataValue ; CString bmg = " bmg_ " ; int writecount =0;
Alexander Bonin
86
A. Quellcodelistings
for ( std :: vector < buyer >:: size_type i = 0; i < buyer_vec . size () ; i ++ ) { if (! existDataValue ( pDataList , " BMGNR " , buyer_vec [ i ]. holdingnumber . c_str () ) ) { pDataList - > AddDataRecord ( counter + writecount ) ; pDataRecord = pDataList - > GetDataRecord ( counter + writecount ) ; pDataRecord - > GetDataValue ( " BMGNR " ) -> SetStringValue ( buyer_vec [ i ]. holdingnumber . c_str () ) ; pDataRecord - > GetDataValue ( " PNR " ) -> SetStringValue ( bmg + buyer_vec [ i ]. holdingnumber . c_str () ) ; pDataRecord - > GetDataValue ( " BMGNR " ) -> SetStringValue ( buyer_vec [ i ]. holdingnumber . c_str () ) ; pDataRecord - > GetDataValue ( " ORT " ) -> SetStringValue ( buyer_vec [ i ]. city . c_str () ) ; pDataRecord - > GetDataValue ( " NAME " ) -> SetStringValue ( buyer_vec [ i ]. name . c_str () ) ; pDataRecord - > GetDataValue ( " PLZ " ) -> SetStringValue ( buyer_vec [ i ]. postalcode . c_str () ) ; pDataRecord - > GetDataValue ( " STR_NR " ) -> SetStringValue ( buyer_vec [ i ]. street . c_str () ) ; pDataRecord - > GetDataValue ( " STELLUNG " ) -> SetStringValue ( " P " ) ; writecount ++; } } return true ; } catch ( Poco :: Exception error ) { return false ; } }
Alexander Bonin
87
A. Quellcodelistings
std :: string getbmgnumbers_response ( Poco :: AutoPtr < Poco :: XML :: Document > req ) { std :: string return_string = " " ; Poco :: XML :: NodeIterator it ( req , Poco :: XML :: NodeFilter :: SHOW_ELEMENT ) ; Poco :: XML :: Node * pNode = it . nextNode () ; int counter =0; while ( pNode ) { if ( pNode - > nodeName () == " return " ) { return_string = pNode - > innerText () ; } pNode = it . nextNode () ; } return return_string ; } std :: string sendincommings_response ( Poco :: AutoPtr < Poco :: XML :: Document > req ) { std :: string return_string = " " ; Poco :: XML :: NodeIterator it ( req , Poco :: XML :: NodeFilter :: SHOW_ELEMENT ) ; Poco :: XML :: Node * pNode = it . nextNode () ; int counter =0; while ( pNode ) { if ( pNode - > nodeName () == " return " ) { return_string = pNode - > innerText () ; } pNode = it . nextNode () ; } return return_string ; } std :: string sendcancellations_response ( Poco :: AutoPtr < Poco :: XML :: Document > req ) { std :: string return_string = " " ; Poco :: XML :: NodeIterator it ( req , Poco :: XML :: NodeFilter :: SHOW_ELEMENT ) ; Poco :: XML :: Node * pNode = it . nextNode () ;
Alexander Bonin
88
while ( pNode ) { if ( pNode - > nodeName () == " return " ) { return_string = pNode - > innerText () ; } pNode = it . nextNode () ; } return return_string ; }
Alexander Bonin
89
B Anhang
B.1 Telefonprotokoll Bio mit Gesicht
Telefonat Frank Wrner Bio mit Gesicht. Wie ist die Anmeldung bei Bio mit Gesicht gestaltet? Der Teilnehmer nimmt Kontakt mit Bio mit Gesicht auf und bersendet einen Antrag. Dieser beinhaltet die Artikel sowie die Marktpartner welche auf Bio mit Gesicht Seite eingestellt werden. Wie ist die Form der Artikel und Marktpartnerlisten. Es gibt keine allgemeine Form meist werden diese in Form von Exceltabellen eingeliefert, eine Liste als PDF oder Ausdruck wre aber auch in Ordnung. Welche Informationen werden in den Listen bentigt. Die Artikelliste bentigt die folgenden Informationen: Artikelbezeichnung intern Artikelbezeichnung extern Abrechnungseinheit Die Marktpartnerliste bentigt lediglich den Namen und die Anschrift des Marktpartners. Der Markpartner muss nicht zwangslug an Bio mit Gesicht Teilnehmen. Allgemeine Erfahrungen mit der Anbindung eSchlagKartein an Bio mit Gesicht. Bisher gibt es mit der Anbindung keine Erfahrungen es gibt Interesse von verschiedenen Seiten aber keine realisierte Lsung. Kritische Anmerkung gibt es von einigen eSchlagKartei Lsung in der Hinsicht das wohl keine Lagerausbuchung mit Mengen in der SchlagKartei realisiert ist oder diese nicht genutzt wird.
Alexander Bonin
90
Inhalt
1 2 2.1 2.2 2.3 2.4 3 3.1 3.2 3.3 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.4 3.5 3.5.1 3.5.2 3.6 3.7 nderungen Vorbemerkung Grundstzliches zur Schnittstelle Validierung der XML-Dokumente Relationaler Aufbau Encoding Webservice Methoden logIn logOut getMasterData Supplier Buyer Product Unit Standard Quality getBmgNumbers bertragen der Bewegungsdaten Chargenfhrung sendIncomings sendCancellations getVersion 1 2 2 2 2 2 3 4 4 5 5 5 6 6 7 7 7 8 8 8 11 11
1
0.2
nderungen
Datum 24.11.09 Anmerkung getMasterDat Liste Company aufgespalten in Supplier und Buyer
Version
1 von 11
Abbildungsverzeichnis
3.1 3.2 3.3 3.4 3.5 3.6 Aufbau der Daten in Elsa-ko . . . . . BMG Login Flussdiagramm . . . . . . BMG Logout Flussdiagramm . . . . . BMG Synchronisation Flussdiagramm . BMG bertragen Flussdiagramm . . . BMG Lschen Flussdiagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 14 14 15 15 16
Alexander Bonin
92
Tabellenverzeichnis
3.1 3.2 3.3 3.4 3.5 3.6 SOAP Framework bersicht . . . . . . . . Schnittstellenbeschreibung Login . . . . . Schnittstellenbeschreibung Logout . . . . . Schnittstellenbeschreibung Synchronisieren Schnittstellenbeschreibung Senden . . . . . Schnittstellenbeschreibung Lschen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 10 11 11 12 12
Alexander Bonin
93
Listings
1.1 1.2 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12 4.13 4.14 4.15 4.16 4.17 4.18 4.19 4.20 4.21 A.1 A.2 A.3 A.4 A.5 A.6 A.7 A.8 A.9 XML Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XML Beispiel eines SOAP Requests . . . . . . . . . . . . . . . . . . . Initiale Aktionen beim Laden der DLL . . . . . . . . . . . Funktion zum Bekanntmachen der Modulinformationen . . Verentlichen von Modulinformationen . . . . . . . . . . Funktion zum Verbindungstest mit Bio mit Gesicht. . . . Funktion zum Holen der Bio mit Gesicht Masterdaten. . Funktion zum bertragen der Bewegungsdaten. . . . . . . Strukturierte Datentypen der sendbmg Funktion. . . . . . Funktion zum stornieren von Bewegungsdaten. . . . . . . . Funktion zum senden aller markierten Bewegungsdaten. . . Generieren des incommings XML-Dokumentes . . . . . . . Strukturierte Datentypen fr sendIncommings . . . . . . . Auslesen der Buyer Information aus dem Masterdata XML Aufbau des Vectors fr Buyer Informationen . . . . . . . . XML bertragung per HTTP . . . . . . . . . . . . . . . . Umwandlung eines XML Dokumentes in einen String . . . Umwandlung eines Strings in ein XML Dokument . . . . . Prfen auf Netzverfgbarkeit . . . . . . . . . . . . . . . . . Beispiel fr einen Unit Eintrag . . . . . . . . . . . . . . . . Mappen unterschiedlicher Einheitenbezeichner . . . . . . . Aunden eines Wertes in den Gesamtdaten . . . . . . . . Auslesen der ID Werte von Bio mit Gesicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 3 17 17 18 19 20 21 24 26 27 29 31 33 34 35 37 38 39 40 40 41 42 45 46 58 60 64 65 67 81 82
Inhalt der BMGModul Headerdatei . . . . . . . . . . . . . . . . Inhalt der BMGModul.cpp . . . . . . . . . . . . . . . . . . . . . Inhalt der functions Headerdatei . . . . . . . . . . . . . . . . . . Inhalt der functions.cpp . . . . . . . . . . . . . . . . . . . . . . Denition der strukturierten Datentypen . . . . . . . . . . . . . Funktionen zum generieren von XML Dokumenten Headerdatei Funktionen zum generieren von XML Dokumenten . . . . . . . Funktionen zum Auswerten der SOAP Response Headerdatei . . Funktionen zum Auswerten der SOAP Response . . . . . . . . .
Alexander Bonin
94
Eidesstattliche Erklrung
Ich versichere an Eides Statt durch meine eigenhndige Unterschrift, dass ich die vorliegende Arbeit selbststndig und ohne fremde Hilfe angefertigt habe. Alle Stellen, die wrtlich oder dem Sinn nach auf Publikationen oder Vortrgen anderer Autoren beruhen, sind als solche kenntlich gemacht. Ich versichere auerdem, dass ich keine andere als die angegebene Literatur verwendet habe. Diese Versicherung bezieht sich auch auf alle in der Arbeit enthaltenen Zeichnungen, Skizzen, bildlichen Darstellungen und dergleichen. Die Arbeit wurde bisher keiner anderen Prfungsbehrde vorgelegt und auch noch nicht verentlicht.
Alexander Bonin
95