Best Practices for SAP¶
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.
This section covers SAP and Jitterbit terminology, updating SAP data, the IDoc structure, and date formats.
This section defines SAP-specific terminology as it relates to Jitterbit Harmony Design Studio and its SAP Connector.
- SAP: When we refer to SAP, we mean a version of SAP that is compatible with the Jitterbit Harmony 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 on-premises.
- 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.
- SAP Connector: The Jitterbit Harmony 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 Jitterbit 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.
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:
Though SAP can display dates in its GUI in different formats (following country conventions), the data format for the SAP APIs is
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 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 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.
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.
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:
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
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|
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
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
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
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
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
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:
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
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
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.