Skip to Content
Business Trends
Author's profile photo Dilip Kumar Krishnadev Pandey

SAP oData Service [GET]: Multiple Table Output

Overview

  • In this blog, we will come to know, how we can get multiple table output in a single oData Service call.
  • This blogs is a business case example of parent blog:

Business Scenario:

  • Creating a purchase order via fiori app.
  • In this fiori app, we need F4 help for certain type of data (like Document-Type, Vendor-List, Purchase-Group) on different drop-down boxes, from which user selects input for purchase order creation process.
  • For same, in back-end System, we have a RFC which can return multiple table records like Document-Type, Vendor-List, Purchase-Group etc.
  • We consume this RFC in oData Service in such a manner, so that in a single call via one EntitySet, oData Service should return multiple EntitySet output (which is mapped from multiple table output of RFC)
  • Here, below explained steps is synonym to above business scenario.
  • Above type of required oData-Service will be implemented using technique of ‘Association and Navigation supporting ‘$expand’ query.

OData($expand query):

  • The $expand query option is very powerful and allows us to provide multiple entities and/or entity sets in one single service call, instead of performing several calls subsequently
  • For $expand query to work, an association or navigation property should be created.
  • And we implement get_expanded_entityset method.

Association and Navigation properties

  • These are two important properties available in SAP Netweaver Gateway to associate multiple entity types.
  • If we want a odata Service, which, in a single call, via one main EntitySet, can retrun multiple output table records in separate other EntitySets, then we use this Association and Navigation Property.
  • Here, in our case, in a single call, via EntitySet ‘InputHelpSet’, we want to receiev three type of output table records in following separte EntitySets:
    • ‘DocTypSet’ for Document List
    • ‘VendorListSet’  for Vendor List
    • ‘PurchGrpSet’ for Purchase Group List

Back-end RFC Details

  • In backend system (SAP-ECC), there is a RFC which provides multiple type of “F4 help data” in separate table.
  • This RFC need to be invoked without any input and in return, it provides following out tables:
    1. Document Type List
    2. Purchase Group List
    3. Vendor List

 

Steps to create oData Service [with GET_EXPANDED_ENTITYSET]:

  • Here, we will see detailed steps to create an oData service, which has
    • Four EntitySet structures
      • 1st is main EntitySet with which we invoke service and below three EntitySets will be navigated to refer their structures
      • 2nd is to store Document-Type records
      • 3rd is to store Purchasing-Group records
      • and 4th is store Vendor-List records
    • Three Associations
      • We create Associations to link rest three EntitySets to main EntitySet,
      • so that on call of main EntitySet, we can fill rest entitySet structure with respective RFC table output
    • And Re-definition of “get_expanded_entityset” method, which,
      • will be invoked on service call from App
      • which will in-turn call backed RFC, receives output tables of RFC
      • and map output to three different structures (EntitySets)
  • For same, lets follow below steps:

[1] Create main EntitySet to invoke service 

  • First lets create an EntitySet, with which we trigger oDataService.
  • For same create an Entity Name ‘InputHelp’
  • create EntitySet for same Entity, (in simple words, here Entity is like DataType and EntitySet is like variable)
  • Entity name ‘InputHelp’ with EntitySet name ‘InputHelpSet’
  • We create a single property (i.e column or field) in this Entity which is named as ‘field1’

[2] Create EntitySet to receive/store Document -Type

  • This EntitySet is similar structure as of Document-Type RFC-table having all respective columns/fields
  • For same, create Entity name ‘DocType’ with EntitySet name ‘DocTypeSet’
  • With following two properties:
    • von     Document Type Code
    • bis      Description

[3] Create EntitySet to receive/store Purchasing-Group

  • This EntitySet is similar structure as of Purchasing-Group RFC-table having all respective columns/fields
  • For same, create Entity name ‘PurchGrp’ with EntitySet name ‘PurchGrpSet’
  • This Entity will have following two properties:
    • EKGRP   Purchase Group
    • EKNAM   description

[4] Create EntitySet to receive/store VendorList

  • This EntitySet is similar structure as of VendorList RFC-table having all respective columns/fields
  • For same, create Entity name ‘VendorList ‘ with EntitySet name ‘VendorListSet’
  • This Entity will have following two properties:
    • LIFNR   Vendor Code
    • NAME   Vendor Name
  • Once Entity creation completed, lets save and re-generate runtime objects, for same, select project folder, click on icon (red/white circle) of ‘Generate Runtime Objects’
  • On successful generation below message appears.
  • Thus we have created four Entity with respective EntitySets structures:
    • InputHelp
    • DocType
    • PurchGrp
    • VendorList
  • Next, as per plan, we need to link rest 3 Entity with main Entity ‘InputHelp’, which can be done with help of Association & Navigation.

[5] Creating Associations & Navigation

  • With help of ‘Associations & Navigaions‘ technique of oData-Service, here we will associate three entities (DocType, PurchGrp, VendorList) with main Entity (InputHelp)
  • With this approach, via a single call through main entitySet, oDataService gets reference/access to other three entitySets too, and we can use these three entities to return respective RFctables outputs to these three entitySets.
  • To  Create Association, Go to oData Service project in t-code ‘SEGW’ -> select ‘Associations’ -> right click -> ‘Create’
  • Here we create three association with respective Navigation, to:
    1. Association between Entity ‘InputHelp’ & Entity ‘DocType’
      • To associate Entity ‘DocType’ with Entity ‘InputHelp’
      • To set navigation from Entity ‘InputHelp’ to Entity ‘DocType’
    2. Association between Entity ‘InputHelp’ & Entity ‘PurchGrp’
      • To associate Entity ‘PurchGrp’ with Entity ‘InputHelp’
      • To set navigation from Entity ‘InputHelp’ to Entity ‘PurchGrp’
    3. Association between Entity ‘InputHelp’ & Entity ‘VendorList’
      • To associate Entity ‘VendorList’ with Entity ‘InputHelp’
      • To set navigation from Entity ‘InputHelp’ to Entity ‘VendorList’

[A]  Association & Navigation between Entity ‘InputHelp’ & Entity ‘DocType’

  • To create ‘Associations’ -> click on folder name ‘Associations’ -> right click -> select ‘Create’
  • Enter Association Name “InputHelp_DocType” with Principal Entity “InputHelp” and Dependent Entity ‘DocType
  • and Navigation Property ‘NAVDOCTYP
  • Click next button -> select one Dependent Property ‘von’ from Dependent Entity ‘DocType
  • Click next button -> next window shows respective ‘Association Set’ name with respective ‘Entity Set’ names of Principal & Dependent Entity
  • Click ‘Finish’ button. next verify/check navigation details which just been created in above steps
  • Check/Verify Navigation:

[B]  Association & Navigation between Entity ‘InputHelp’ & Entity ‘PurchGrp’

  • To create ‘Associations’ -> click on folder name ‘Associations’ -> right click -> select ‘Create’
  • Enter Association Name “InputHelp_PurchGrp” with Principal Entity “InputHelp” and Dependent Entity ‘PurchGrp’
  • and Navigation Property ‘NAVPURCHGRP
  • Click next button -> select one Dependent Property ‘EKGRP’ from Dependent Entity ‘PurchGrp
  • Click next button -> next window shows respective ‘Association Set’ name with respective ‘Entity Set’ names of Principal & Dependent Entity
  • Click ‘Finish’ button. next verify/check navigation details which just been created in above steps
  • Check/Verify Navigation:

[C]  Association & Navigation between Entity ‘InputHelp’ & Entity ‘VendorList’

  • To create ‘Associations’ -> click on folder name ‘Associations’ -> right click -> select ‘Create’
  • Enter Association Name “InputHelp_VendorList” with Principal Entity “InputHelp” and Dependent Entity ‘VendorList
  • and Navigation Property ‘NAVVENDOR
  • Click next button -> select one Dependent Property ‘LIFNR’ from Dependent Entity ‘VendorList
  • Click next button -> next window shows respective ‘Association Set’ name with respective ‘Entity Set’ names of Principal & Dependent Entity
  • Click ‘Finish’ button. next verify/check navigation details which just been created in above steps
  • Check/Verify Navigation:

 

[6] Re-definitions in MPC & DPC of oData

  • MPC (Model Provider class) – This is used to define model. we can use the method Define to create entity, properties etc using code based implementation. we rarely use MPC extension class.
  • DPC (Data provider class) – used to code our ‘CRUDQ’ methods as well as function import methods. we write all our logic in redefined methods of DPC extension class.
  • The ‘CRUDQ’ methods:
    • This is nothing but Create, Read, Update, Delete and Query operations which we can do in oData Service.
  • This blog’s example is of  ‘Read’ operation in oData Service.
  • In this blog’s example, redefinition in MPC not required.
  • In DPC, we will re-define method ‘GET_EXPANDED_ENTITYSET

[6.1] Re-define [GET_EXPANDED_ENTITYSET] in DPC

  • Lets go to Project’s ‘Runtime Artifacts’ -> click on DPC Extension class of oData Service i.e. ‘ZCL_ZTEST_ODATA_DPC_EXT’
  • Select & Double click on it to go to abap workbench of DPC
  • To re-define GET_EXPANDED_ENTITYSET, go to folder ‘ZCL_ZTEST_ODATA_DPC_EXT’ -> folder ‘Methods’ -> folder ‘Inherited Methods’ -> folder ‘/IWBEP/IF_MGW_APPL_SRV_RUNTIME’ -> select GET_EXPANDED_ENTITYSET -> right click -> select ‘Redefine’
  • once method re-defined, it get listed in folder ‘Redefinitions’
  • Inside method GET_EXPANDED_ENTITYSET, we write following code, which is:
    • Here, first we check with which EntitySet, service call is been invoked, this means same method can be invoked from other EntitySets of oDataService for other purpose.
    • In our case, we call odata-Service with main EntitySet, which is ‘InputHelpSet’
    • next we call RFC of backend system (using RFC-Destination of backend system)
    • In output, RFC returns three table records:
      • lt_DocTyp : table having Document Type List
      • lt_Vendor  : table having Vendor List
      • lt_PurGrp  : table having Purchase Group List
    • Next we need to map these structures to oDataservice’s respective three EntitySets which is been referred using Navigation property
    • Here, while declaring variables of navigated entity sets, we need to keep same naming conventions, as of navigation names.
    • Variable ‘struct_response’ combines structures of four Entities
      • Main EntitySet ‘InputHelp’ directly included
      • and its navigated structures been referred with same navigation names
        • NAVDOCTYP          navigating to Entity DocType
        • NAVPURCHGRP    navigating to Entity PurchGrp
        • NAVVENDOR         navigating to Entity VendorList
    • Next we need to map received table outputs to ‘struct_response’ structure’s respective tables
    • and finally return response to oDataService using Step-05/06
  •   method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET.
    
    CASE iv_entity_set_name.
    WHEN 'InputHelpSet'.
    
    * Step-01: Variable decalartions
    DATA: lt_Vendor   TYPE TABLE OF ZCL_ZTEST_ODATA_MPC=>TS_VendorList,
          ls_Vendor   TYPE          ZCL_ZTEST_ODATA_MPC=>TS_VendorList,
          lt_DocTyp   TYPE TABLE OF ZCL_ZTEST_ODATA_MPC=>TS_DocType,
          ls_DocTyp   TYPE          ZCL_ZTEST_ODATA_MPC=>TS_DocType,
          lt_PurGrp   TYPE TABLE OF ZCL_ZTEST_ODATA_MPC=>TS_PurchGrp,
          ls_PurGrp   TYPE          ZCL_ZTEST_ODATA_MPC=>TS_PurchGrp.
    
    DATA:
        BEGIN OF struct_response.
         INCLUDE            TYPE                   ZCL_ZTEST_ODATA_MPC=>TS_InputHelp.
         DATA: NAVDOCTYP    TYPE STANDARD TABLE OF ZCL_ZTEST_ODATA_MPC=>TS_DocType    WITH DEFAULT KEY,
               NAVPURCHGRP  TYPE STANDARD TABLE OF ZCL_ZTEST_ODATA_MPC=>TS_PurchGrp   WITH DEFAULT KEY,
               NAVVENDOR    TYPE STANDARD TABLE OF ZCL_ZTEST_ODATA_MPC=>TS_VendorList WITH DEFAULT KEY,
        END OF struct_response.
    
    Data: lt_response        LIKE TABLE OF struct_response,
          ls_clause_DocTyp   LIKE LINE  OF et_expanded_tech_clauses,
          ls_clause_PurchGrp LIKE LINE  OF et_expanded_tech_clauses,
          ls_clause_Vendor   LIKE LINE  OF et_expanded_tech_clauses.
    
    
    * Step-02: Call RFC of backend system
    CALL FUNCTION '<RfcName>' DESTINATION  '<Rfc Destinations name conencting to back-end system>'
      TABLES
        GT_DocTyp   = lt_DocTyp
        GT_VEN      = lt_Vendor
        GT_PurGrp   = lt_PurGrp.
    
    
    * Step-03: Return internal output tables to Odata Service Response
    * Document Type List
    LOOP AT lt_DocTyp INTO ls_DocTyp.
     APPEND ls_DocTyp TO struct_response-NAVDOCTYP.
     Clear ls_DocTyp.
    ENDLOOP.
    
    * Vendor List
    LOOP AT lt_Vendor INTO ls_Vendor.
     APPEND ls_Vendor TO struct_response-NAVVENDOR.
     Clear ls_Vendor.
    ENDLOOP.
    
    * Purchase Group List
    LOOP AT lt_PurGrp INTO ls_PurGrp.
     APPEND ls_PurGrp TO struct_response-NAVPURCHGRP.
    ENDLOOP.
    
    
    *Step-04: Assign the Navigation Proprties to Expanded Tech clauses
      ls_clause_DocTyp     = 'NAVDOCTYP'.
      APPEND ls_clause_DocTyp   TO et_expanded_tech_clauses.
      clear ls_clause_DocTyp.
    
      ls_clause_PurchGrp   = 'NAVPURCHGRP'.
      APPEND ls_clause_PurchGrp TO et_expanded_tech_clauses.
      clear ls_clause_PurchGrp.
    
      ls_clause_Vendor     = 'NAVVENDOR'.
      APPEND ls_clause_Vendor   TO et_expanded_tech_clauses.
      clear ls_clause_Vendor.
    
    
    *Step-05: Append Deep Strcture Values to Final Internal Table
     APPEND struct_response TO lt_response.
     clear struct_response.
    
    
    *Step-06: Send back Response to XML output
      copy_data_to_ref(
        EXPORTING
          is_data = lt_response
        CHANGING
          cr_data = er_entityset ).
    
    
    ENDCASE.
    
      endmethod.
  • and finally save and activate.
——–Begin of content-addition[Date 08-Jul-2019]: Case => To depcit how input parameters can be passed in ODataService-example ———-
  • Suppose, SAP-ECC’s RFC requires some input parameter, then same we can passed through ODataService in url pattern.
  • Create respective Fields in ODataservice entity, for example ‘field1’ and ‘field2’.
  • Note: Here, ODataService will support ‘GET’ method, we are passing input in url pattern and same we will receive in ABAP-Workbench of ODataService implementation and then it will be passed to RFC call function.
  • ODataService url will be like as follows, where two input parameters are passed ‘field1’ and ‘field2’:
    /sap/opu/odata/sap/ZTEST_ODATA_SRV/InputHelpSet?$filter=(field1 eq ‘Val123’ and field2 eq ‘val456’) &$expand=NAVDOCTYP,NAVPURCHGRP,NAVVENDOR
  • Invoke this service using ‘GET’ operation
    Next capture input from ODataService Url pattern and pass it to RFC as shown in below code.
  • * Step-01.01   :   Variables for ODataservice's URL-pattern's Input Parameters
    Data: lt_filter_select_options  TYPE          /iwbep/t_mgw_select_option,
          ls_filter                 TYPE          /iwbep/s_mgw_select_option,
          ls_filter_range           TYPE          /iwbep/s_cod_select_option,
          lv_inputx                 TYPE          C LENGTH 4,  "Type as in RFC
          lv_inputy               	TYPE          C LENGTH 4,  "Type as in RFC
       
    * Step-01.02   :   Get Input Parameters from OData Request Message
    * ODataService url is as
    * /sap/opu/odata/sap/ZTEST_ODATA_SRV/InputHelpSet?$filter=(field1 eq 'Val123' and field2 eq 'val456') &$expand=NAVDOCTYP,NAVPURCHGRP,NAVVENDOR
    * Here, we read input of 'field1' and 'field2'
    LOOP AT it_filter_select_options INTO ls_filter.
      LOOP AT ls_filter-select_options INTO ls_filter_range.
        TRANSLATE ls_filter-property TO UPPER CASE.
         CASE ls_filter-property.
           WHEN 'FIELD1'.
             lv_inputx = ls_filter_range-low.
    
           WHEN 'FIELD2'.
             lv_inputy = ls_filter_range-low.
    
           WHEN OTHERS.
             " Log message in the application log
             me->/iwbep/if_sb_dpc_comm_services~log_message(
           EXPORTING
             iv_msg_type   = 'E'
             iv_msg_id     = '/IWBEP/MC_SB_DPC_ADM'
             iv_msg_number = 020
             iv_msg_v1     = ls_filter-property ).
             " Raise Exception
             RAISE EXCEPTION TYPE /iwbep/cx_mgw_tech_exception
             EXPORTING
               textid = /iwbep/cx_mgw_tech_exception=>internal_error.
         ENDCASE.
      ENDLOOP.
    ENDLOOP.
    	
    * Step-02: Call RFC of backend system
    CALL FUNCTION '<RfcName>' DESTINATION  '<Rfc Destinations name conencting to back-end system>'
       EXPORTING              "While RFC call, input as Exporting parameters
        IV_inputx   = lv_inputx
        IV_inputy   = lv_inputy
      TABLES
        GT_DocTyp   = lt_DocTyp
        GT_VEN      = lt_Vendor
        GT_PurGrp   = lt_PurGrp.
——–End of content-addition[Date 08-Jul-2019]: Case => To depict how input parameters can be passed in ODataService-example ————

 

 

Testing the oData Service:

[1] Testing in Fiori-Server using t-code ‘/n/iwfnd/gw_client’:

  • To test above oData Service, go to t-code ‘/n/iwfnd/gw_client’ and provide the url.
  • Expanded URL pattern is as follows with which this oDataService is to be called:
  • /sap/opu/odata/sap/ZTEST_ODATA_SRV/InputHelpSet?$filter=(field1 eq ”) &$expand=NAVDOCTYP,NAVPURCHGRP,NAVVENDOR
    • here we call odataService using main EntitySet ‘InputHelpSet’
    • and we pass blank ‘field1’ input of main EntitySet ‘InputHelpSet’
    • and we used refer navigation names in which output tables are mapped
    • Here, We are passing blank value for property ‘field1’ of main EntitySet (InputHelpSet), this is required, because this is the ‘Principal Property’ which is linked with at least one ‘Dependent Property’ in three Associations of three EntitySets (DocTypSet, PurchGrpSet, VendorListSet) with Main EntitySet (InputHelpSet)
  • select ‘GET’ method, here no separate input required as a HTTP request.
  • In URL pattern we can send inputs
  • Click on ‘Execute’
  • Following output xml found, which has all three table output in respective separate EntitySet structure
  • <feed xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xml:base="http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/"><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/InputHelpSet</id><title type="text">InputHelpSet</title><updated>2018-04-04T14:38:55Z</updated><author><name/></author><link href="InputHelpSet" rel="self" title="InputHelpSet"/><entry><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/InputHelpSet('')</id><title type="text">InputHelpSet('')</title><updated>2018-04-04T14:38:55Z</updated><category term="ZTEST_ODATA_SRV.InputHelp" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/><link href="InputHelpSet('')" rel="self" title="InputHelp"/><link href="InputHelpSet('')/NAVDOCTYP" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/NAVDOCTYP" type="application/atom+xml;type=feed" title="NAVDOCTYP"><m:inline><feed xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xml:base="http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/"><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/InputHelpSet('')/NAVDOCTYP</id><title type="text">DocTypeSet</title><updated>2018-04-04T14:38:55Z</updated><author><name/></author><link href="InputHelpSet('')/NAVDOCTYP" rel="self" title="DocTypeSet"/><entry><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/DocTypeSet('TP')</id><title type="text">DocTypeSet('TP')</title><updated>2018-04-04T14:38:55Z</updated><category term="ZTEST_ODATA_SRV.DocType" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/><link href="DocTypeSet('TP')" rel="self" title="DocType"/><content type="application/xml"><m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"><d:von>TP</d:von><d:bis>STO MM route</d:bis></m:properties></content></entry><entry><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/DocTypeSet('EUB')</id><title type="text">DocTypeSet('EUB')</title><updated>2018-04-04T14:38:55Z</updated><category term="ZTEST_ODATA_SRV.DocType" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/><link href="DocTypeSet('EUB')" rel="self" title="DocType"/><content type="application/xml"><m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"><d:von>EUB</d:von><d:bis>DFPS Int. Ord. Type</d:bis></m:properties></content></entry><entry><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/DocTypeSet('ZJ2')</id><title type="text">DocTypeSet('ZJ2')</title><updated>2018-04-04T14:38:55Z</updated><category term="ZTEST_ODATA_SRV.DocType" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/><link href="DocTypeSet('ZJ2')" rel="self" title="DocType"/><content type="application/xml"><m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"><d:von>ZJ2</d:von><d:bis>Stock transport ord.</d:bis></m:properties></content></entry></feed></m:inline></link><link href="InputHelpSet('')/NAVVENDOR" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/NAVVENDOR" type="application/atom+xml;type=feed" title="NAVVENDOR"><m:inline><feed xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xml:base="http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/"><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/InputHelpSet('')/NAVVENDOR</id><title type="text">VendorListSet</title><updated>2018-04-04T14:38:55Z</updated><author><name/></author><link href="InputHelpSet('')/NAVVENDOR" rel="self" title="VendorListSet"/><entry><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/VendorListSet('V01')</id><title type="text">VendorListSet('V01')</title><updated>2018-04-04T14:38:55Z</updated><category term="ZTEST_ODATA_SRV.VendorList" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/><link href="VendorListSet('V01')" rel="self" title="VendorList"/><content type="application/xml"><m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"><d:LIFNR>V01</d:LIFNR><d:NAME>NOVODIGM Ltd</d:NAME></m:properties></content></entry><entry><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/VendorListSet('V02')</id><title type="text">VendorListSet('V02')</title><updated>2018-04-04T14:38:55Z</updated><category term="ZTEST_ODATA_SRV.VendorList" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/><link href="VendorListSet('V02')" rel="self" title="VendorList"/><content type="application/xml"><m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"><d:LIFNR>V02</d:LIFNR><d:NAME>Ambrisha Ltd</d:NAME></m:properties></content></entry><entry><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/VendorListSet('V03')</id><title type="text">VendorListSet('V03')</title><updated>2018-04-04T14:38:55Z</updated><category term="ZTEST_ODATA_SRV.VendorList" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/><link href="VendorListSet('V03')" rel="self" title="VendorList"/><content type="application/xml"><m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"><d:LIFNR>V03</d:LIFNR><d:NAME>Ghankyou Pv.t Ltd</d:NAME></m:properties></content></entry></feed></m:inline></link><link href="InputHelpSet('')/NAVPURCHGRP" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/NAVPURCHGRP" type="application/atom+xml;type=feed" title="NAVPURCHGRP"><m:inline><feed xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xml:base="http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/"><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/InputHelpSet('')/NAVPURCHGRP</id><title type="text">PurchGrpSet</title><updated>2018-04-04T14:38:55Z</updated><author><name/></author><link href="InputHelpSet('')/NAVPURCHGRP" rel="self" title="PurchGrpSet"/><entry><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/PurchGrpSet('D11')</id><title type="text">PurchGrpSet('D11')</title><updated>2018-04-04T14:38:55Z</updated><category term="ZTEST_ODATA_SRV.PurchGrp" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/><link href="PurchGrpSet('D11')" rel="self" title="PurchGrp"/><content type="application/xml"><m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"><d:EKGRP>D11</d:EKGRP><d:EKNAM>DB -QC SER REG</d:EKNAM></m:properties></content></entry><entry><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/PurchGrpSet('H45')</id><title type="text">PurchGrpSet('H45')</title><updated>2018-04-04T14:38:55Z</updated><category term="ZTEST_ODATA_SRV.PurchGrp" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/><link href="PurchGrpSet('H45')" rel="self" title="PurchGrp"/><content type="application/xml"><m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"><d:EKGRP>H45</d:EKGRP><d:EKNAM>HO Distribution</d:EKNAM></m:properties></content></entry><entry><id>http://fiori:8000/sap/opu/odata/sap/ZTEST_ODATA_SRV/PurchGrpSet('T06')</id><title type="text">PurchGrpSet('T06')</title><updated>2018-04-04T14:38:55Z</updated><category term="ZTEST_ODATA_SRV.PurchGrp" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/><link href="PurchGrpSet('T06')" rel="self" title="PurchGrp"/><content type="application/xml"><m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"><d:EKGRP>T06</d:EKGRP><d:EKNAM>TRP -QC CONS</d:EKNAM></m:properties></content></entry></feed></m:inline></link><content type="application/xml"><m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"><d:field1></d:field1></m:properties></content></entry></feed>

 

Debugging the oData Service:

[1.1] Debugging-oData service to understand call is processed and output is flowing:

  • Lets debug the oData Service
    • To understand the oData Service’s call processing
    • To know in runtime, how RFC is been called
    • and how its table output is been returned as a odataService response in different enttySet
  • Inside method ‘GET_EXPANDED_ENTITYSET’, set external break point when main EntitySet ‘InputHelpSet’ is been called with url
    • /sap/opu/odata/sap/ZTEST_ODATA_SRV/InputHelpSet?$filter=(field1 eq ”) &$expand=NAVDOCTYP,NAVPURCHGRP,NAVVENDOR
  • Trigger odata service from t-code ‘/n/iwfnd/gw_client’
  • on service trigger breakpoints  invoked, code processing enters inside EntitySet ‘InputHelpSet’
  • Next RFC call happens, in result three output is been received from RFC
  • 1st table ‘LT_DOCTYP’ which is Document Type List records
  • 2nd table ‘LT_Vendor’ which is Vendor List records
  • 3rd table ‘LT_PURGRP’ which is Purchase Group records
  • Next all three output tables been mapped to common oData Service’s structure ‘LT_RESPONSE’
  • Records of ‘Document Type’ using navigation reference ‘NAVDOCTYP’
  • Records of ‘Purchase Group’ using navigation reference ‘NAVPURCHGRP’
  • Records of ‘Vendor List’ using navigation reference ‘NAVVENDOR’
  • next complete the debug execution.

 

 

Consume above oData Service in Fiori app (inside Eclipse):

Assigned Tags

      34 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Michelle Crapo
      Michelle Crapo

      Woohoo! Another timely one for me. I'll be doing something similar soon.

      Michelle

      Author's profile photo Alejandra Ardilla
      Alejandra Ardilla

      Hello,

       

      very good blog. It's been very useful 🙂

      I have one question: If we have more than one input field, would we have to add manually the filtering option in the /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET code?

      In my case, I have 4 input fields and I don't know if I have to add some extra code.

      Thank you very much.

       

      Regards,

       

      Alejandra

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Dear  Alejandra Ardila,

      For four input fields, you need to do below things in Entity ‘InputHelp

      • Create four property for example: field1, field3, field3, field4
      • OData service URI pattern to send input in these fields will be like as below:
        • /sap/opu/odata/sap/ZTEST_ODATA_SRV/InputHelpSet?$filter=(field1 eq ‘val1’ and field2 eq ‘val’  and field3 eq ‘val’  and field4 eq ‘val’ ) &$expand=NAVDOCTYP,NAVPURCHGRP,NAVVENDOR
      • And in method ‘GET_EXPANDED_ENTITYSET’, you need to read each property’s input as below:
        • Data: lt_filter_select_options  TYPE          /iwbep/t_mgw_select_option,
                ls_filter                 TYPE          /iwbep/s_mgw_select_option,
                ls_filter_range           TYPE          /iwbep/s_cod_select_option,
                lv_field1                 TYPE          STRING,     
                lv_field2                 TYPE          STRING,
                lv_field3                 TYPE          STRING,
                lv_field4                 TYPE          STRING.
          
          * Get Input Parameters from OData Request Message
          LOOP AT it_filter_select_options INTO ls_filter.
            LOOP AT ls_filter-select_options INTO ls_filter_range.
              TRANSLATE ls_filter-property TO UPPER CASE.
               CASE ls_filter-property.
          
                 WHEN 'FIELD1'.
                   lv_field1 = ls_filter_range-low.
          
                 WHEN 'FIELD2'.
                   lv_field2 = ls_filter_range-low.
          
                 WHEN 'FIELD3'.
                   lv_field3 = ls_filter_range-low.
          
                 WHEN 'FIELD4'.
                   lv_field4 = ls_filter_range-low.
          
                 WHEN OTHERS.
                   " Log message in the application log
                   me->/iwbep/if_sb_dpc_comm_services~log_message(
                 EXPORTING
                   iv_msg_type   = 'E'
                   iv_msg_id     = '/IWBEP/MC_SB_DPC_ADM'
                   iv_msg_number = 020
                   iv_msg_v1     = ls_filter-property ).
                   " Raise Exception
                   RAISE EXCEPTION TYPE /iwbep/cx_mgw_tech_exception
                   EXPORTING
                     textid = /iwbep/cx_mgw_tech_exception=>internal_error.
               ENDCASE.
            ENDLOOP.
          ENDLOOP.
          
          
          
      • Now you have input in variables ‘lv_field1′, lv_field2’, ‘lv_field3’ , ‘lv_field4’, which you can use in your case.
      • Hope above will help you.

       

      Thanks & Regards,

      Dilip

       

      Author's profile photo Alejandra Ardilla
      Alejandra Ardilla

      Dear Dilip,

      thank you very much,  it worked fine for me 🙂

      Author's profile photo Sophie Li
      Sophie Li

      Dear Dilip,

      If the input is table data  as filter set, but the URI has the length limitation in the characters, how should we proceed in this case

      For  example,

      we need to filter the fied1 field2 feild3 feild4 with more than 20 values combination groups as follows,

      V11 V21 V31 V41 ; V12 V22 V32 V42 ;V13 V23 V33 V43 ; V14 V24 V34 V44 ;

      V15 V25 V35 V45 ; V16 V26 V36 V46 ;V17 V27 V37 V47 ; V18 V28 V38 V48 ;........

      If we use the get method similar like this, we have limitation on URI length

      • /sap/opu/odata/sap/ZTEST_ODATA_SRV/InputHelpSet?$filter=(field1 eq ‘val11’ and field2 eq ‘val21’  and field3 eq ‘val31’  and field4 eq ‘val41’ )&$filter=(field1 eq ‘val12’ and field2 eq ‘val22’  and field3 eq ‘val32’  and field4 eq ‘val42’ ) &$filter=(field1 eq ‘val13’ and field2 eq ‘val23’  and field3 eq ‘val33’  and field4 eq ‘val43’ ) ......

      Thanks and regards,

      Sophie

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Dear Sophie,

      URI lenght limitiation may be there while accessing Odata service from SAP-Fiori t-code '/n/iwfnd/gw_client',

      but from SAP-Fiori-App's controller file (in JavaScript), there is no such limitation.

      Please check and let me know because this concept too is new for me using such big URI length.

       

      Thanks & Regards,

      Dilip

      Author's profile photo Mauricio Pinheiro Predolim
      Mauricio Pinheiro Predolim

      Great tips Dilip! Thanks a lot!

      I have a doubt about using Multiple Table Outputs:

      Using your example  i have 3 different content tables for example: 2018, 2017 and 2016 that i'm filling in calling an RFC with same fields.

      I can't see the tables output in OData service payload. Is that a reason for it? In the debug it's ok.

      Best Regards.

      Mauricio.

       

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Mauricio Pinheiro Predolim,

      In your case:

      • 3 tables with same fields in RFC...thats ok
      • In oDataService, parallel three structure should be present
      • and one more EntitySet which will be used in  'association/navigation' to achieve multiple output results.
      • Using correct navigation URL pattern only multiple entities can be referred in output

      If you are getting results in debug, but not reflecting same in oDataService, then please re-verify association/Navigation and use proper URL pattern while calling service. Your case in very much similar to above blog.

       

      Thanks & Regards,

      Dilip

      Author's profile photo Mauricio Pinheiro Predolim
      Mauricio Pinheiro Predolim

      Hi Dilip!

      I double-checked my oDataService and now it's working!

      Thanks and regards.

      Mauricio.

       

       

      Author's profile photo KarthiK R
      KarthiK R

      Hi Dilip,

      This is an excellent blog. I followed the steps what you mentioned above for my current scenario. I created an UserInfoset similar to your InputHelpSet and created association with 2 of my output internal tables. I completed the coding in the method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET.

      When I test my service I get the following error.

      Resource not found for the segment:(NAVIGATION NAME)

      Can you please tell me if I miss anything here?

      Thanks,

      Karthik

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Karthikeyan,

      You please re-check below:

      • Navigation and association
      • coding in the method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_EXPANDED_ENTITYSET
      • and url pattern while testing
      • check T-Code "/n/iwfnd/error_log" for more details

       

      Thanks & Regards,

      Dilip

      Author's profile photo KarthiK R
      KarthiK R

      Thanks Dilip. I have made a mistake and now it is working fine.

      Author's profile photo Rashmi Joshi
      Rashmi Joshi

      Hi Dilip,

      This is an excellent blog and very well explained. Thanks for this.

      Author's profile photo Venkata Angara
      Venkata Angara

      Hi Dileep,

      Thanks for sharing. I have a question on this. I tried replicating this scenario and it is still calling the old Create_Entity default method and hence returning a structure format instead of a deep structure format. Does this scenario work only for multiple records using $batch scenario or can it be used for a single record as well?

       

      Thanks,

      Pavan

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Venkata,

      You please re-check your scenario w.r.t. steps given in this blog.

      For your information, we use below re-definition techniques w.r.t. B.Requirement:

      1. Multiple Table input (Header/Item) => CREATE_DEEP_Entity
      2. Multiple Table Output  => GET_Expanded_EntitySet
      3. Single Table Output/Input => GET_EnitySet

      Please refer below link for more clarity:

      https://blogs.sap.com/2018/04/10/sap-fiori-odata-service-examples/

       

      Thanks & Regards,

      Dilip

       

      Author's profile photo Syed Omer Hussain
      Syed Omer Hussain

      Hi Dilip,

      Nice Blog. I do have a question , i tried implementing the above scenario and i am able to get the data in "lt_response"  when i debug but when the debug is finished am getting the below error. What exactly did is miss ?

      Thanks & Regards.

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Syed,

      Your Navigation/association link seems to be im-proper, please cross check again.

      Because it will should invoke/deal Expanded_EntitySet methods only instead of GET_Entity.

      And in url, use small brackets

      /HeaderReqSet?$filter=(RBUKKRS eq '1000' and BELNR eq '100000034') &$expand=NAVDocOutput

       

      thanks & regards,

      Dilip

      Author's profile photo David Fryda
      David Fryda

      Hi.

      It worked for me at first time! Thank you.

      I have a little question. Lets say you just want to execute the NAVDOCTYP navigation.

      I get the doctype table data in return in my xml. But the function is executed and returns all the tables like lt_vendor and lt_purgrp. So there is no gain of performance.

      Best Regards.

       

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi David,

      Sorry for very late interaction, till now, you may have already addressed the requirement

      Yes, Function will return all tables for which its been programmed.

      Thanks & Regards,

      Dilip

      Author's profile photo David Fryda
      David Fryda

      Hi Dilip,

       

      Thanks anyway. It is always good to have another confirmation.

       

      Best Regards.

      Author's profile photo Tata Manikanta Subrahmanyam Gupta
      Tata Manikanta Subrahmanyam Gupta

      Hi Dilip Kumar Krishnadev Pandey

      I have tried as per the above, but i am uable to debug the oData Service with External Break point even though i am using the same user id in Fiori frontend and ECC Backend.

       

      Can u please suggest me how to debug in S/4 Hana 1909 version with external Break Point

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Tata M. S. G.,

      Sorry for very late interaction, till now, you may have already addressed the requirement.

      You should have same debug procedure in S/4 Hana too, till now, I haven’t got the chance to work on S/4 Hana, so, can’t comment anything specific.

      Thanks & Regards,

      Dilip

      Author's profile photo Saurabh Tiwari
      Saurabh Tiwari

      Very well explained.

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      धन्यवाद तिवारी जी

      Author's profile photo Deepak Asoda
      Deepak Asoda

      Hey Dilip,

      Thank you very much for a good blog, very well explained for beginners and who want to understand conceptually .

       

      Regards,

      Deepak

       

      Author's profile photo Juan Camilo Martinez Arias
      Juan Camilo Martinez Arias

      Hi Dilip

       i have a trouble,  when i put a breakpoint of session only stops in the method inputhelpset_get_entityset, never stops in the method GET_EXPANDED_ENTITYSET.

       i checked my associations and looks good.

       

      Im usign this URL /sap/opu/odata/sap/*********/InputHelpSet?$filter=((Plfaz ge datetime'2019-04-01T12:00' and Plfaz le datetime'2019-04-29T12:00') and (Plsez ge datetime'2019-06-01T12:00' and Plsez le datetime'2019-06-30T12:00'))&$expand=NAVDATACONJUNTO,NAVDATAINDIVIDUAL

      and this is the error when i use the claused "expand"

      PSDT: I redefine the method inputhelpset_get_entityset too and i tried to set my two output tables on  the parameter ET_ENTITYSET of the same method

       

      Can you help me ?

      Thanks & Regards.

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Juan,

      Sorry for very late reply. By now, you may would have already addressed the issue.

      • However, inside ‘GET_Expanded_EntitySet’, just recheck CASE…WHEN ‘<custEntitySetName>’ where  <custEntitySetName> is caseSensitive in nature it should be same as of EntitySet visible in SEGW
      • and try to set the external debug at line WHEN (for example at line 4 in this blog case). Here, if EntitySet is wrongly referred, then atleast debug will come at this line

      Thanks & Regards,

      Dilip P.

      Author's profile photo Venkat Challa
      Venkat Challa

      Hi Dilip,

      I am trying to find a solution for the below issue.

      Input1 -> A structure with 2 or 3 columns.

       Input2 -> Table with 4 columns and about 30 rows.

      Based on the Input1 request, and the entries in the input table, I get the result back in a table.

      Output -> Table with 5 columns and about 10 to 20 rows.

      My question is how do I pass my input table? I am not sure how to solve this.

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Venkat,

      Sorry for late reply, You can refer below blog link, if, in case, you havn't yet addressed your requirement

      SAP oData Service [POST]: Multiple Table Input | SAP Blogs

      FYI, below is other oData examples too:

      SAP (Fiori) OData Service Examples | SAP Blogs

       

      Thanks & Regards,

      Dilip

      Author's profile photo Venkat Challa
      Venkat Challa

      Thanks Dilip. This is really a nice blog. I was able to get the solution. But this confirms that I am in the right path..

       

      Author's profile photo David Coiro
      David Coiro

      Hi Dilip.

      Thank you so much for this tutorial. It helps me a lot for one of my requirement.

      It works perfect :).

      Best regards

      David.

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Good to hear, David !!...keep learning, stay safe

      Author's profile photo Till Settelmeier
      Till Settelmeier

      Hello,

       

      Really Good Stuff. Thank you.

      Suppose if I want like in the display then how I have to change the code.

      Header, Internal Table1-Row1, Internal Table2-Row1, Internal Table1-Row2, Internal Table2-Row2,.............., Internal Table3.

       

      And also how the order of the internal Tables are changed ? means can I display Internal Table 1 at 3rd position?

      Author's profile photo Dilip Kumar Krishnadev Pandey
      Dilip Kumar Krishnadev Pandey
      Blog Post Author

      Hi Till Settelmeier,

      Sorry for late reply.

      Internal-Table's order doesn't matter, you can make use of any internal-table in GUI.

       

      Thanks & Regards

      Dilip Pandey