SAP best practices for Jitterbit Design Studio
Introduction
There are a number of unique issues and considerations for SAP integration projects, particularly for bidirectional integrations. This page presents information relevant to all SAP integrations, common integration patterns for SAP and their design considerations, and SAP-specific how-tos.
Basic information
This section covers SAP and Jitterbit terminology, updating SAP data, the IDoc structure, and date formats.
Terminology
This section defines SAP-specific terminology as it relates to Jitterbit Design Studio and its SAP Connector.
SAP terminology
- SAP: When we refer to SAP, we mean a version of SAP that is compatible with the Jitterbit Design Studio SAP connector. The essential component that the Design Studio SAP Connector requires is a version of SAP that uses the SAP Java Connector (SAP JCo). This includes ECC version 6 or later, and SAP S/4HANA single-tenant.
- IDoc: An Intermediate Document (IDoc) is a text file with a predefined format similar to an Electronic Data Interchange (EDI) document. There are IDocs for master data objects, such as customers and vendors, as well as for transactional objects such as sales orders. Originally used to exchange data between SAP systems, IDocs can also be used for third-party integration. Be aware that an IDoc uses German abbreviations inside the document.
- BAPI: A Business Application Programming Interface (BAPI) is an API — similar to a SOAP or REST API — and uses a request and response construct to communicate with SAP. One main difference from SOAP or REST is that a BAPI has a single method and is specific to an object. For example, there are 60 BAPIs related solely to SAP's customer object. BAPIs are delivered and maintained by SAP.
- RFC: An RFC (Remote Function Call) is the same as a BAPI except that an RFC may or may not be maintained across SAP upgrades. Some RFCs are standard and supplied by SAP. Custom RFCs can also be built to support integrations and must be maintained by the SAP customer.
Jitterbit terminology
- SAP Connector: The Jitterbit Design Studio SAP Connector uses SAP Java Connector (SAP JCo) to work with SAP objects and is compatible with ECC version 6 or later, and SAP S/4HANA on-premises. The SAP Connector can be used out-of-the-box for SAP-inbound communications from Harmony to SAP using RFCs, BAPIs, or IDocs.
- SAP Event Listener: The Jitterbit SAP Event Listener is an application that installs and runs as a service on a Windows or Linux server. It extends the functionality of the SAP Connector by listening for and receiving SAP-outbound IDocs. Using the transactional RFC (tRFC) protocol, IDocs are sent in a batch without a defined order. Using the queued RFC (qRFC) protocol, the SAP Event Listener responds to SAP after receiving each IDoc, signaling SAP to send the next IDoc in the transaction.
Updating SAP data
As a best practice, when updating data in SAP, using a BAPI or RFC is usually preferable to using an IDoc. The main reason for this is that BAPIs and RFCs return a response that can be used in the integration project:
- A successful update often has record IDs in the response, which can be used to update the source application.
- If an error is returned, it can be incorporated into error handling processes.
In comparison, when an IDoc is sent, the only acknowledgment sent back is a code indicating it was received; there is no indication of success or failure. IDocs are processed in SAP asynchronously. If an IDoc fails, user action is required to reprocess the IDoc.
There are certain scenarios where an IDoc is preferable:
- An IDoc can contain multiple records, while BAPIs and RFCs can usually handle only a single record update. A bulk update scenario may require the use of an IDoc.
- An IDoc can be used to capture changed data, while BAPIs and RFCs cannot handle timestamp-based queries.
- There may be functionality that an IDoc can invoke that is not available using a BAPI or RFC.
IDoc structure
The structure of an IDoc is flat. Though the XML looks as if it is hierarchical, repeating nodes are not actually nested within parent nodes.
In the example structure below, all segments of the parent IDOC
are at the same sublevel. Header information is at the same level as item information:
Date formats
Though SAP can display dates in its GUI in different formats (following country conventions), the data format for the SAP APIs is yyyy-mm-dd
.
Integration patterns
This section presents common integration patterns that can be used for interacting with SAP data.
Master data integration of customers
In SAP, a customer can be one of — or a combination of — partner functions, such as SoldTo, ShipTo, and BillTo. For example:
- A customer could be its own SoldTo, ShipTo, and BillTo.
- A customer could be a SoldTo and a BillTo, with a different customer as the ShipTo.
- A customer could be a SoldTo with many other customers being the ShipTos (a common case where a franchise customer has many locations)
When using the SAP customer object in integration projects, it's essential to have a thorough understanding of the integration requirements for both customers and the partner functions.
With an initial loading of data, in general the SoldTo customers need to be loaded first, since the other customers are dependent on the SoldTo to exist in the target endpoint in order to build the relationship. As the BillTo contains the billing address, frequently the endpoint customer definition needs main and shipping addresses, and the integration has to update the SoldTo customer with the BillTo address in the endpoint.
In the example below, a single IDoc from SAP results in an upsert to both an account and a custom object child account in Salesforce:
Bidirectional integrations
Bidirectional integration projects are those where data flows both to and from each endpoint. For example, you may need SAP customer data to be created in a target endpoint, and any changes to customer data in that target endpoint to be reflected in customers and partner functions in SAP.
As SAP's object creation data validation rules are stricter than other endpoints, this requires custom work on both the endpoint and SAP itself to handle the partner functions. This example shows moving Salesforce accounts to SAP and handles the partner function management:
Capturing changed data for master data objects
In general, IDocs are used for capturing changed data in SAP, as BAPIs and RFCs cannot handle timestamp-based queries.
IDocs can be configured to be generated using change pointers associated with an object, and can be generated to contain either all the data or just changes. Getting all the data is generally a better choice, as there may be relationships in the data that are needed for an upsert. However, mass updates of data can trigger thousands of IDocs at a time, the processing of which can then exceed login or other limits in the target endpoint.
Straight-through processing
Straight-through processing follows this data flow:
- The SAP Event Listener receives an IDoc.
- The SAP Event Listener moves the payload to the Jitterbit operation queue.
- The operation receives the IDoc.
- The IDoc data is loaded into the target endpoint.
Though the processing is straight through, consider these effects of straight-through processing:
- If thousands of IDocs are sent at once, then the SAP Event Listener will instantiate multiple threads and create multiple simultaneous calls. If the call is to update an endpoint with login limits, such as Salesforce, then the volume of calls can exceed login limits.
- If the target endpoint is unreachable, then the IDoc payload is not delivered to the end target and is lost.
Store-and-forward processing
The alternative to straight-through processing is store-and-forward processing, where the IDoc payload is written to a temporary file.
In the example operation chain below:
-
The first operation receives an IDoc from the SAP Event Listener and stores it locally.
-
The second operation is on a fast schedule (such as every minute) and scans the file directory for files to process. When files are found, the files are looped through and each file is passed to the next operation.
-
When the last operation in the chain is run, it deletes the file, and the loop is repeated until exhausted. If there is a technical failure during the process, the file is not deleted and is reprocessed a second time.
Note
By default, temporary files are stored for 24 hours before being deleted. This is configurable for a longer period if necessary.
When running operations in a multi-agent environment, an IDoc may be received by Agent 1 and stored locally, but the schedule may select Agent 2, which will find no files to process. It won't be until Agent 1 is called by the scheduler that its files will be processed.
Keep in mind that all the files in the temp directories will be processed until exhausted. If there is a requirement that IDocs must be guaranteed to be processed in order, then use a shared resource such as an FTP site, a local file system, or a database. However, adding external data stores can create an additional point of failure. Agent clusters are used for failover and load balancing, so using external data stores that are not similarly configured can undermine overall system robustness.
Extracting an ID to fetch additional data
If the IDoc has an ID, a BAPI can be called to fetch additional data:
In the above example, looking at the third operation (3. Mat-Get Details), the IDoc is read to retrieve the material ID, which is then used to call a custom RFC. This screenshot shows the transformation extracting the material ID:
SAP-specific how-tos
This section provides SAP-specific how-tos for these topics:
Handling empty end dates
If an end date is not populated in SAP (as may be the case in an "evergreen" agreement), SAP will send 00000000
in an IDoc, which can be trapped for and handled:
result = FindValue("108", OUTPUT$ORDERS05.IDOC$E1EDP01.E1EDP03#.IDDAT$, OUTPUT$ORDERS05.IDOC$E1EDP01.E1EDP03#.DATUM$);
If(result == "00000000",
RunScript("<TAG>Scripts/WTOL</TAG>", "No End Date, using 12/31/4000");
result="40001231"
);
GetUTCFormattedDateTime(result, "UTC", false);
// The year 4000 is the maximum date used by Salesforce
For further details, see the Jitterbit functions FindValue()
, RunScript()
, and GetUTCFormattedDateTime()
.
Finding customer and partner functions
When looking for the appropriate customer or partner function in SAP, pay particular attention to the German abbreviations.
For example, when creating a sales order, in the SAP GUI you might see a name such as Sold-To Party or the language-specific equivalent partner function SP, but the SAP API instead uses the German abbreviation AG as shown in the first column:
Partner Function | Language | Name | Language-specific Partner Function |
---|---|---|---|
AG | EN | Sold-To Party | SP |
RE | EN | Bill-To Party | BP |
RG | EN | Payer | PY |
WE | EN | Ship-To Party | SH |
Using the SAP function builder to model an API call
When mapping data in a transformation using a BAPI or RFC target, it helps to test the exact values SAP is looking for, as what is seen in the SAP GUI is often not what is used in the SAP API.
You can use the SAP transaction code SE37 to access SAP's Function Builder to model a BAPI or RFC call. For a complete example, see Part 2: Modeling the query in the SAP instance in Guide to using RFC_READ_TABLE to query SAP tables.
Handling BAPI conventions
Certain BAPIs — such as BAPI_SALESORDER_CREATEFROMDAT2
— have sets of fields that require special handling.
As shown below, the fields that are mapped in the header (ORDER_HEADER_IN
) are repeated in the *_INX
folder. To tell SAP that you intend to populate the header fields, insert an "X"
as the field value in each of the fields that are a repeat of a header field:
However, in the ORDER_ITEMS_INX
section, the ITM_NUMBER
field under ORDER_ITEMS_INX
does not have an "X"
inserted; instead, it receives the same item number as used in the field ORDER_ITEMS_IN
:
Handling partner functions with additional folders
In this section, we need to pass in the SoldTo, ShipTo, and BillTo. We've added additional folders for mapping them and defaulted the partner roles (AG, WE, RE):
Handling partner functions with the SetInstances
Function
An alternative to adding new folders is to use the SetInstances()
function with no additional folders:
In the root condition, we would create a series of arrays inside a PartnersArray
and set it to the ORDER_PARTNERS
using:
SoldToParentArray = Array();
Set(SoldToParentArray, "AG", -1);
Set(SoldToParentArray, Order$Header$Sold_To_Customer_Number$, -1);
ShipToParentArray = Array();
Set(ShipToParentArray, "WE", -1);
Set(ShipToParentArray, Order$Lines$Line#1.Customer_Number$, -1); // new change
BillToParentArray = Array();
Set(BillToParentArray, "RE", -1);
Set(BillToParentArray, Order$Header$Bill_To_Customer_Number$, -1);
PartnersArray = Array();
Set(PartnersArray, SoldToParentArray, -1);
Set(PartnersArray, ShipToParentArray, -1);
Set(PartnersArray, BillToParentArray, -1);
SetInstances("ORDER_PARTNERS", PartnersArray);
True
In the folder condition under ORDER_PARTNERS
, to set the instances we would use:
$instanceReference = GetInstance();
True
For further details, see the Jitterbit functions Set()
, GetInstance()
, and SetInstances()
.
Handling incrementing line numbers
In the section ORDER_SCHEDULES_IN
, we would once again insert an "X"
in the data fields.
For the field SCHED_LINE
, SAP increments them by 10 (line 10, line 20, line 30, and so on). We can use a global variable counter in the condition under ORDER_SCHEDULES_IN
to calculate the value:
If(Length($ItemLineCounterS) == 0, $ItemLineCounterS = 0);
$ItemLineCounterS = $ItemLineCounterS + 10;
True
For further details, see the Jitterbit function Length()
.
Retrieving values from an IDoc
Here we want to get start and end dates from an IDoc to create a contract. The data is located here:
In E1EDP03
, we want the DATUM
value where IDDAT == 107
(or 108
) for the start and end dates respectively. A handy function for this is the Jitterbit FindValue()
function. This function will cycle through the IDDAT
values, find the one with "107"
and retrieve the DATUM
field:
result=FindValue("107", OUTPUT$ORDERS05.IDOC$E1EDP01.E1EDP03#.IDDAT$, OUTPUT$ORDERS05.IDOC$E1EDP01.E1EDP03#.DATUM$);
Troubleshooting BAPI commits
In some scenarios, you may find that although the execution of a BAPI appears to be successful, the expected transaction isn't committed to SAP.
This may occur if a BAPI returns a response type that is something other than S
(Success). Jitterbit's SAP Connector, by default, issues a BAPI transaction commit (in the same thread) only when a BAPI response is Success. However, it does not issue a transaction commit if the BAPI response is anything other than Success.
For example, the response type may be I
(Information), E
(Error), or W
(Warning). The response type is returned in the RETURN
node's TYPE field:
If you are using a customized BAPI, we recommend changing the BAPI to return a Success.