Friday, 29 November 2019

SADL – Handling OData Navigation Without Association

Overview


In this blog post I’ll share how I was able to enable navigation between two OData entities that did not have an association mapped by SADL.  I wasted a lot of time searching for a blog post or question on this and didn’t find one.  So now that I figured out the answer hopefully it will save you time!

Context


Our development environment contains the following SAP Versions

◉ EHP7 For SAP ERP 6.0 SP17
◉ SAP Netweaver 7.4 SP20
◉ SAP Fiori Front-End Server 4.0

I’m developing a Fiori Elements List Report application that manages material demand records.  The end users also want to see related material master data for each demand record.

The OData entity for demand data is a BOPF object.  The related material master data is supported by a CDS View.  Both entities were imported and are supported by SADL.

Relevant Demand attributes

◉ Demand Number (Key)
◉ Material Number (ZzMatnrExt)

Material Master Attributes

◉ Material Number (Matnr)
◉ Material Type (Mtart)
◉ Material Group (Matkl)
◉ Base Unit (Meins)

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

Problem


I have not found a way to associate a BOPF object to a related dataset supported by a CDS view.  So, how can two entities that are related to each other but don’t have an association supported by SADL navigate between their respective OData entities?

Well after lots and lots of google searching I finally came across the link I shared above titled Fine-Tuning the Execution of SADL-Based Gateway Services.  This document from SAP shares some extra SADL capabilities you can enable through a little extra ABAP work. 

Implementation


Create an association in your OData Service between the two entities.


i. Right click on the Data Model Folder

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

ii. Name your association, provide the entities and cardinality, create a navigation property.

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

iii. In step 2 the referential constraints are provided.

1. This requires you to specify only the key from the principal entity.  This is usually a problem when I link to related data.  The values that link the two entities may not be key values on either entity.

2. So, I provide no referential constraint in this step as they will be specified in the later step where we define the condition to select target entity records from the database.

3. Use the delete row button to remove the referential constraint.

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

iv. In Step 3 the entity set and association set are named.

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

You should now see the association and navigation info created in your odata service project.


SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

Create class instance attributes to store the navigation information.


i. The first step specified by the Handling OData Navigation document is to add two attributes.

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

ii. Go to your DPC_EXT class of your odata service.

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

iii. Go to the Attributes tab, add the two attributes specified by the documentation.

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

In the getter methods of the target entity, store the navigation information.


i. The second step specified by the Handling OData Navigation document is to store the navigation information in the getter methods of the target entity.

ii. Our target entity is MATNR_INFO, we’ll redefine the methods and add the code to store the navigation information in the class member attributes.

iii. Select the MATNR_INFOSET_GET_ENTITYSET method, push the Redefine Method button.

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

iv. Add the code from the Handling Odata Navigation step 2. Also you’ll notice that there is commented out code that calls SUPER->MATNR_INFOSET_GET_ENTITYSET.  Uncomment this code and pass the parameters from our redefined method to it.  This allows the normal SADL processing to continue for requests.

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

v. Repeat this process for the MATNR_INFOSET_GET_ENTITY method as well.

Force SADL to ignore the navigation and define a condition to select the target entities from the database.


i. The third and final step from the Handling OData Navigation document is to intercept the navigation to the target entity MATNR_INFO and define the conditions by which to select the related data.

ii. Redefine the IF_SADL_GW_QUERY_CONTROL~SET_QUERY_OPTIONS method in your DPC_EXT class following the same principal steps depicted above.

iii. Following the code example from the Handling OData Navigation document, set up a case statement.

iv. Follow the code comments to help understand the process.  I did add another method to my DPC_EXT class to read the Demand record from the database by the key, as the entire record is not passed in to the DPC_EXT class during navigation.

CASE iv_entity_set.

    WHEN 'MATNR_INFOSet'.
      IF mt_navigation_info IS NOT INITIAL.
        DATA(ls_nav_step) = mt_navigation_info[ 1 ].
        " Is this the navigation we have to handle (BO_DMND -> MATNR_INFO)?
        IF ls_nav_step-source_entity_type = 'BO_DMND'
            AND ls_nav_step-nav_prop      = 'MATNR_INFO'.
          " Make SADL ignore navigation
          io_query_options->remove_navigation_info( ).
          " Define condition based on source entity key
          DATA(lo_cond_factory) =
              cl_sadl_cond_prov_factory_pub=>create_basic_condition_factory( ).
          "Read ZCOLLECTOR record from DB to get ZZ_MATNR_EXT field.
          DATA lv_key TYPE /BOBF/CONF_KEY.
          lv_key = mt_source_keys[ name = 'KEY' ]-value.
          DATA(ls_collector) = GET_DEMAND_BY_KEY( EXPORTING IV_KEY = lv_key ).

*          io_query_options->add_condition_provider(
*              lo_cond_factory->equals(
*                  name  = 'ZZ_MATNR_EXT' " ABAP field name of GW property
*                  value = mt_source_keys[ name = 'ZZ_MATNR_EXT' ]-value ) ).
          " Define condition based on target entity key (if any)
          IF ls_collector IS NOT INITIAL.
            DATA lv_matnr_ext TYPE string.
            lv_matnr_ext = ls_collector-zz_matnr_ext.
            io_query_options->add_condition_provider(
                lo_cond_factory->equals(
                    name = 'MATNR' " ABAP field name of GW property
                    value = lv_matnr_ext ) ).
          ENDIF.
        ENDIF.
      ENDIF.
  ENDCASE.


*TRY.
CALL METHOD SUPER->IF_SADL_GW_QUERY_CONTROL~SET_QUERY_OPTIONS
  EXPORTING
    IV_ENTITY_SET    = iv_entity_set
    IO_QUERY_OPTIONS = io_query_options
    .
* CATCH /IWBEP/CX_MGW_BUSI_EXCEPTION .
* CATCH /IWBEP/CX_MGW_TECH_EXCEPTION .
*ENDTRY.
  endmethod.

Evaluate the OData service output and follow the navigation to see if the related data is available.


Now when I evaluate the data provided in the odata service I can see the new relationship.

◉ In the metadata

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

◉ In the OData response to getting a single Demand record, there is a navigation to material info.

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

◉ If you follow this navigation you’ll see the related material info.

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

Utilize the data in a Fiori Elements List Report


The entire effort we just went through will now enable us to annotate the target entity to display on our List Report application as we see fit.

SAP ABAP Study Materials, SAP ABAP Learning, SAP ABAP Tutorial and Material, SAP ABAP Online Exam, SAP ABAP Certifications

No comments:

Post a Comment