Skip to Content

There are a number of SAP Gateway Deep Insert examples. I liked this one Deep Insert in SAP Netweaver Gateway from Prakash’s blog series. I had to make some code changes though to make it work for me, extended the example with deep insert from Fiori and tried to make explanation short and simple.

SAP Gateway Deep Inset allows to store hierarchical data like in our case Sales Order that has both header and item data (one can not exist without another).

Deep Inset is an opposite to $expand URI option.

Let’s create OData Service that will implement both $expand URI option and Deep Insert (we will use $expand results as request for Deep Insert testing in Gateway Client)

Service has two entities: SalesOrder and OrderItems. One for SO Header data and another to SO Item data

Here is how SalesOrder and OrderItems entities are defined

SalesOrder has OrderToItems navigation property to implement $expand URI Option

The OData Services implements following operation:

SalesOrder GetEntity

SalesOrder GetEntitySet (note needed for Deep Insert and $expand, but helps find testing data)

OrderItems GetEntity

Create Deep Entry

Get Expanded Entity

Here is complete implementation of DPC class:

class ZCL_ZSL_EPM_DEMO_DPC_EXT definition
  public
  inheriting from ZCL_ZSL_EPM_DEMO_DPC
  create public .

public section.

  methods /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY
    redefinition .
  methods /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITY
    redefinition .
protected section.

  methods ORDERITEMSSET_GET_ENTITYSET
    redefinition .
  methods SALESORDERSET_GET_ENTITY
    redefinition .
  methods SALESORDERSET_GET_ENTITYSET
    redefinition .
private section.
ENDCLASS.



CLASS ZCL_ZSL_EPM_DEMO_DPC_EXT IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ZSL_EPM_DEMO_DPC_EXT->/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_ENTITY_NAME                 TYPE        STRING(optional)
* | [--->] IV_ENTITY_SET_NAME             TYPE        STRING(optional)
* | [--->] IV_SOURCE_NAME                 TYPE        STRING(optional)
* | [--->] IO_DATA_PROVIDER               TYPE REF TO /IWBEP/IF_MGW_ENTRY_PROVIDER
* | [--->] IT_KEY_TAB                     TYPE        /IWBEP/T_MGW_NAME_VALUE_PAIR(optional)
* | [--->] IT_NAVIGATION_PATH             TYPE        /IWBEP/T_MGW_NAVIGATION_PATH(optional)
* | [--->] IO_EXPAND                      TYPE REF TO /IWBEP/IF_MGW_ODATA_EXPAND
* | [--->] IO_TECH_REQUEST_CONTEXT        TYPE REF TO /IWBEP/IF_MGW_REQ_ENTITY_C(optional)
* | [<---] ER_DEEP_ENTITY                 TYPE REF TO DATA
* | [!CX!] /IWBEP/CX_MGW_BUSI_EXCEPTION
* | [!CX!] /IWBEP/CX_MGW_TECH_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD /iwbep/if_mgw_appl_srv_runtime~create_deep_entity.
DATA: BEGIN OF ls_order_item_data.
        INCLUDE TYPE zcl_zsl_epm_demo_mpc=>ts_salesorder.
      DATA: OrderToItems  TYPE zcl_zsl_epm_demo_mpc=>tt_orderitems,
      END OF ls_order_item_data.
DATA: lv_entity_set_name TYPE /iwbep/mgw_tech_name,
      ls_headerdata      TYPE bapi_epm_so_header,
      lt_itemdata        TYPE STANDARD TABLE OF  bapi_epm_so_item,
      ls_itemdata        TYPE bapi_epm_so_item,
      ls_req_itemdata    TYPE zcl_zsl_epm_demo_mpc=>ts_orderitems,
      lt_return          TYPE STANDARD TABLE OF bapiret2,
      lv_so_id           TYPE bapi_epm_so_id.

* Get Entity Set Name
  lv_entity_set_name     = io_tech_request_context->get_entity_set_name( ).
*
  CASE lv_entity_set_name.
  WHEN 'SalesOrderSet'.

*   Get the Sales Order header and item data from the request to be created
    io_data_provider->read_entry_data( IMPORTING es_data = ls_order_item_data ).
    MOVE-CORRESPONDING ls_order_item_data TO ls_headerdata.
    CLEAR: ls_headerdata-created_by,
           ls_headerdata-changed_by.
*
* Populate the BAPI structures
*   Sales Order Header
    ls_headerdata-buyer_id = '0100000000'. "ls_order_item_data-buyer_id.
*
*   Sales Order Item
    LOOP AT ls_order_item_data-OrderToItems INTO ls_req_itemdata.
      MOVE-CORRESPONDING ls_req_itemdata TO ls_itemdata.
      CLEAR: ls_itemdata-so_id,
             ls_itemdata-so_item_pos,
             ls_itemdata-currency_code.
      GET TIME STAMP FIELD ls_itemdata-delivery_date.
      APPEND ls_itemdata TO lt_itemdata.
    ENDLOOP.
*
    CALL FUNCTION 'BAPI_EPM_SO_CREATE'
         EXPORTING
              headerdata   = ls_headerdata
         IMPORTING
              salesorderid = lv_so_id
         TABLES
              itemdata     = lt_itemdata
              return       = lt_return.
    READ TABLE lt_return TRANSPORTING NO FIELDS WITH KEY type = 'E'.
    IF sy-subrc = 0.
      CALL METHOD mo_context->get_message_container( )->add_messages_from_bapi(
           EXPORTING
                it_bapi_messages          = lt_return
                iv_determine_leading_msg  = /iwbep/if_message_container=>gcs_leading_msg_search_option-first ).
      RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
            EXPORTING
                 textid            = /iwbep/cx_mgw_busi_exception=>business_error
                 message_container = mo_context->get_message_container( ).
    ENDIF.
*
*   Push back the data again with newly created Sales Order ID
    CLEAR: ls_headerdata,lt_itemdata[],ls_order_item_data.
    CALL FUNCTION 'BAPI_EPM_SO_GET_DETAIL'
    EXPORTING
         so_id      = lv_so_id
    IMPORTING
         headerdata = ls_headerdata
    TABLES
         itemdata   = lt_itemdata.

    MOVE-CORRESPONDING ls_headerdata TO ls_order_item_data.
    APPEND LINES OF lt_itemdata TO ls_order_item_data-OrderToItems.

    copy_data_to_ref( EXPORTING is_data = ls_order_item_data
                       CHANGING  cr_data = er_deep_entity ).

  ENDCASE.

ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ZSL_EPM_DEMO_DPC_EXT->/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITY
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_ENTITY_NAME                 TYPE        STRING(optional)
* | [--->] IV_ENTITY_SET_NAME             TYPE        STRING(optional)
* | [--->] IV_SOURCE_NAME                 TYPE        STRING(optional)
* | [--->] IT_KEY_TAB                     TYPE        /IWBEP/T_MGW_NAME_VALUE_PAIR(optional)
* | [--->] IT_NAVIGATION_PATH             TYPE        /IWBEP/T_MGW_NAVIGATION_PATH(optional)
* | [--->] IO_EXPAND                      TYPE REF TO /IWBEP/IF_MGW_ODATA_EXPAND(optional)
* | [--->] IO_TECH_REQUEST_CONTEXT        TYPE REF TO /IWBEP/IF_MGW_REQ_ENTITY(optional)
* | [<---] ER_ENTITY                      TYPE REF TO DATA
* | [<---] ES_RESPONSE_CONTEXT            TYPE        /IWBEP/IF_MGW_APPL_SRV_RUNTIME=>TY_S_MGW_RESPONSE_ENTITY_CNTXT
* | [<---] ET_EXPANDED_CLAUSES            TYPE        STRING_TABLE
* | [<---] ET_EXPANDED_TECH_CLAUSES       TYPE        STRING_TABLE
* | [!CX!] /IWBEP/CX_MGW_BUSI_EXCEPTION
* | [!CX!] /IWBEP/CX_MGW_TECH_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entity.
DATA: BEGIN OF s_expand_so.
        INCLUDE TYPE zcl_zsl_epm_demo_mpc=>ts_salesorder.
      DATA: OrderToItems  TYPE zcl_zsl_epm_demo_mpc=>tt_orderitems,
      END OF s_expand_so.
DATA: ls_expand_so   LIKE s_expand_so,
      ls_item TYPE zcl_zsl_epm_demo_mpc=>ts_orderitems.
DATA:  ls_salesorder TYPE bapi_epm_so_header,
       lt_itemdata   TYPE TABLE OF bapi_epm_so_item,
       ls_itemdata   TYPE  bapi_epm_so_item.
DATA:  ls_key_tab   TYPE /iwbep/s_mgw_name_value_pair,
       lv_soid  TYPE bapi_epm_so_id.
DATA: lv_product_id     TYPE bapi_epm_product_id,
      ls_product_header TYPE bapi_epm_product_header.
CONSTANTS: lc_expand_tech_clause  TYPE string VALUE 'ORDERTOITEMS'.

*Get the key property values and Read Sales Order and Item data
  READ TABLE it_key_tab WITH KEY name = 'SoId' INTO ls_key_tab.
  lv_soid = ls_key_tab-value.
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
       EXPORTING
            input = lv_soid
       IMPORTING
            output = lv_soid.
  CALL FUNCTION 'BAPI_EPM_SO_GET_DETAIL'
       EXPORTING
            so_id     = lv_soid
       IMPORTING
            headerdata = ls_salesorder
       TABLES
            itemdata  = lt_itemdata.

* Data processing logic
  MOVE-CORRESPONDING ls_salesorder TO ls_expand_so  .
  LOOP AT lt_itemdata INTO ls_itemdata WHERE so_id = ls_salesorder-so_id .
    MOVE-CORRESPONDING ls_itemdata TO ls_item  .
    lv_product_id = ls_itemdata-product_id.
    APPEND ls_item  TO ls_expand_so-OrderToItems.
  ENDLOOP.

* Fill ER_ENTITY
  copy_data_to_ref(
    EXPORTING
         is_data = ls_expand_so
    CHANGING
         cr_data = er_entity ).

* Insert Navigation property into ET_EXPANDED_TECH_CLAUSES
  INSERT lc_expand_tech_clause INTO TABLE et_expanded_tech_clauses.

ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_ZSL_EPM_DEMO_DPC_EXT->ORDERITEMSSET_GET_ENTITYSET
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_ENTITY_NAME                 TYPE        STRING
* | [--->] IV_ENTITY_SET_NAME             TYPE        STRING
* | [--->] IV_SOURCE_NAME                 TYPE        STRING
* | [--->] IT_FILTER_SELECT_OPTIONS       TYPE        /IWBEP/T_MGW_SELECT_OPTION
* | [--->] IS_PAGING                      TYPE        /IWBEP/S_MGW_PAGING
* | [--->] IT_KEY_TAB                     TYPE        /IWBEP/T_MGW_NAME_VALUE_PAIR
* | [--->] IT_NAVIGATION_PATH             TYPE        /IWBEP/T_MGW_NAVIGATION_PATH
* | [--->] IT_ORDER                       TYPE        /IWBEP/T_MGW_SORTING_ORDER
* | [--->] IV_FILTER_STRING               TYPE        STRING
* | [--->] IV_SEARCH_STRING               TYPE        STRING
* | [--->] IO_TECH_REQUEST_CONTEXT        TYPE REF TO /IWBEP/IF_MGW_REQ_ENTITYSET(optional)
* | [<---] ET_ENTITYSET                   TYPE        ZCL_ZSL_EPM_DEMO_MPC=>TT_ORDERITEMS
* | [<---] ES_RESPONSE_CONTEXT            TYPE        /IWBEP/IF_MGW_APPL_SRV_RUNTIME=>TY_S_MGW_RESPONSE_CONTEXT
* | [!CX!] /IWBEP/CX_MGW_BUSI_EXCEPTION
* | [!CX!] /IWBEP/CX_MGW_TECH_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD orderitemsset_get_entityset.
DATA: ls_max_rows   TYPE bapi_epm_max_rows,
      lv_so_id      TYPE bapi_epm_so_id,
      lt_orderitems TYPE TABLE OF bapi_epm_so_item,
      ls_orderitems TYPE bapi_epm_so_item,
      lwa_key_tab   TYPE /iwbep/s_mgw_name_value_pair,
      ls_entityset  TYPE zcl_zsl_epm_demo_mpc=>ts_orderitems.

* To get the Sales Order#
  READ TABLE it_key_tab INTO lwa_key_tab WITH KEY name = 'SoId'.
  IF sy-subrc = 0.
    lv_so_id = lwa_key_tab-value.
  ENDIF.

* if Sales Order is not available in the request,retrieve
* first 20 Sales Orders Items
  IF lv_so_id IS INITIAL.
    ls_max_rows-bapimaxrow = 20.
    CALL FUNCTION 'BAPI_EPM_SO_GET_LIST'
         EXPORTING
              max_rows   = ls_max_rows
         TABLES
              soitemdata = lt_orderitems.
    IF lt_orderitems IS NOT INITIAL.
      LOOP AT lt_orderitems INTO ls_orderitems.
        MOVE-CORRESPONDING ls_orderitems TO ls_entityset.
        APPEND ls_entityset TO et_entityset.
      ENDLOOP.
    ENDIF.
  ELSE.

* if Sales Order is available in the request,retrieve
* it's Order Items
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
         input  = lv_so_id
    IMPORTING
         output = lv_so_id.

    CALL FUNCTION 'BAPI_EPM_SO_GET_DETAIL'
         EXPORTING
              so_id    = lv_so_id
         TABLES
              itemdata = lt_orderitems.
    IF lt_orderitems IS NOT INITIAL.
      LOOP AT lt_orderitems INTO ls_orderitems.
        MOVE-CORRESPONDING ls_orderitems TO ls_entityset.
        APPEND ls_entityset TO et_entityset.
      ENDLOOP.
    ENDIF.
  ENDIF.

ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_ZSL_EPM_DEMO_DPC_EXT->SALESORDERSET_GET_ENTITY
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_ENTITY_NAME                 TYPE        STRING
* | [--->] IV_ENTITY_SET_NAME             TYPE        STRING
* | [--->] IV_SOURCE_NAME                 TYPE        STRING
* | [--->] IT_KEY_TAB                     TYPE        /IWBEP/T_MGW_NAME_VALUE_PAIR
* | [--->] IO_REQUEST_OBJECT              TYPE REF TO /IWBEP/IF_MGW_REQ_ENTITY(optional)
* | [--->] IO_TECH_REQUEST_CONTEXT        TYPE REF TO /IWBEP/IF_MGW_REQ_ENTITY(optional)
* | [--->] IT_NAVIGATION_PATH             TYPE        /IWBEP/T_MGW_NAVIGATION_PATH
* | [<---] ER_ENTITY                      TYPE        ZCL_ZSL_EPM_DEMO_MPC=>TS_SALESORDER
* | [<---] ES_RESPONSE_CONTEXT            TYPE        /IWBEP/IF_MGW_APPL_SRV_RUNTIME=>TY_S_MGW_RESPONSE_ENTITY_CNTXT
* | [!CX!] /IWBEP/CX_MGW_BUSI_EXCEPTION
* | [!CX!] /IWBEP/CX_MGW_TECH_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD salesorderset_get_entity.

DATA: lwa_key_tab TYPE /iwbep/s_mgw_name_value_pair,
      lv_so_id    TYPE snwd_so_id,
      lwa_snwd_so TYPE snwd_so.

* To get the Sales Order#
READ TABLE it_key_tab INTO lwa_key_tab WITH KEY name = 'SoId'.
IF sy-subrc = 0.
lv_so_id = lwa_key_tab-value.
ENDIF.

* Alpha Conversion
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
  EXPORTING
    input         = lv_so_id
 IMPORTING
   output        = lv_so_id.

* Get the data from the table
SELECT SINGLE * FROM snwd_so INTO CORRESPONDING FIELDS OF er_entity WHERE so_id = lv_so_id.

ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Protected Method ZCL_ZSL_EPM_DEMO_DPC_EXT->SALESORDERSET_GET_ENTITYSET
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_ENTITY_NAME                 TYPE        STRING
* | [--->] IV_ENTITY_SET_NAME             TYPE        STRING
* | [--->] IV_SOURCE_NAME                 TYPE        STRING
* | [--->] IT_FILTER_SELECT_OPTIONS       TYPE        /IWBEP/T_MGW_SELECT_OPTION
* | [--->] IS_PAGING                      TYPE        /IWBEP/S_MGW_PAGING
* | [--->] IT_KEY_TAB                     TYPE        /IWBEP/T_MGW_NAME_VALUE_PAIR
* | [--->] IT_NAVIGATION_PATH             TYPE        /IWBEP/T_MGW_NAVIGATION_PATH
* | [--->] IT_ORDER                       TYPE        /IWBEP/T_MGW_SORTING_ORDER
* | [--->] IV_FILTER_STRING               TYPE        STRING
* | [--->] IV_SEARCH_STRING               TYPE        STRING
* | [--->] IO_TECH_REQUEST_CONTEXT        TYPE REF TO /IWBEP/IF_MGW_REQ_ENTITYSET(optional)
* | [<---] ET_ENTITYSET                   TYPE        ZCL_ZSL_EPM_DEMO_MPC=>TT_SALESORDER
* | [<---] ES_RESPONSE_CONTEXT            TYPE        /IWBEP/IF_MGW_APPL_SRV_RUNTIME=>TY_S_MGW_RESPONSE_CONTEXT
* | [!CX!] /IWBEP/CX_MGW_BUSI_EXCEPTION
* | [!CX!] /IWBEP/CX_MGW_TECH_EXCEPTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method SALESORDERSET_GET_ENTITYSET.
DATA:      ls_max_rows   TYPE bapi_epm_max_rows,
           lt_salesorder TYPE TABLE OF bapi_epm_so_header,
           ls_salesorder TYPE bapi_epm_so_header,
           ls_entityset  TYPE zcl_zsl_epm_demo_mpc=>ts_salesorder.

    ls_max_rows-bapimaxrow = 20.
    CALL FUNCTION 'BAPI_EPM_SO_GET_LIST'
      EXPORTING
        max_rows     = ls_max_rows
      TABLES
        soheaderdata = lt_salesorder.
    IF lt_salesorder IS NOT INITIAL.
      LOOP AT lt_salesorder INTO ls_salesorder.
        MOVE-CORRESPONDING ls_salesorder TO ls_entityset.
        APPEND ls_entityset TO et_entityset.
      ENDLOOP.
    ENDIF.


  endmethod.
ENDCLASS.

Note: that both Create Deep Entry and Get Expanded Entity methods operates with with hierarchical data and Order Item table has a name of navigation property e.g. OrderToItems

Once the OData Service is ready lets test it in Gateway Client.

Let’s get Sales Order and Item data in one request with $expand URI option first

Now let’s do Deep Insert using previous request data (clearing header data except for Currency Code) and changing HTTP method from GET to POST

As you can from request response below new Sales Order was created

Finally lets do Deep Insert from Fiori. Here is a Java Script code snippet responsible for that.

sap.ui.define([
	"sap/ui/core/mvc/Controller",
	"sap/m/MessageToast",
	"sap/m/MessageBox",
	"sap/ui/model/json/JSONModel"
], function (Controller, MessageToast, MessageBox, JSONModel) {
	"use strict";

	return Controller.extend("deep.insert.UX402_DeepInsertExercise.controller.Main", {

		onPress: function (evt) {
			var json = {
				"CurrencyCode": "EUR",
				"OrderToItems": [{
					"ProductId": "HT-1000",
					"Note": "EPM DG: SO ID 0500000000 Item 0000000010",
					"CurrencyCode": "EUR",
					"GrossAmount": "1137.64",
					"GrossAmountExt": "1137.6400",
					"NetAmount": "956.00",
					"NetAmountExt": "956.0000",
					"TaxAmount": "181.64",
					"TaxAmountExt": "181.6400",
					"DeliveryDate": "2018-08-26T04:00:00.0000000",
					"Quantity": "1",
					"QuantityUnit": "EA"
				}]
			};
			this.createModel = new JSONModel(json);
			this.getView().setModel(this.createModel, "createCollection");
			var oSOData = this.getView().getModel("createCollection").getData();

			var oModel = this.getOwnerComponent().getModel();
			var mParameters = {
				success: this._handleCreateSuccess,
				error: this._handleCreateError
			};
			oModel.create("/SalesOrderSet", oSOData, mParameters);
		},

		_handleCreateSuccess: function (oData, response) {
			MessageBox.alert("Order created. Order number is: " + oData.SoId);
		},

		_handleCreateError: function (oError) {
			if (oError) {
				if (oError.responseText) {
					var oErrorMessage = JSON.parse(oError.responseText);
					MessageBox.alert("Order was not created due to: " +
						oErrorMessage.error.message.value);
				}
			}
		}

	});
});

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

 

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply