Quantcast
Channel: SCN : All Content - SAP Gateway
Viewing all articles
Browse latest Browse all 2823

Let's code association/navigation and data provider expand in OData service!

$
0
0

 

Introduction

 

In my earlier blog Let’s code CRUDQ and Function Import operations in OData service! we understood the basic operation performed in OData service.


In this blog I will explain creation of simple SAP Gateway OData service having association and navigation between entities. Also we will see how to implement it through code based approach and finally conclude with implantation of GET_EXPANDED_ENTITYSET and GET_EXPANDED_ENTITY

invoked by $expand.

 

Note - Steps mentioned in this blog are performed in SAP Gateway System SP08 (Embedded Architecture)

 

Let’s see what is meant by association and navigation property.

 

Associationsdefine the relationship between two or more Entity Types (for example, Employee WorksFor Department). Instances of associations are grouped inAssociation Sets.

Navigation Propertiesare special properties on Entity Types which are bound to a specific association and can be used to refer to associations of an entity.

Finally, all instance containers (Entity Sets and Association Sets) are grouped in anEntity Container.

 

Reference - Overview | Open Data Protocol

 

Also let's understand the difference between association/navigation and $expand. In short, it is as below,

 

Association/NavigationGive me associated (dependent) entity/entities using Navigation propertyhttp://services.odata.org/OData/OData.svc/Categories(1)/Products?$format=json
$expand

Give me associated (dependent) entity/entities + Principal entity/entities

using Navigation property

http://services.odata.org/OData/OData.svc/Categories(1)?$expand=Products&$format=json

 

you can also refer this nice blog Implementing  Expand Entity/Entity Set by Srikanth Gajula

 

Scenario

 

We will read Sales order, items and product data from Enterprise Procurement Model (EPM). This is the pictorial representation of sales order, items and product with their association.

 

dpe.jpg

We will have 3 entities as displayed in below EDM diagram.

dpe1.jpg

SalesOrder will be associated with SalesOrderItem and SalesOrderItem with Product.

 

Principle EntityDependent EntityNavigation PropertyCardinality
SalesOrderSalesOrderItemOrderToItems1:N
SalesOrderItemProductItemToProduct1:1

 

We will use below BAPIs to get the Sales Order, Items and Product data in DPC_EXT class methods.

  • BAPI_EPM_SO_GET_LIST
  • BAPI_EPM_SO_GET_DETAIL
  • BAPI_EPM_PRODUCT_GET_DETAIL

 

We will code for association/navigation and data provider expand scenario and will also understand the framework expand.

 

Before that just look at difference between Data provider expand and framework expand

 

Framework Expand Data Provider Expand
Formerly called as generic expand Formerly called as basic expand
Requires no implementation effortRequires implementation effort
As this is handled by framework, same logic may be called multiple times in loop resulting in poor performance In some cases, this provides better performance depending on how the code is implemented

 

Reference - Expand in Framework and Data Provider - SAP NetWeaver Gateway - SAP Library

 

Procedure


Create entity SalesOrder by importing DDIC structure as shown below. Please note that Entity set will be created by default if the check box “Create Default Entity Set” is checked.

 

dpe2.jpg

Repeat the process for entities SalesOrderItem and Product. End result will be as displayed below.

dpe3.jpg

Now let’s create association, navigation etc. By using Create Association wizard, it is just 3 steps as displayed below. This will create Navigation property, Association set etc.

 

Create association between entities SalesOrder and SalesOrderItem with navigation property as OrderToItems.

dpe4.jpg

On similar lines, create association between entities SalesOrderItem and Product with navigation property as ItemToProduct.

dpe5.jpg

Please note that we do not have referential constraints created between SalesOrderItem and Product.

 

The final OData modeling will look like as below,

dpe6.jpg

 

Coding

 

In this section, we will redefine methods in DPC_EXT class. Please note that code provided in this blog is in simplest form. You may need to consider proper error handling and other best practices while writing the code.

 

Association/Navigation

 

First we will implement logic in method SALESORDERSET_GET_ENTITYSET by redefining it.

 

We will use below execution URI in Gateway Client (Transaction /IWFND/GW_CLIENT) to check the response payload.

 

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet

METHOD salesorderset_get_entityset.

 

  DATA: lt_salesorder TYPETABLEOF bapi_epm_so_header,

         ls_salesorder LIKELINEOF lt_salesorder,

         ls_entity   LIKELINEOF et_entityset,

         l_max_rows TYPE bapi_epm_max_rows.

 

  l_max_rows-bapimaxrow = '10'.

 

  CALLFUNCTION'BAPI_EPM_SO_GET_LIST'

    EXPORTING

      max_rows    = l_max_rows

    TABLES

      soheaderdata = lt_salesorder.

 

*Fill ET_ENTITYSET

  LOOPAT lt_salesorder INTO  ls_salesorder .

    MOVE-CORRESPONDING ls_salesorder TO ls_entity.

    APPEND ls_entity TO et_entityset.

  ENDLOOP.

ENDMETHOD.

 

Redefine method SALESORDERSET_GET_ENTITY as below and then execute with below URI

 

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000009')

METHOD salesorderset_get_entity.

 

  DATA: ls_salesorder TYPE bapi_epm_so_header,

        ls_key_tab    TYPE /iwbep/s_mgw_name_value_pair,

        lv_soid       TYPE bapi_epm_so_id.

 

*Get the key property values

  READTABLE it_key_tab WITHKEY name = 'SoId'INTO ls_key_tab.

 

  lv_soid = ls_key_tab-value.

 

  CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

    EXPORTING

      input = lv_soid

    IMPORTING

      output = lv_soid.

 

  CALLFUNCTION'BAPI_EPM_SO_GET_DETAIL'

    EXPORTING

      so_id     = lv_soid

    IMPORTING

      headerdata = ls_salesorder.

 

*Fill ER_ENTITY

  MOVE-CORRESPONDING ls_salesorder TO er_entity.

 

ENDMETHOD.

 

Redefine method SALESORDERITEMSE_GET_ENTITYSET as below with URI

 

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000008')/OrderToItems

METHOD salesorderitemse_get_entityset.

  DATA: ls_salesorder TYPE bapi_epm_so_header,

        lt_itemdata   TYPETABLEOF bapi_epm_so_item,

        ls_itemdata   TYPE  bapi_epm_so_item,

        ls_entity     LIKELINEOF et_entityset.

 

  DATA:  ls_key_tab  TYPE /iwbep/s_mgw_name_value_pair,

          lv_soid    TYPE bapi_epm_so_id.

 

*Get the key property values

  READTABLE it_key_tab WITHKEY name = 'SoId'INTO ls_key_tab.

 

  lv_soid = ls_key_tab-value.

 

  CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

    EXPORTING

      input = lv_soid

    IMPORTING

      output = lv_soid.

 

  CALLFUNCTION'BAPI_EPM_SO_GET_DETAIL'

    EXPORTING

      so_id     = lv_soid

    IMPORTING

      headerdata = ls_salesorder

    TABLES

      itemdata  = lt_itemdata.

 

 

  LOOPAT lt_itemdata INTO ls_itemdata.

    MOVE-CORRESPONDING ls_itemdata TO ls_entity  .

    APPEND ls_entity  TO et_entityset.

  ENDLOOP.

 

ENDMETHOD.

 

Notice that we used navigation property OrderToItems to get the associated entities.

 

Framework expand

 

By executing below URI, it will call framework expand by default.

 

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet?$expand=OrderToItems

 

This calls method SALESORDERSET_GET_ENTITYSET and SALESORDERITEMSE_GET_ENTITYSET in loop.

 

Check the values in header name sapgw-statistics for URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet?$expand=OrderToItems&sap-statistics=true

 

This will give you performance statistics for OData request. For more information, refer Some new features in SAP NW Gateway 2.0 SP08

dpe7.jpg

 

If we execute URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000009')?$expand=OrderToItems

 

It will call method SALESORDERSET_GET_ENTITY and SALESORDERITEMSE_GET_ENTITYSET.

 

For below URI to work

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000000')/OrderToItems(SoId='0500000000',SoItemPos='0000000010')

We need to implement logic with navigation property keys.

 

Alternatively we can read as /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderItemSet(SoId='0500000000',SoItemPos='0000000010')

 

Let’s implement SALESORDERITEMSE_GET_ENTITY so that we can read data for above URI as

METHOD salesorderitemse_get_entity.

  DATA: ls_salesorder TYPE bapi_epm_so_header.

 

  DATA:  ls_key_tab   TYPE /iwbep/s_mgw_name_value_pair,

          lv_soid  TYPE bapi_epm_so_id,

          lv_soitempos TYPE snwd_so_item_pos,

          lt_itemdata TYPETABLEOF bapi_epm_so_item,

         ls_itemdata TYPE  bapi_epm_so_item.

 

*Get the key property values

  READTABLE it_key_tab WITHKEY name = 'SoId'INTO ls_key_tab.

  lv_soid = ls_key_tab-value.

 

  READTABLE it_key_tab WITHKEY name = 'SoItemPos'INTO ls_key_tab.

  lv_soitempos = ls_key_tab-value.

 

  CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

    EXPORTING

      input = lv_soid

    IMPORTING

      output = lv_soid.

 

 

  CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

    EXPORTING

      input = lv_soitempos

    IMPORTING

      output = lv_soitempos.

 

*Get data from BAPI

 

  CALLFUNCTION'BAPI_EPM_SO_GET_DETAIL'

    EXPORTING

      so_id     = lv_soid

    IMPORTING

      headerdata = ls_salesorder

    TABLES

      itemdata  = lt_itemdata.

 

 

  READTABLE  lt_itemdata INTO  ls_itemdata WITHKEY so_id = lv_soid

                                                      so_item_pos = lv_soitempos.

  IF sy-subrc = 0.

    MOVE-CORRESPONDING ls_itemdata TO er_entity.

  ENDIF.

ENDMETHOD.

 

Use of Navigation Path to read navigation keys

 

To read the data for below URI, we need to implement logic as below in method PRODUCTSET_GET_ENTITY

 

Execution URI - /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000001')/OrderToItems(SoId='500000001',SoItemPos='0000000010')/ItemToProduct

METHOD productset_get_entity.

  DATA: ls_salesorder TYPE bapi_epm_so_header.

 

 

  DATA:  ls_key_tab   TYPE /iwbep/s_mgw_name_value_pair,

         lv_soid  TYPE bapi_epm_so_id,

         lv_soitempos TYPE snwd_so_item_pos,

         lt_itemdata TYPETABLEOF bapi_epm_so_item,

         ls_itemdata TYPE  bapi_epm_so_item.

 

  DATA: ls_navigation    TYPE /iwbep/s_mgw_navigation_path,

        lv_property                 TYPE string.

 

  DATA: lv_product_id TYPE bapi_epm_product_id,

        lv_product_header TYPE bapi_epm_product_header.

 

  IF iv_source_name = iv_entity_name.

 

*Get the key property values

    READTABLE it_key_tab WITHKEY name = 'ProductId'INTO ls_key_tab.

 

    IF sy-subrc = 0.

* MOVE-CORRESPONDING ls_itemdata to er_entity.

      lv_product_id = ls_key_tab-value.

 

      CALLFUNCTION'BAPI_EPM_PRODUCT_GET_DETAIL'

        EXPORTING

          product_id = lv_product_id

        IMPORTING

          headerdata = lv_product_header.

 

      MOVE-CORRESPONDING lv_product_header TO er_entity.

 

    ENDIF.

 

  ELSE.

 

    IF it_navigation_path ISNOTINITIAL.

      READTABLE it_navigation_path INTO ls_navigation INDEX1.

      IF sy-subrc EQ0.

        CASE ls_navigation-nav_prop.

          WHEN'OrderToItems'.

            LOOPAT ls_navigation-key_tab INTO ls_key_tab.

              CASE ls_key_tab-name.

                WHEN'SoId'.

                  lv_soid = ls_key_tab-value.

                WHEN'SoItemPos'.

                  lv_soitempos = ls_key_tab-value.

                WHENOTHERS.

 

              ENDCASE.

            ENDLOOP.

        ENDCASE.

      ENDIF.

 

    ENDIF.

 

    CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

      EXPORTING

        input = lv_soid

      IMPORTING

        output = lv_soid.

 

 

    CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

      EXPORTING

        input = lv_soitempos

      IMPORTING

        output = lv_soitempos.

 

*Get data from BAPI_EPM_SO_GET_DETAIL

 

    CALLFUNCTION'BAPI_EPM_SO_GET_DETAIL'

      EXPORTING

        so_id     = lv_soid

      IMPORTING

        headerdata = ls_salesorder

      TABLES

        itemdata  = lt_itemdata.

 

 

*Fill ER_ENTITY

    READTABLE  lt_itemdata INTO  ls_itemdata WITHKEY so_id = lv_soid

                                                        so_item_pos = lv_soitempos.

    IF sy-subrc = 0.

      lv_product_id-product_id = ls_itemdata-product_id.

 

      CALLFUNCTION'BAPI_EPM_PRODUCT_GET_DETAIL'

        EXPORTING

          product_id = lv_product_id

        IMPORTING

          headerdata = lv_product_header.

 

      MOVE-CORRESPONDING lv_product_header TO er_entity.

 

    ENDIF.

 

  ENDIF.

ENDMETHOD.

 

Also note that we can read product directly using URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/ProductSet('HT-1030')

 

Now try with this URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000000')?$expand=OrderToItems/ItemToProduct

Product details will not filled as in the navigation keys are empty because we do not have referential constraint.

 

Also try with /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderItemSet(SoId='0500000000',SoItemPos='0000000020')/ItemToProduct and check why it is not working.

 

Additionally you can query as

 

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000000')/$links/OrderToItems

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000009')/$links/OrderToItems/$count

 

Data Provider Expand

 

In this section, we will see how to implement data provider expand by redefining GET_EXPANDED_ENTITYSET and GET_EXPANDED_ENTITY.

 

Implementing GET_EXPANDED_ENTITYSET

 

Let’s redefine GET_EXPANDED_ENTITYSET. With redefinition (just blank code) execute again the URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet?$expand=OrderToItems

 

You will not get any response as you need to implement the code yourself.

 

One of the important point while implementing logic is Data declaration! Based on level till which you want to expand, you need to define your internal table having nested structure or table type.

 

In below code, we want to expand Sales Order and its items. Hence the expand technical clause will be ORDERTOITEMS.

METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entityset.

 

  DATABEGINOF t_expand_so.

  INCLUDE             TYPE zcl_ztest_dp_expand_mpc_ext=>ts_salesorder.

  DATA: ordertoitems  TYPE zcl_ztest_dp_expand_mpc_ext=>tt_salesorderitem,

       ENDOF t_expand_so.

 

  DATA: lt_expand_so   LIKE  TABLEOF t_expand_so,

        ls_expand_so   LIKE t_expand_so,

        ls_item        TYPE zcl_ztest_dp_expand_mpc_ext=>ts_salesorderitem.

 

 

  DATA: lt_salesorder  TYPETABLEOF bapi_epm_so_header,

        ls_salesorder LIKELINEOF lt_salesorder,

        lt_itemdata   TYPETABLEOF bapi_epm_so_item,

        ls_itemdata   TYPE  bapi_epm_so_item,

        l_max_rows    TYPE bapi_epm_max_rows.

 

  CONSTANTS: lc_expand_tech_clause TYPE string VALUE'ORDERTOITEMS'.

 

 

* Read Sales Order and Item data

  l_max_rows-bapimaxrow = '10'.

  CALLFUNCTION'BAPI_EPM_SO_GET_LIST'

    EXPORTING

      max_rows    = l_max_rows

    TABLES

      soheaderdata = lt_salesorder

      soitemdata  = lt_itemdata.

 

* Data processing logic

  LOOPAT lt_salesorder INTO ls_salesorder.

    MOVE-CORRESPONDING ls_salesorder TO ls_expand_so  .

    LOOPAT lt_itemdata INTO ls_itemdata WHERE so_id = ls_salesorder-so_id .

      MOVE-CORRESPONDING ls_itemdata TO ls_item  .

      APPEND ls_item  TO ls_expand_so-ordertoitems.

      CLEAR: ls_item.

    ENDLOOP.

    APPEND ls_expand_so  TO lt_expand_so.

    CLEAR: ls_expand_so.

  ENDLOOP.

 

* Fill EE_ENTITYSET

  copy_data_to_ref(

    EXPORTING

      is_data = lt_expand_so

    CHANGING

      cr_data = er_entityset ).

 

* Insert Navigation property into ET_EXPANDED_TECH_CLAUSES

  INSERT lc_expand_tech_clause INTOTABLE et_expanded_tech_clauses.

ENDMETHOD.

 

 

Query with URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet?$expand=OrderToItems&sap-statistics=true to check the runtime statistics and compare the values with before implementing data provider expand.

dpe8.jpg

Now we will try to expand to one level more i.e. we will expand sales order, its items and product of each item. In this case the expand technical clause will be ORDERTOITEMS/ITEMTOPRODUCT.

 

Below is the code we need to put to achieve the desired result.

 

METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entityset.

 

 

  DATABEGINOF t_orderitems.

  INCLUDE              TYPE  zcl_ztest_dp_expand_mpc_ext=>ts_salesorderitem.

  DATA: itemtoproduct TYPE  zcl_ztest_dp_expand_mpc_ext=>ts_product,

        ENDOF t_orderitems.

 

  DATABEGINOF t_expand_so.

  INCLUDE             TYPE zcl_ztest_dp_expand_mpc_ext=>ts_salesorder.

  DATA: ordertoitems  LIKETABLEOF t_orderitems,

       ENDOF t_expand_so.

 

  DATA: lt_expand_so   LIKE  TABLEOF t_expand_so,

        ls_expand_so   LIKE t_expand_so,

        ls_item        LIKE t_orderitems.

 

 

  DATA: lt_salesorder  TYPETABLEOF bapi_epm_so_header,

        ls_salesorder LIKELINEOF lt_salesorder,

        lt_itemdata   TYPETABLEOF bapi_epm_so_item,

        ls_itemdata   TYPE  bapi_epm_so_item,

        l_max_rows    TYPE bapi_epm_max_rows.

 

  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/ITEMTOPRODUCT'.

 

 

* Read Sales Order and Item data

  l_max_rows-bapimaxrow = '10'.

  CALLFUNCTION'BAPI_EPM_SO_GET_LIST'

    EXPORTING

      max_rows    = l_max_rows

    TABLES

      soheaderdata = lt_salesorder

      soitemdata  = lt_itemdata.

 

* Data processing logic

  LOOPAT lt_salesorder INTO ls_salesorder.

    MOVE-CORRESPONDING ls_salesorder TO ls_expand_so  .

    LOOPAT 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.

      CALLFUNCTION'BAPI_EPM_PRODUCT_GET_DETAIL'

        EXPORTING

          product_id = lv_product_id

        IMPORTING

          headerdata = ls_product_header.

      MOVE-CORRESPONDING ls_product_header TO ls_item-itemtoproduct.

      APPEND ls_item  TO ls_expand_so-ordertoitems.

      CLEAR: ls_item.

    ENDLOOP.

    APPEND ls_expand_so  TO lt_expand_so.

    CLEAR: ls_expand_so, lv_product_id.

  ENDLOOP.

 

 

* Fill EE_ENTITYSET

  copy_data_to_ref(

    EXPORTING

      is_data = lt_expand_so

    CHANGING

      cr_data = er_entityset ).

 

* Insert Navigation property into ET_EXPANDED_TECH_CLAUSES

  INSERT lc_expand_tech_clause INTOTABLE et_expanded_tech_clauses.

ENDMETHOD.

 

Please note that we need to insert complete expand clause in et_expanded_tech_clauses

 

Implementing GET_EXPANDED_ENTITY

 

Let’s implement GET_EXPANDED_ENTITY.

 

Below is the query to execute and code to for implementation.


/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000005')?$expand=OrderToItems/ItemToProduct

 

METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entity.

 

  DATABEGINOF t_orderitems.

  INCLUDE              TYPE  zcl_ztest_dp_expand_mpc_ext=>ts_salesorderitem.

  DATA: itemtoproduct TYPE  zcl_ztest_dp_expand_mpc_ext=>ts_product,

        ENDOF t_orderitems.

 

 

  DATABEGINOF t_expand_so.

  INCLUDE             TYPE zcl_ztest_dp_expand_mpc_ext=>ts_salesorder.

  DATA: ordertoitems  LIKETABLEOF t_orderitems,

       ENDOF t_expand_so.

 

 

  DATA: ls_expand_so   LIKE t_expand_so,

        ls_item LIKE t_orderitems.

 

 

  DATA:  ls_salesorder TYPE bapi_epm_so_header,

         lt_itemdata   TYPETABLEOF 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/ITEMTOPRODUCT'.

 

*Get the key property values and Read Sales Order and Item data

  READTABLE it_key_tab WITHKEY name = 'SoId'INTO ls_key_tab.

  lv_soid = ls_key_tab-value.

 

  CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

    EXPORTING

      input = lv_soid

    IMPORTING

      output = lv_soid.

 

  CALLFUNCTION'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  .

  LOOPAT 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.

    CALLFUNCTION'BAPI_EPM_PRODUCT_GET_DETAIL'

      EXPORTING

        product_id = lv_product_id

      IMPORTING

        headerdata = ls_product_header.

    MOVE-CORRESPONDING ls_product_header TO ls_item-itemtoproduct.

    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 INTOTABLE et_expanded_tech_clauses.

ENDMETHOD.

 

Closing Remarks

 

Important points to be considered while coding for association/navigation and data provider $expand,

  • Use of navigation path and navigation key. Entities can be directly accessed or via navigation property. Code for both scenario using navigation path and navigation keys.
  • Data declaration of internal tables in case of data provider expand. Understand the relations between entities. while declaring internal table, use navigation property name to address dependent entity structure. It should be same. Check below data declaration.

  DATABEGINOF t_orderitems.

  INCLUDE              TYPE  zcl_ztest_fw_expand_mpc_ext=>ts_salesorderitem.

  DATA: itemtoproductTYPE  zcl_ztest_fw_expand_mpc_ext=>ts_product,

        ENDOF t_orderitems.

 

 

  DATABEGINOF t_expand.

  INCLUDE             TYPE zcl_ztest_fw_expand_mpc_ext=>ts_salesorder.

  DATA: ordertoitems  LIKETABLEOF t_orderitems,

       ENDOF t_expand.

 

 

  DATA: lt_so   LIKE  TABLEOF t_expand,

        ls_so   LIKE t_expand,

        ls_item LIKE t_orderitems.

  • Parent and its immediate child will be separated using "/" for e.g $expand=OrderToItems/ItemToProduct  if we would have 2nd sibling at order level for e.g Partners of Sales order then we could have navigation property as OrderToPartners with say its child as PartnerToAddress then we need to access it as OrderToPartners/PartnerToAddress. To get the expanded result for both hierarchies, the expand clause will look as $expand=OrderToItems/ItemToProduct,OrderToPartners/PartnerToAddress (separated by ",")
  • Navigation property separated with "/" will be inserted into expanded technical clause. 2nd hierarchy will be appended in expanded technical clause

        In short, for example mentioned in point 3, it would be,

ls_expanded_clause_items = 'ORDERTOITEMS/ITEMTOPRODUCT'.

ls_expanded_clause_partners = 'ORDERTOPARTNERS/PARTNERTOADDRESS'.

APPEND ls_expanded_clause_items TO et_expanded_tech_clauses.

APPEND ls_expanded_clause_partners TO et_expanded_tech_clauses.

        also refer this thread Error with $expand and navigation: Resource not found for the segment 'NavAtp'

  • whether framework expand or data provider expand provides better result will depends on your scenario. Please notice that with $expand, we are making single call to read the parent and child data but at the same time ensure that the data to be retrieved is not too large.

 

I hope you enjoyed reading this blog and now will be able to play with association/navigation and data provider $expand!

 

Please feel free if you have any different thoughts to improve any section of this blog.

 

Happy Learning & Coding


Viewing all articles
Browse latest Browse all 2823

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>