Calling the OAGIS SalesOrder Web Service
This proof of concept was developed to demonstrate RPG-XML Suiteās ability to process and respond with OAGIS specified documents. In this program, we work exclusively with SalesOrder documents, and work with ProcessSalesOrder and RespondSalesOrder. Due to the verbose nature of the OAGIS specification, this proof of concept has the following limits:
-
Accepts a maximum of 5 SalesOrderLine elements.
-
Implements a very limited subset of the specifications
-
Has hardcoded data and does not use DB2 tables.
Source Code
//?***************************************************************************************
//?@Author: Adam Taylor
//?@Desc: Read incoming ProcessSalesOrder XML via STDIN, create a RespondSalesOrder
//? in an XML file, and return it to the requestor via STDOUT.
//?@Notes: This example only accounts for up to 5 items being present in a
// ProcessSalesOrder, and is a limited subset of both XML documents as compared
// to their full form per OAGIs.
//?***************************************************************************************
H dftactgrp(*no) bnddir('RXSBND')
/copy rxs,RXSCp ?RXS_* procedures & definitions
D gError ds likeds(RXS_Error) inz
D salesOrder ds qualified inz
D sndLogicalId 10a
D sndCmpntId 12a
D sndRefId 5a
D sndConfirmURI 40a Varying
D sndConfirmCd 15a
D sndAuthId 12a
D rcvLogicalId 10a
D rcvId 10a
D crtDateTime d
D BODID 3a Varying
D saleOrderType 1a
D saleHdrDesc 50a Varying
D noteAuthor 4a Varying
D noteDateTime d
D noteStatus 1a
D note 50a Varying
D totAmtCurType 6a
D totAmt 8 2
D salesOrderLine ds qualified inz dim(5)
D lineNumber 5 0
D description 50a Varying
D originCountry 50a Varying
D serialNumber 20a
D gLineCnt s 10i 0 Inz(0)
D counter s 10i 0 Inz(0)
D gReqFile s like(RXS_FilePath)
D gRspFile S like(RXS_FilePath)
D allHandler pr
D pType value like(RXS_Type)
D pXPath value like(RXS_XPath)
D pData value like(RXS_XmlData)
D pDataLen value like(RXS_Length)
D errHandler pr
D pCurLine 10i 0 value
D pCurCol 10i 0 value
D pErrStr 1024a value varying
/free
monitor;
gReqFile = RXS_cmpTransFile('_': '.xml': 'cargill_req');
gRspFile = RXS_cmpTransFile('_': '.xml': 'cargill_rsp');
RXS_readToFile(gReqFile);
exsr parse;
exsr compose;
exsr respond;
on-error;
RXS_stdOutError('error': RXS_catchError(): *on);
endmon;
*inlr = *On;
//?--------------------------------------------------------------------------------------
//?@Author: Adam Taylor
//?@Desc: Prime parsing engine
//?--------------------------------------------------------------------------------------
begsr parse;
monitor;
// Ignore all namespaces.
RXS_ignElemNamSpc();
RXS_allElemContentHandler(%paddr(allHandler));
RXS_allAttrHandler(%paddr(allHandler));
RXS_parse(gReqFile : RXS_STMF : %paddr(errHandler));
on-error;
gError = RXS_catchError();
endmon;
endsr;
//?--------------------------------------------------------------------------------------
//?@Author: Adam Taylor
//?@Desc: Build RespondSalesOrder XML file using Template Engine
//?--------------------------------------------------------------------------------------
begsr compose;
monitor;
// Composing our XML RespondSalesOrder and storing it in a STMF
RXS_initTplEng(RXS_STMF: gRspFile: *omit: *omit: *omit: *off);
RXS_loadTpl('RespondSalesOrder.tpl');
RXS_updVar('LogicalID' : salesOrder.sndLogicalId);
RXS_updVar('ComponentID' : salesOrder.sndCmpntId);
RXS_updVar('ReferenceID' : salesOrder.sndRefId);
RXS_updVar('languageID' : 'en-US');
RXS_updVar('ConfirmationCode' : salesOrder.sndConfirmCd);
RXS_updVar('AuthorizationID' : salesOrder.sndAuthId);
RXS_updVar('BODID' : salesOrder.BODID);
RXS_updVar('CreationDateTime' : %Char(salesOrder.crtDateTime));
RXS_updVar('currencyID' : salesOrder.totAmtCurType);
RXS_updVar('TotalAmount' : %Char(salesOrder.totAmt));
RXS_updVar('SaleHeaderDescription' : salesOrder.saleHdrDesc);
RXS_updVar('author' : salesOrder.noteAuthor);
RXS_updVar('entryDateTime' : %Char(salesOrder.noteDateTime));
RXS_updVar('status' : salesOrder.noteStatus);
RXS_updVar('Note' : salesOrder.note);
RXS_updVar('Code' : 'INI');
RXS_updVar('EffectiveDateTime' : %Char(%Date()));
RXS_updVar('ChangeDateTime' : %Char(%Date() - %Days(3)));
RXS_updVar('FromStateCode' : 'ORD');
RXS_updVar('ReasonCode' : 'CDE');
RXS_updVar('ToStateCode' : 'PRC');
RXS_updVar('actionCode' : 'Always');
RXS_updVar('ResponseExpression' : 'Successful');
RXS_wrtSection('RespondSalesOrder_beg');
// Print out however many order lines we parsed.
for counter = 1 To 5;
if salesOrderLine(counter).lineNumber > 0;
RXS_updVar('LineNumber' :
%Char(salesOrderLine(counter).lineNumber));
RXS_updVar('CountryOfOriginCode' :
salesOrderLine(counter).originCountry);
RXS_updVar('Description' :
salesOrderLine(counter).description);
RXS_updVar('SerialNumber' :
salesOrderLine(counter).serialNumber);
RXS_wrtSection('SalesOrderLine');
endif;
endfor;
// Finalize XML file, flush buffer to XML file
RXS_wrtSection('RespondSalesOrder_end' : *On);
on-error;
gError = RXS_catchError();
endmon;
endsr;
//?--------------------------------------------------------------------------------------
//?@Author: Adam Taylor
//?@Desc: Return RespondSalesOrder via STDOUT
//?--------------------------------------------------------------------------------------
begsr respond;
monitor;
RXS_writeXmlHdr();
RXS_outFromFile(gRspFile);
on-error;
gError = RXS_catchError();
endmon;
endsr;
/end-free
//---------------------------------------------------------------------------------------
// @Author:
// @Created:
// @Desc:
//----------------------------------------------------------------------------------------
P allHandler b
D allHandler pi
D pType value like(RXS_Type)
D pXPath value like(RXS_XPath)
D pData value like(RXS_XmlData)
D pDataLen value like(RXS_Length)
D chgMe s like(RXS_XmlData)
D baseEnv s 70a varying
/free
// For the sake of this example, we're loading the repeating
// SalesOrderLine elements into an array, limited at 5 elements.
// In normal use, you would most likely want to load these into a
// DB2 table.
baseEnv = '/Envelope/Body/ProcessSalesOrder';
select;
when pXPath = baseEnv +'/ApplicationArea/Sender/LogicalID/';
salesOrder.sndLogicalId = pData;
when pXPath = baseEnv +'/ApplicationArea/Sender/ComponentID/';
salesOrder.sndCmpntId = pData;
when pXPath = baseEnv +'/ApplicationArea/Sender/ReferenceID/';
salesOrder.sndRefId = pData;
when pXPath = baseEnv +'/ApplicationArea/Sender/ConfirmationCode'+
'@listURI';
salesOrder.sndConfirmURI = pData;
when pXPath = baseEnv +'/ApplicationArea/Sender/ConfirmationCode/';
salesOrder.sndConfirmCd = pData;
when pXPath = baseEnv +'/ApplicationArea/Sender/AuthorizationID/';
salesOrder.sndAuthId = pData;
when pXPath = baseEnv +'/ApplicationArea/Receiver/LogicalID/';
salesOrder.rcvLogicalId = pData;
when pXPath = baseEnv +'/ApplicationArea/Receiver/ID/';
salesOrder.rcvId = pData;
when pXPath = baseEnv +'/ApplicationArea/CreationDateTime/';
salesOrder.crtDateTime = %DATE(pData : *ISO);
when pXPath = baseEnv +'/ApplicationArea/BODID/';
salesOrder.BODID = pData;
when pXPath = baseEnv +'/DataArea/SalesOrder/SalesOrderHeader'+
'/Description/';
salesOrder.saleHdrDesc = pData;
when pXPath = baseEnv +'/DataArea/SalesOrder/SalesOrderHeader/Note'+
'@author';
salesOrder.noteAuthor = pData;
when pXPath = baseEnv +'/DataArea/SalesOrder/SalesOrderHeader/Note'+
'@entryDateTime';
salesOrder.noteDateTime = %DATE(pData : *ISO);
when pXPath = baseEnv +'/DataArea/SalesOrder/SalesOrderHeader/Note/';
salesOrder.note = pData;
when pXPath = baseEnv +'/DataArea/SalesOrder/SalesOrderHeader'+
'/TotalAmount@currencyID';
salesOrder.totAmtCurType = pData;
when pXPath = baseEnv +'/DataArea/SalesOrder/SalesOrderHeader'+
'/TotalAmount/';
salesOrder.totAmt = %DEC(pData : 8 : 2);
// Process up to 5 incoming line items.
when pXPath = baseEnv +'/DataArea/SalesOrder/SalesOrderLine/LineNumber/';
gLineCnt += 1;
salesOrderLine(gLineCnt).lineNumber = %Dec(pData : 5 : 0);
when pXPath = baseEnv +'/DataArea/SalesOrder/SalesOrderLine/Item'+
'/Description/';
salesOrderLine(gLineCnt).description = pData;
when pXPath = baseEnv +'/DataArea/SalesOrder/SalesOrderLine/Item'+
'/CountryOfOriginCode/';
salesOrderLine(gLineCnt).originCountry = pData;
when pXPath = baseEnv +'/DataArea/SalesOrder/SalesOrderLine/Item'+
'/SerialNumber/';
salesOrderLine(gLineCnt).serialNumber = pData;
endsl;
/end-free
P e
P errHandler B
D errHandler PI
D pCurLine 10i 0 value
D pCurCol 10i 0 value
D pErrStr 1024a value varying
/free
gError.code = 'SALE001';
gError.severity = 100;
gError.pgm = 'SALE001.errHandler';
gError.text =
'Line:' + %char(pCurLine) + ' Col:' + %char(pCurCol) + ' ' + pErrStr;
/end-free
P E
Template File
::RespondSalesOrder_beg
<RespondSalesOrder xmlns="http://www.openapplications.org/oagis/9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.openapplications.org/oagis/9 ../../Developer/BODs/RespondSalesOrder.xsd"
languageCode="en-US"
versionID="9_4"
releaseID="9_4"
systemEnvironmentCode="Production">
<ApplicationArea>
<Sender>
<LogicalID>.:LogicalID:.</LogicalID>
<ComponentID>.:ComponentID:.</ComponentID>
<ReferenceID>.:ReferenceID:.</ReferenceID>
<ConfirmationCode languageID=".:languageID:.">.:ConfirmationCode:.</ConfirmationCode>
<AuthorizationID>.:AuthorizationID:.</AuthorizationID>
</Sender>
<CreationDateTime>.:CreationDateTime:.</CreationDateTime>
<BODID>.:BODID:.</BODID>
</ApplicationArea>
<DataArea>
<Respond>
<OriginalApplicationArea>
<Sender>
<LogicalID>.:LogicalID:.</LogicalID>
<ComponentID>.:ComponentID:.</ComponentID>
<ReferenceID>.:ReferenceID:.</ReferenceID>
<ConfirmationCode languageID=".:languageID:.">.:ConfirmationCode:.</ConfirmationCode>
<AuthorizationID>.:AuthorizationID:.</AuthorizationID>
</Sender>
<CreationDateTime>.:CreationDateTime:.</CreationDateTime>
<BODID>.:BODID:.</BODID>
</OriginalApplicationArea>
<ResponseCriteria>
<ResponseExpression actionCode=".:actionCode:.">.:ResponseExpression:.</ResponseExpression>
<ChangeStatus>
<Code languageID=".:languageID:.">.:Code:.</Code>
<EffectiveDateTime>.:EffectiveDateTime:.</EffectiveDateTime>
<ReasonCode languageID=".:languageID:.">.:ReasonCode:.</ReasonCode>
<StateChange>
<FromStateCode languageID=".:languageID:.">.:FromStateCode:.</FromStateCode>
<ToStateCode languageID=".:languageID:.">.:ToStateCode:.</ToStateCode>
<ChangeDateTime>.:ChangeDateTime:.</ChangeDateTime>
</StateChange>
</ChangeStatus>
</ResponseCriteria>
</Respond>
<SalesOrder>
<SalesOrderHeader>
<Description languageID=".:languageID:.">.:SaleHeaderDescription:.</Description>
<Note languageID=".:languageID:." author=".:author:." entryDateTime=".:entryDateTime:." status=".:status:.">.:Note:.</Note>
<TotalAmount currencyID=".:currencyID:.">.:TotalAmount:.</TotalAmount>
</SalesOrderHeader>
::SalesOrderLine
<SalesOrderLine>
<LineNumber>.:LineNumber:.</LineNumber>
<Item>
<Description languageID=".:languageID:.">.:Description:.</Description>
<CountryOfOriginCode languageID=".:languageID:.">.:CountryOfOriginCode:.</CountryOfOriginCode>
<SerialNumber>.:SerialNumber:.</SerialNumber>
</Item>
</SalesOrderLine>
::RespondSalesOrder_end
</SalesOrder>
</DataArea>
</RespondSalesOrder>
</source>
Sample XML Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.openapplications.org/oagis/9">
<soapenv:Header/>
<soapenv:Body>
<ns:ProcessSalesOrder systemEnvironmentCode="Production" languageCode="en-US">
<ns:ApplicationArea>
<ns:Sender>
<ns:LogicalID>1159963824</ns:LogicalID>
<ns:ComponentID>64720-22-358</ns:ComponentID>
<ns:ReferenceID>16683</ns:ReferenceID>
<ns:ConfirmationCode listURI="http://www.example.org">Always</ns:ConfirmationCode>
<ns:AuthorizationID>489665871337</ns:AuthorizationID>
</ns:Sender>
<ns:Receiver>
<ns:LogicalID>4283699511</ns:LogicalID>
<ns:ID>1594826735</ns:ID>
</ns:Receiver>
<ns:CreationDateTime>2010-07-13</ns:CreationDateTime>
<ns:BODID>485</ns:BODID>
</ns:ApplicationArea>
<ns:DataArea>
<ns:SalesOrder type="N">
<ns:SalesOrderHeader>
<ns:Description languageID="en-US">Example order description would go here.</ns:Description>
<ns:Note languageID="en-US" author="986" entryDateTime="2010-07-13" status="9">Some notes would go here.</ns:Note>
<ns:TotalAmount currencyID="en-US">12300.99</ns:TotalAmount>
</ns:SalesOrderHeader>
<ns:SalesOrderLine>
<ns:LineNumber>100</ns:LineNumber>
<ns:Item>
<ns:Description languageID="en-US">Item description here.</ns:Description>
<ns:CountryOfOriginCode languageID="en-US">Canada</ns:CountryOfOriginCode>
<ns:SerialNumber>153-8894-778-9636-45</ns:SerialNumber>
</ns:Item>
</ns:SalesOrderLine>
<ns:SalesOrderLine>
<ns:LineNumber>200</ns:LineNumber>
<ns:Item>
<ns:Description languageID="en-US">2nd Item description here.</ns:Description>
<ns:CountryOfOriginCode languageID="en-US">Spain</ns:CountryOfOriginCode>
<ns:SerialNumber>956-4421-263-5684-23</ns:SerialNumber>
</ns:Item>
</ns:SalesOrderLine>
<ns:SalesOrderLine>
<ns:LineNumber>300</ns:LineNumber>
<ns:Item>
<ns:Description languageID="en-US">3rd Item description here.</ns:Description>
<ns:CountryOfOriginCode languageID="en-US">Belgium</ns:CountryOfOriginCode>
<ns:SerialNumber>223-8695-748-9644-78</ns:SerialNumber>
</ns:Item>
</ns:SalesOrderLine>
<ns:SalesOrderLine>
<ns:LineNumber>400</ns:LineNumber>
<ns:Item>
<ns:Description languageID="en-US">A Fourth Item description here.</ns:Description>
<ns:CountryOfOriginCode languageID="en-US">Peru</ns:CountryOfOriginCode>
<ns:SerialNumber>845-9595-748-3625-24</ns:SerialNumber>
</ns:Item>
</ns:SalesOrderLine>
</ns:SalesOrder>
</ns:DataArea>
</ns:ProcessSalesOrder>
</soapenv:Body>
</soapenv:Envelope>