Developing business objects using IDocs

WebSphere business objects for the ABAP Extension Module can be defined in SAP as an IDoc. IDocs are part of SAP's EDI solution known as ALE (Application Link Enabling). Their definitions are stored in SAP's BOR (Business Object Repository) and can be accessed globally within an SAP system. This leverages the definition part of ALE to interpret and parse WebSphere business objects in the SAP application in preparation for use with an SAP native API. The adapter provides an IDoc handler that supports business objects developed using IDocs.

IDoc handler consists of two function modules. Other ABAP handlers such as Dynamic Retrieve and Dynamic Transaction consist of only a single function module.

/CWLD/RFC_DO_VERB_NEXTGEN passes business object data to IDoc handler /CWLD/IDOC_HANDLER. This IDoc handler, which is generic to all object types, uses the business object's application-specific information to obtain the type of IDoc specified and to reformat the business object data into the structure of that IDoc. After it reformats the data, the generic IDoc handler passes the business object data to an object-specific IDoc handler (based on the combination of the business object type and its verb), which handles the integration with an SAP native API. After the object-specific IDoc handler finishes processing the business object data, it returns the business object data in IDoc format to /CWLD/IDOC_HANDLER. This generic IDoc handler now converts the business object data back to its original format and returns it to /CWLD/RFC_DO_VERB_NEXTGEN.

Figure 16 illustrates the basic architecture of IDoc handler.

Figure 16. IDoc h'andler architecture


To use the adapter-provided IDoc handler, you must have an IDoc defined in the SAP application. Either SAP-delivered or customer-built IDocs can be used. Because an IDoc definition must mirror the definition of the WebSphere business object for SAP, the adapter provides two tools to generate the WebSphere business object definition based on an IDoc:

The following sections describe how to use both of these tools.

Using IBM CrossWorlds Station to generate a business object definition

Before you can use IBM CrossWorlds station to generate a business object definition, you must have already created a WebSphere business object in the SAP application. To create a business object definition based on an IDoc:

  1. Go to IBM CrossWorlds Station (transaction /n/CWLD/HOME).
    Important:
    You must log on to the SAP system in English when using IBM CrossWorlds Station to generate business object definitions or ABAP handlers. The CrossWorlds Station log is available only in English.
  2. Click the Tools tab.
  3. Click the CW Object Definition button, and then click Advanced Download (F7).
  4. Fill in the Object and Functions information as needed. You must specify an existing IDoc type and WebSphere Object Name. The fields in the Functions section are the application-specific information for the supported verbs.

For example, an SAP4_Order business object based on the Order IDoc type YXRV4B01 could have the following functions:

For more information on how the application-specific information is used for the verb functions, see Business object data routing to ABAP handlers.

After defining the IDoc, create a function module for each verb the business object must support. Each function should have the following interface to ensure that /CWLD/IDOC_HANDLER can call it:

*" IMPORTING 
 *"        VALUE(OBJECT_KEY_IN) LIKE /CWLD/LOG_HEADER-OBJ_KEY OPTIONAL 
 *"        VALUE(INPUT_METHOD) LIKE  BDWFAP_PAR- NPUTMETHD OPTIONAL
 *"        VALUE(LOG_NUMBER) LIKE /CWLD/LOG_HEADER-LOG_NR OPTIONAL 
 *" EXPORTING 
 *"        VALUE(OBJECT_KEY_OUT) LIKE /CWLD/LOG_HEADER-OBJ_KEY 
 *"        VALUE(RETURN_CODE) LIKE /CWLD/RFCRC_STRU-RFCRC 
 *"        VALUE(RETURN_TEXT) LIKE /CWLD/LOG_HEADER-OBJ_KEY 
 *" TABLES 
 *"        IDOC_DATA STRUCTURE  EDID4
 

Using SAPODA to generate a business object definition

You can use SAPODA to generate business object definitions for the ABAP Extension Module based upon an IDoc:

Important:
You must log on to the SAP system in English to use SAPODA.

When you use SAPODA to generate a business object definition, you can use Business Object Designer to view and modify the definition. For more information on using SAPODA, see Appendix D, Generating business object definitions using SAPODA.

After defining the IDoc, create a function module for each verb the business object must support. Each function should have the following interface to ensure that
/CWLD/IDOC_HANDLER can call it:

*" IMPORTING 
 *"        VALUE(OBJECT_KEY_IN) LIKE /CWLD/LOG_HEADER-OBJ_KEY OPTIONAL 
 *"        VALUE(INPUT_METHOD) LIKE  BDWFAP_PAR- NPUTMETHD OPTIONAL
 *"        VALUE(LOG_NUMBER) LIKE /CWLD/LOG_HEADER-LOG_NR OPTIONAL 
 *" EXPORTING 
 *"        VALUE(OBJECT_KEY_OUT) LIKE /CWLD/LOG_HEADER-OBJ_KEY 
 *"        VALUE(RETURN_CODE) LIKE /CWLD/RFCRC_STRU-RFCRC 
 *"        VALUE(RETURN_TEXT) LIKE /CWLD/LOG_HEADER-OBJ_KEY 
 *" TABLES 
 *"        IDOC_DATA STRUCTURE  EDID4
 

IDoc handlers and create, update, and delete verbs

IDoc handlers that support Create, Update, and Delete operations receive business object data formatted as an IDoc. The role of these operations is to integrate the business object data with SAP's Call Transaction API and generate an object key. Only the object key is passed back through /CWLD/IDOC_HANDLER to the connector, not the business object data. /CWLD/IDOC_HANDLER stores the business object data in memory and inserts the object key into the first attribute marked IsKey in the parent business object. Then, /CWLD/IDOC_HANDLER passes the business object data back to the connector.

Note:
When the WebShpere InterChange Server is the integration broker, it is critical to maintain the business object data because the mapping infrastructure requires the preservation of the ObjectEventId for dynamic cross-referencing.

The sample code below represents the following flow:

  1. Initializes global data.
  2. Deconstructs the IDoc into working tables.
  3. Builds the BDC. Uses the forms in /CWLD/INBIDOC_FRMS0 to transfer data from the internal tables into the BDC table for consistent behavior across objects.
  4. Creates a Call Transaction.
  5. Captures the object key.

The following sample code supports SAP Sales Quote Create:

*- Initialize working variables and internal tables
   PERFORM INITIALIZE_IN.
  
 *- I01(MF): Begin IDoc interpretation
   PERFORM LOG_UPDATE(/CWLD/SAPLLOG) USING C_INFORMATION_LOG TEXT-I01
                                      SPACE SPACE SPACE.
  
 *- Interpret IDoc data structure
   IF NOT IDOC_DATA[] IS INITIAL.
  
 *- Move IDoc to internal tables
     PERFORM INTERPRET_IDOC.
  
 *- Check some of the input fields
     PERFORM CHECK_INPUT.
  
 *- If key values were missing, exit function
     IF RETURN_CODE NE 0.
       EXIT.
     ENDIF.
  
 *- E01(MF): No Idoc data lines sent for processing.
   ELSE.
  
     RETURN_CODE = 2.
     RETURN_TEXT = TEXT-E01.
     EXIT.
  
   ENDIF.
  
 *- Build the BDC session for transaction VA21.
   PERFORM BUILD_BDC_VA21.
  
 *- Call Transaction
   PERFORM LOG_UPDATE(/CWLD/SAPLLOG) USING C_INFORMATION_LOG TEXT-I02
                                      'VA21' C_BLANK C_BLANK.
  
   CALL TRANSACTION 'VA21' USING BDCDATA
                            MODE INPUT_METHOD
                          UPDATE 'S'
                        MESSAGES INTO BDC_MESSAGES.
  
 *- Capture return code and object key from transaction
   PERFORM PREPARE_RETURNED_MESSAGE.
  
 ENDFUNCTION.
 

The Create logic has two main functions:

Translating IDOC structure

The first part of the Create logic is the task of translating data in the IDoc structure into working data structures. To do this, you need to create code similar to the following:

loop at idoc_data.
  
     case idoc_data-segnam.
       when 'ZSQVBAK'.                  " Header Data
         move idoc_data-sdata to zsqvbak.
  
       when 'ZSQVBUK'.                  " Status Segment
         move idoc_data-sdata to zsqvbuk.
  
       when 'ZSQVBP0'.                  " Partner Header Level
         move idoc_data-sdata to zsqvbp0.
  
       when 'ZSQVBAP'.                  " Item Detail
         move idoc_data-sdata to zsqvbap.
  
       when 'ZSQVBA2'.                  " Item Detail Part 2
         move idoc_data-sdata to zsqvba2.
  
       when 'ZSQVBUP'.                  " Item Status
         move idoc_data-sdata to zsqvbup.
  
       when 'ZSQVBKD'.                  " Commercial data
         move idoc_data-sdata to zsqvbkd.
  
       when 'ZSQKONV'.                  " Condition
         move idoc_data-sdata to zsqkonv.
  
       when 'ZSQVBPA'.                  " Partner Item Level
         move idoc_data-sdata to zsqvbpa.
  
     endcase.
  
   endloop.
 

Creating inbound call transaction logic

The second part of the create logic performs the operation of adding data to the SAP application database. You can use available functionality such as BAPIs and SAP standard functions or you can use custom-developed Call Transaction functionality. Keep in mind that if you use the available functionality, it may change in future releases. It is recommended that you use Call Transactions instead of writing to the database. Call Transactions allow you to develop custom functionality, independent of SAP database changes and specific to the scope and functionality you need.

To pass business object data into SAP, you can generate some of the ABAP code by using the Inbound Wizard in IBM CrossWorlds Station (transaction /n/CWLD/HOME), using the SAP BDC recorder, or developing it manually.

The Inbound Wizard records the activity for your create transaction and creates a text file with the BDC logic. For the Sales Quote example, transaction VA21 is recorded.

To record transaction VA21 using Inbound Wizard:

  1. Go to IBM CrossWorlds Station (transaction /n/CWLD/HOME).
    Important:
    You must log on to the SAP system in English when using IBM CrossWorlds Station to generate business object definitions or ABAP handlers. The CrossWorlds Station log is available only in English.
  2. On the Development tab, click the Inbound Wizard button.
  3. Enter the following information:
  4. Click Record.
  5. Step through the transaction that supports your business object functionality. Use all necessary fields and screens. When you are finished, save your transaction.
  6. Choose the components that you want to include as metadata in your business object. Place your cursor on the component, and then click the Select/Deselect sub-tree button (F9). By default, all components are selected.
  7. Generate a new dynamic object or source code.

The following sample code is an excerpt from the first few lines of the generated BDC session:

* Sales doc. Initial screen Create
 perform dynpro_new using 'SAPMV45A' '0101' .
  
 * Sales document type
 perform dynpro_set using 'VBAK-AUART' 'QT' .
  
 * Distribution channel
 perform dynpro_set using 'VBAK-VTWEG' 'sourcefield' .
  
 * Division
 perform dynpro_set using 'VBAK-SPART' 'sourcefield' .
  
 * Function Command
 perform dynpro_set using 'BDC_OKCODE' '=ENT2' .
  
 * 4.0: Screen Container for Overview Screens (normal header)
 perform dynpro_new using 'SAPMV45A' '4001' .
  
 * Sold-to party
 perform dynpro_set using 'KUAGV-KUNNR' '238' .
  
 * Ship-to party
 perform dynpro_set using 'KUWEV-KUNNR' '238' .
  
 * Function Command
 perform dynpro_set using 'BDC_OKCODE' '=KKAU' .
  
 * 4.0: Screen container for document header screens
 perform dynpro_new using 'SAPMV45A' '4002' .
  
 * Date until which bid/quotation is binding (valid-to date)
 perform dynpro_set using 'VBAK-BNDDT' '20000630' .
 

You can also use SAP's BDC recorder (transaction SHDB). The following sample code was generated using the BDC recorder:

start-of-selection.                                
  
 read dataset dataset into record.
  if sy-subrc <> 0. exit. endif.
  
  perform bdc_dynpro      using 'SAPMV45A' '0101'.
  perform bdc_field       using 'BDC_CURSOR'
                                'VBAK-AUART'.
  perform bdc_field       using 'BDC_OKCODE'
                                '=ENT2'.
  perform bdc_dynpro      using 'SAPMV45A' '4001'.
  perform bdc_field       using 'BDC_OKCODE'
                                '=KKAU'.
  perform bdc_field       using 'BDC_CURSOR'
                                'KUWEV-KUNNR'.
  perform bdc_field       using 'KUAGV-KUNNR'
                                record-KUNNR_001.
  perform bdc_field       using 'KUWEV-KUNNR'
 

The output from this method does not have the business object comments from the first method and is less preferable. The advantage using SAP's BDC recorder is that it produces an independent method to verify your recording of BDC.

Another method is to generate the BDC manually. This is not an advised approach for the entire create functionality but rather as a supplement to the previous methods. It is useful when you need to add logic for additional screens or pop up boxes that may occur if the input data causes the SAP transaction to produce them.

IDoc handlers and the retrieve verbs

Object-specific IDoc handlers that support the Retrieve verb do not receive business object data from /CWLD/IDOC_HANDLER. Instead /CWLD/IDOC_HANDLER uses the OBJECT_KEY_IN parameter of the object-specific IDoc handler function to pass only the value of the first attribute marked IsKey. It is the object-specific IDoc handler's responsibility to use the value of this attribute to retrieve all information relevant to the instance of the business object using ABAP SQL, and to format that data in the appropriate IDoc structure.

Note:
In cases where the key is composed of multiple fields, the event detection mechanism (or, when the WebSphere InterChange Server is the integration broker, the map) concatenates the values of these fields into the first key attribute of the top-level business object. /CWLD/IDOC_HANDLER takes this concatenated key and loads it into its OBJECT_KEY_IN parameter. The object-specific IDoc handler must parse the value of the OBJECT_KEY_IN parameter into the multiple key fields. To maintain this functionality, it is important that you do not specify name-value pairs for the key when using /CWLD/IDOC_HANDLER.

The code fragment below illustrates an object-specific IDoc handler for retrieval of a Sales Quote. The Sales Quote business object retrieves data from tables VBAK, VBUK, VBPO, VBAP, VBUP, VBKD, KNOV, and VBPA. The tables follow the hierarchy and cardinality of IDoc type ZSLSQUOT. The code does the following:

  1. Initializes global data.
  2. Returns business object data from the SAP application database.
  3. Builds an IDoc from the returned data and returns that data to /CWLD/IDOC_HANDLER.

The code fragment for an object-specific IDoc handler for IDoc type ZSLSQUOT is:

*- Clear the interface structures.
   clear: g_text, object_key_out, return_code, return_text, idoc_data.
   refresh: idoc_data.
  
 *  If no key value is specified, log it as an error and exit.
   if object_key_in is initial or
      object_key_in = c_cxignore_const.
     perform log_update(/cwld/sapllog) using c_error_log text-e02
                                        space space space.
     return_code = 1.
     return_text = text-e02.
     exit.
   endif.
  
   perform initialize_global_structures.
  
   perform fill_internal_tables.
   if not return_code is initial.
     exit.
   endif.
  
 * Build Idoc segments from internal tables
   perform fill_idoc_inttab.
  
   return_code = 0.
   return_text = text-s01.
  
   perform log_update(/cwld/sapllog) using c_information_log text-s01
                                      space space space.
 endfunction.
 

The two most important parameters are OBJECT_KEY_IN for the inbound key and IDOC_DATA for the outbound data. Note that OBJECT_KEY_IN may be a concatenated string that represents a multiple key (depending on the conventions you have defined). The object-specific IDoc handler parses the concatenated value and loads its parts into the appropriate key fields. To maintain this functionality, it is important that you do not specify name-value pairs for the key when using /CWLD/IDOC_HANDLER.

The VBAK table drives the selection criteria for the child tables, so each table is loaded into working tables. Using the VBAK table, you can retrieve the child tables with additional keys. So, for the Sales Quote example, the code is as follows:

form fill_internal_tables.
  
   * Get information from VBAK, VBUK, VBAP, VBKD, KONV, VBPA
  
   select single * from vbak
          where vbeln = object_key_in.
  
   if sy-subrc <> 0.
     perform log_update(/cwld/sapllog) using c_error_log text-e01
                                  object_key_out c_blank c_blank.
     return_code = '1'.
     g_text = text-e01.
     replace '&' with order_number into g_text.
     return_text = g_text.
  
     exit.
   endif.
  
   select single * from vbuk
          where vbeln = vbak-vbeln.
  
   select * from vbap into table t_vbap
          where vbeln = vbak-vbeln.
  
   * Continue for other tables
 

The following code is used to copy the requested data from the application database into internal tables and working variables. Then it creates segments that directly correspond to the WebSphere business object definition and puts them into the SAP segment structure.

In some cases for close matches on fields between the IDoc type and the working structure, you can do an ABAP move-corresponding command. In other cases, it is preferable to manually move fields from the working table to the IDoc type table because of the relatively few fields to move in comparison to the overall number of fields in the structure. Simply, it is used to transfer data from the working data structures into the IDoc structures and then into the flat data field.

The code is:

form fill_idoc_inttab.
  
 perform fill_zsqvbak.                   " Fill the Sales Quote Header
 perform fill_zsqvbuk.                   " Fill the Sales Quote Status
 perform fill_zsqvbap.                   " Fill Sales Quote Lines
  
 endform.                                " FILL_IDOC_INTTAB
  
 *-- fill the Sales Quote Header
 form fill_zsqvbak.
  
   clear idoc_data.
   clear zsqvbak.
   idoc_data-segnam = 'ZSQVBAK'.
  
   move-corresponding vbak to zsqvbak.
   move zsqvbak to idoc_data-sdata.
   append idoc_data.
  
 endform.                                " FILL_ZSQVBAK
  
 *-- fill the Sales Quote Header Status
 form fill_zsqvbuk.
  
   clear idoc_data.
   clear zsqvbuk.
   idoc_data-segnam = 'ZSQVBUK'.
  
   move-corresponding vbuk to zsqvbuk.
   move zsqvbuk to idoc_data-sdata.
   append idoc_data.
  
 endform.                                " FILL_ZSQVBAK
  
 *-- fill the Sales Quote Line and the Line Child segments
 form fill_zsqvbap.
  
   loop at t_vbap.
     clear idoc_data.
     clear zsqvbap.
     idoc_data-segnam = 'ZSQVBAP'.
  
     move-corresponding t_vbap to zsqvbap.
     move zsqvbap to idoc_data-sdata.
     append idoc_data.
  
     perform fill_zsqvba2.
     perform fill_zsqvbup.
     perform fill_zsqvbkd.
     perform fill_zsqkonv.
     perform fill_zsqvbpa.
  
  
   endloop.
  
 endform.
  
 *-- fill second part of vbap
 form fill_zsqvba2.
 " etc.
 

Copyright IBM Corp. 2003, 2004