Skip to Content
Technical Articles
Author's profile photo Kranthi Kumar nalla

Convert complex GUI report into Fiori Elements list report using ABAP RESTful Application Programming Model (RAP) on premise (S/4HANA 1909)

Introduction

This Blog Post discusses about the approach to convert Classical GUI report programs to Fiori application on S/4HANA 1909 On-Premise system.

Is it possible to develop complex reports using the ABAP CDS model? 

This is the most frequently asked question when customers think of Fiori or doing system conversion to S/4HANA where most of the application developed on top of CDS data model. This is quite challenging task for IT analysts to convert GUI reports with complex business logic to Fiori applications.

We have been developing classical GUI reports with complex custom logic and calculations for many years, Customers don’t want to scrap their code and turn their mind to simple Fiori applications immediately. Most of the time, we use complex custom codes, function modules, BAPIs, methods to build applications, and sometimes it’s difficult for us to choose a standard CDS or convert the complete business logic into CDS.

Approach

We can achieve this partially by using virtual elements (ABAP code Exits) in CDS but sometimes not enough. Check more details in the below link:

https://help.sap.com/viewer/cc0c305d2fab47bd808adcad3ca7ee9d/7.51.7/en-US/a7fc007921d44263b09ccc092392b05f.html

ABAP RESTful Application Programming Model in short RAP is evolving and good choice for developers, Technical Consultants, and Architectures to make it possible and providing ways to reuse existing business logic.

Use case

Build a Fiori Element list report application to replace a custom GUI report by following SAP best practices and reusing the existing business logic.

Solution

Fiori element-based list report application using Custom CDS entity ( The runtime is implemented in a class, and the data partially received from CDS views and partially from FMs, BAPIs, conversions, combine the data in the class implementation and fill result (Response) entity set. Check more details in the below link:

https://help.sap.com/viewer/923180ddb98240829d935862025004d6/Cloud/en-US/6436a50d7d284f01af2cca7a76c7116a.html#8acde6ef9a8d4d5e951362279566e642.html

Steps to create GUI based report transactions:

  • Create Selection Screen for input data
  • Fetch data from multiple tables based on selection criteria
  • Apply Authority check, Use FMs, BAPIs, other manipulations to fetch additional data
  • Do conversion and prepare final internal table
  • Populate Field catalog for the column information
  • Call ALV Method/ function module to display the data on the screen

Steps to create Fiori application using RAP (S4HANA 1909):

(Ideally this approach is to work with cloud ABAP environment and combine data from different sources, but I tried it on-Premise)

  • Create a CDS view to fetch partial data (Apply Code push down as much as possible)
  • Create a CDS custom entity with all the fields required in the list display
  • Use necessary UI annotations for selection screen, search helps, list item details
  • Add object model annotation for query implementation class for the business logic @ObjectModel.query.implementedBy.
  • Write select query on composite CDS and use your ABAP skills to combine FM/BAPI/ other sources data in the method implementation
  • Implement paging logic and prepare response data
  • create Service definition on CDS Custom entity and Service binding to expose data
  • Use WebIDE / SAP Business Application Studio to create front end application using Fiori Elements list report template

CDS Custom entity:

@ObjectModel: {
    query: {
       implementedBy: 'ABAP:zcl_sample'
    }
}
@UI.headerInfo: { typeName: 'List title' ,
                  typeNamePlural: 'List title' }
@EndUserText.label: 'custom entity'
define custom entity ZTEST_CDS_CUSTOMENTITY
{
      @UI.selectionField    : [{position: 10 }]
      @UI.lineItem :  [{label:       'Material',position: 10 ,importance: #HIGH }]
      @Consumption.valueHelpDefinition: [{ entity: {  name:    'I_MaterialVH' ,element: 'Material' } }]
  key Material     : matnr;
      @UI.selectionField    : [{position: 20 }]
      @UI.lineItem :  [{position: 30 ,importance: #HIGH }]
  key Plant        : werks_d;
      @UI.lineItem :  [{position: 30 ,importance: #HIGH }]
      MaterialName : maktx;
}

The details about data requested from the front-end application retrieved using the below methods of the interface.

Interface name: IF_RAP_QUERY_PROVIDER

CLASS zcl_sample DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_rap_query_provider .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.
CLASS zcl_sample IMPLEMENTATION.
  METHOD if_rap_query_provider~select.

    IF io_request->is_data_requested( ).
      DATA: lt_response TYPE TABLE OF ztest_cds_customentity.
      DATA(lv_top)           = io_request->get_paging( )->get_page_size( ).
      DATA(lv_skip)          = io_request->get_paging( )->get_offset( ).
      DATA(lt_clause)        = io_request->get_filter( )->get_as_sql_string( ).
      DATA(lt_fields)        = io_request->get_requested_elements( ).
      DATA(lt_sort)          = io_request->get_sort_elements( ).

      TRY.
          DATA(lt_filter_cond) = io_request->get_filter( )->get_as_ranges( ).
        CATCH cx_rap_query_filter_no_range INTO DATA(lx_no_sel_option).
      ENDTRY.

      DATA(lr_material)  =  VALUE #( lt_filter_cond[ name   = 'MATERIAL' ]-range OPTIONAL ).
      
****Data retrival and business logics goes here*****

      io_response->set_total_number_of_records( lines( lt_response ) ).
      io_response->set_data( lt_response ).

    ENDIF.
  ENDMETHOD.
ENDCLASS.

 

Paging in OData:

Get the details of How many records wants to retrieve and How many records wants to skip

  • data(lv_top) = io_request->get_paging( )->get_page_size( ).
  • data(lv_skip) = io_request->get_paging( )->get_offset( ).

Get the where clause to insert to the select query:

  • data(lv_clause)     = io_request->get_filter( )->get_as_sql_string( ).

Get requested fields:

  • data(lt_fields) = io_request->get_requested_elements().

Get sorting fields:

  • data(lt_sort) = io_request->get_sort_elements().

Get selection criteria:

  • data(lt_filter_cond) = io_request->get_filter ()->get_as_ranges ().

 

For instance, Materials entered in UI filter captured as below

DATA(lr_material) = VALUE #( lt_filter_cond[ name = ‘MATERIAL’ ]-range OPTIONAL ).

Populate final entity set by combining data from CDS select and other data sources (BAPI/ function modules) or you can reuse the existing business logic.

 

Set the total number of records and final entity set

  • io_response->set_total_number_of_records (lines (lt_response)).
  • io_response->set_data (lt_response).

 

Conclusion

Instead of creating a tile for GUI classical report in Fiori Launchpad, We can easily convert into actual Fiori application by reusing most of the existing business logic and later convert the code using code push down techniques like CDS and AMDPs to improve performance.

 

Note:

  • I am the owner of all the content and code used in this blog post.

Hope you like this blog post and comment your views on this.

 

Assigned Tags

      9 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Maitenance IBM India
      Maitenance IBM India

      Good post.

      Author's profile photo Dmitry Penzar
      Dmitry Penzar

      A very difficult decision. You can use something like: 1) selection criteria in FIORI + 2) Export list to memory in ABAP + 3) Sinlge FM to hide the conversion routine for ODATA. That's all, if we're talking about a list report and necessity of a "fast solution"

      Author's profile photo aostv apk
      aostv apk

      Thanks for the good post and it is very useful for me.

      Author's profile photo Mio Yasutake
      Mio Yasutake

      Thanks for sharing this.

      Custom CDS entity must be useful.

      Author's profile photo Avi Mishan
      Avi Mishan

      Thank you for sharing.

      Yet, there are solutions out there that will do the same w/o code.

       

      Author's profile photo Alexander Rützel
      Alexander Rützel

      What solutions are we talking about?

      Link?

      Author's profile photo Somnath Choudhury
      Somnath Choudhury

      Yes very curious to know about the solutions . Pls share incase if you know of any . For a custom solution we have no other option but to sweat hard in building one. This is still a nice blog to know how to start .

      Author's profile photo Mahesh Palavalli
      Mahesh Palavalli

      Nice example, thanks for sharing Kranthi Kumar nalla

      Author's profile photo Beyhan MEYRALI
      Beyhan MEYRALI

      Thanks a lot for sharing Kranthi. I was looking for that.

      I could not endure to see one more blog of /dmo/flight example 🙂