There is an API in S/4HANA Cloud that can be used to retrieve electronic documents. This API (Document Compliance – Electronic Document File) can be used for sending electronic documents to an external system. The file content when the API is called is base64 encoded and a common question is how to decode and use this data.
In this blog, I’ll show you how you can quickly develop an iFlow on SAP BTP Cloud Integration to poll for new documents, decode the files and send to an external system.
First, let’s take a look at the API contents in Postman. The service itself is based on the OData v4 protocol. Notice the encoded file content in the ElectronicDocFileContent.
The requirement in this case is that any new files that have not been sent already should be sent via SFTP to the 3rd party. We’ll use the creation date and creation time to determine which documents should be sent.
The structure of the iFlow is shown in the image below.
- There is a main integration process that queries for the files and then a splitter to process the files one by one before updating 2 local variables to handle the date and time if necessary.
- Decode each file and SFTP to the 3rd party system
- Handle any errors
- Email errors to a power user to take corrective action
The iFlow can be set up to either pull all files based on a static date or run in a “delta mode”. Delta mode uses the date and time of the last execution (which are saved as a local variables) to fetch new documents.
The first Content Modifier sets up the required properties to handle the date and time and control the amount of logging that the iFlow will produce.
The script step then defines the filter to be used in the OData call. If the iFlow is running in delta mode, it will use the variables, otherwise it will use the static dates.
def Message defineFilter(Message message) {
//Body
def body = message.getBody();
def messageLog = messageLogFactory.getMessageLog(message);
def pMap = message.getProperties();
//define Query Filter here
def queryFilter = "";
if(pMap.get("p_useDeltaMode") == "TRUE") {
//define date Filter
queryFilter = "(ElectronicDocFileCreationDate ge " + pMap.get("p_lastRunDate") + " and ElectronicDocFileCreationTime ge " + pMap.get("p_lastRunTime") + ")";
} else {
queryFilter = "(ElectronicDocFileCreationDate ge " + pMap.get("p_manualDate") + " and ElectronicDocFileCreationTime ge " + pMap.get("p_manualTime") + ")";;
}
if(pMap.get("p_debugMode").toUpperCase()=='TRUE' && messageLog != null) {
messageLog.setStringProperty("ResponsePayload", "Printing Payload As Attachment")
messageLog.addAttachmentAsString("Query Filter:", queryFilter, "text/plain");
}
message.setProperty("p_queryFilter", queryFilter);
return message;
}
The output of this script results in a filter as such:
ElectronicDocFileCreationDate ge 2022-08-01 and ElectronicDocFileCreationTime ge 13:28:06
Of course you could add any additional parameters to this query. For example, you may only want to query for certain document types and can add ElectronicDocFileType to the filter.
This property is then used in the OData v4 $filter statement:
The results can then be split using an XPath expression in a Splitter which makes a process call to handle each document.
/ElectronicDocFile/ElectronicDocFile_Type
The sub process then decodes and sends each document and is very straightforward. First, a Content Modifier is used to write the filename and file content to properties. The script step then sets the Message Body to the file content for the decoder.
message.setBody(pMap.get("p_fileContent"));
Then you use a Base64 Decoder which decodes the file and an SFTP step sends the file with the file name property.
This is a sample decoded document that would be sent via SFTP.
Finally, back in the main process a check is done using a Router to see if the iFlow is running in delta mode, and if it is the new date and time are written to local variables for use in the next run. Otherwise, the iFlow was run using manual dates so the variables for “last run” should not be updated.
You should check the results and handle any errors according to your requirements.
That’s all it takes to set up an iFlow that polls for new eDocuments and sends them to an external system. You can be up and running with your own in a very short amount of time.