Skip to Content
Technical Articles
Author's profile photo Prabhjot Bhatia

My journey of building FIORI apps from BOPF to RAP – Part 1

Introduction:


ABAP Restful Programming model is the latest programming model which SAP has introduced and It’s a successor of ABAP programming model in FIORI. In this series of blog posts, I would like to highlight comparison between BOPF Model and RAP model to achieve the different requirements in a sample FIORI app. It would help people to easily adapt the transition from ABAP programming model in FIORI into RAP model. Additionally, I will also highlight some important comparative features between SAP Web IDE and SAP Business Application Studio( BAS ) .

Pre-requisites:


  1. Good knowledge on CDS Modeling, BOPF Framework.
  2. Basic knowledge in RAP Model ( Managed Implementation )
  3. Basic understanding of SAP Web IDE and BAS.

Business Use Case:


A customizing FIORI app is required to configure various active company id and it’s allowed communication language keys. Different departments in one organization can have flexibility to customize different company ID and allowed languages. For that, a unique application ID will be maintained at first place. Use cases handled by the FIORI app would be as follow:

  1. There should be a unique application ID for each business department ( e.g. FI-AR, FI-FSCM, SD-BILLING )
  2. Only active applications can further allowed to have different company ID. For inactive applications, company ID cant be maintained.
  3. CUD operations are not allowed for any inactive instance.
  4. Actions to update the status( Active/Inactive ) should be enabled as per the FIORI UX guidelines.
  5. Custom actions should be dynamically enabled/disabled based on status.
  6. For Company ID, a popup dialog would be needed to set the validity period.
  7. Company IDs where Valid from is in past are NOT allowed.
  8. Valid To for a company should not be less than Valid From date.
  9. Only Authorized users for each application can maintain the entries in the app.
  10. Copy function to allow copy an existing application instance along with its associated entries.

The above points are just few of the use cases our FIORI app can perform but we will group the use cases and based on that, we will follow different blog posts in the series.

App Preview:


At the end, FIORI apps deployed in the launchpad would be a List report FIORI app created via templates but look and feel of the app has been changed as Master-Detail style since It would be helpful for end users to view all the associated entities on one screen.

 

 

Use Cases

Programming Model 

BOPF RAP
#1.1 Change custom action visibility dynamically
  • Use determination ACTION_AND_FIELD_CONTROL
  • Implement application logic in method EXECUTE

 

  • Add feature control in Behavior Definition.
  • Implement application logic in behavior implementation handler class in method GET_INSTANCE_FEATURES  GET_GLOBAL_FEATURES

 

#1.2 Change field visibility dynamically
  • Annotate CDS view fields with object model annotation EXTERNAL_CALCULATION
  • Use determination ACTION_AND_FIELD_CONTROL
  • Implement application logic in method EXECUTE

 

  • Add feature control for corresponding fields in Behavior Definition.
  • Implement application logic in behavior implementation handler class in method GET_INSTANCE_FEATURES  GET_GLOBAL_FEATURES

 

#2 Authorization on standard CUD operations
  • Use authorization in BO and implement methods in authorization class of BO CHECK_STATIC_AUTHORITY
  • Add feature control in Behavior definition for CUD operations.
  • Implement Feature control methods in behavior implementation handler class.
#3 Custom actions with parameters in a dialog
  • Create new DDIC structure with all parameters in dialog.
  • Create new action in BOPF and pass parameter structure.
  • Implement handler class for custom action in BOPF.
  • Create Abstract CDS view entity for all parameters required in dialog.
  • Add action with parameter in Behavior definition for the corresponding entity.
  • Implement the processing logic for custom action in behavior implementation.
#4 Copy complete context including associations Not sure if Its feasible via BOPF. Using UI Extension to provide action dialog, It might be possible. However, It would lead to UI5 programming in Frontend(Not too pleasant for ABAPers 🙂 )  

  • It can be done using Custom action with parameters by creating a copy action.
  • In behavior implementation, create-by-association should be used to copy the associated entities.

Use Cases

UI Development Tool

Web IDE

Business Application Studio

#5 Confirmation popup on custom actions

  • Use Annotation modeler for generated annotation.xml.
  • Set IsActionCritical annotation as true for function Import.
  • Function Import can be selected from annotation modeler.
  • Use code completion feature provided by the XML annotation LSP extension.
  • Set IsActionCritical annotation as true for function Import.
#6 Annotate FIORI app elements 
  • Activate local annotations from annotation file
  • Open Annotation Modeler and check if required functionality is available.
  • Use FIORI Guided development tool for various in-built feature for all the floorplans.
  • Follow step-by-step options provided by the framework and opt to insert the generated annotation automatically in the annotation.xml file.
  • For some features, manifest.json file also gets adjusted automatically from framework.
#7 Adjust FIORI app settings with layout editor options
  • Use Page map to easily adjust the FIORI app with some features Flexi column Layout for List report floorplan, Automatic load table data without pressing Go button etc.

 

Data Model


Entities for Transactional Data:

As depicted in the figure below, the 3-tier entity hierarchy for managing transactional data in our scenario consists of the following editable entities, with a 1: N cardinality on each level:

  • Application
  • Company
  • Language

The figure below shows the composition relationship between the application, company and the language entities, where the application entity represents the root of the data model.

 

Business Object Model:

Entity

Behavior (BOPF)

Behavior (RAP)

Application Operations:

  • Create, Update, Delete

Actions:

  • Set Active, Set Inactive

Validations:

  • Validate duplicate application ID

Authorization:

  • Static check for operations

Determination:

  • Annotation for object model in CDS for dynamic visibility of fields and actions EXTERNAL_CALCULATION

Associations:

  • Link the child entity _Company
Operations:

  • Create, Update, Delete
  • Create Company by association
  • Action: Set Active, Set Inactive

Validations:

  • Validate duplicate application ID

Feature Control:

  • Dynamic operation and action control

 

Company Operations:

  • Create, Update, Delete

Actions:

  • Set Active, Set Inactive, Set Validity

Validations:

  • Validate valid from and valid to

Authorization:

  • Static check for operations

Determination:

  • Annotation for object model in CDS for dynamic visibility of fields and actions EXTERNAL_CALCULATION
  • Derive the parent Application using  create_by_association for new instances of company

Associations:

  • Link the child entity _Language

 

Operations:

  • Update, Delete
  • Create Language by association
  • Action: Set Active, Set Inactive, Set Validity

Validations:

  • Validate valid from and valid to

Determinations:

  • Derive default valid from and valid to dates

Feature Control:

  • Dynamic operation and action control
Language Operations:

  • Create, Update, Delete

Actions:

  • Set Active, Set Inactive

Validations:

  • Validate correct language key

Authorization:

  • Static check for operations

Determination:

  • Annotation for object model in CDS for dynamic visibility of fields and actions EXTERNAL_CALCULATION
  • Derive the parent Company using  create_by_association for new instances of language

 

Operations:

  • Update, Delete
  • Action: Set Active, Set Inactive

Validations:

  • Validate correct language key

Feature Control:

  • Dynamic operation and action control

 

Technical artifacts in the ABAP side can be created for the FIORI app based on the programming model we follow. Lets start now with the listed requirements with both the programming models.


1.1 Change Custom action visibility


As per BO model described above, there are 2 custom actions for all the entities: Set Active and  Set Inactive. Based on the status of the selected entity instance, visibility of the action buttons should be enabled/disabled.

Approach 1 : BOPF


  • In the Business Object, Go to Determination ACTION_AND_FIELD_CONTROL .

 

  • Navigate it’s implementing class and Implement the method /bobf/if_frw_determination~execute .
METHOD /bobf/if_frw_determination~execute.

    DATA: lt_context_data   TYPE ztipb_application.
    DATA: lv_action_enabled TYPE abap_bool.

    io_read->retrieve(
      EXPORTING
        iv_node                 =  is_ctx-node_key
        it_key                  =  it_key[]            " Key Table
      IMPORTING
        eo_message              =  eo_message          " Message Object
        et_data                 =  lt_context_data[]   " Data Return Structure
        et_failed_key           =  et_failed_key       " Failed Key Table
    ).

"(1)--> Handle Actions Dynamically
    LOOP AT lt_context_data ASSIGNING FIELD-SYMBOL(<ls_context>).
      IF <ls_context>-x_active = 'X'.
        lo_property_helper->set_action_enabled(
        iv_action_key = zif_i_pb_application_c=>sc_action-zi_pb_application-set_active
        iv_key        = <ls_context>-key
        iv_value      = abap_false ).

        lo_property_helper->set_action_enabled(
        iv_action_key = zif_i_pb_application_c=>sc_action-zi_pb_application-set_inactive
        iv_key        = <ls_context>-key
        iv_value      = abap_true ).
      ELSE.
        lo_property_helper->set_action_enabled(
        iv_action_key = zif_i_pb_application_c=>sc_action-zi_pb_application-set_active
        iv_key        = <ls_context>-key
        iv_value      = abap_true ).

        lo_property_helper->set_action_enabled(
        iv_action_key = zif_i_pb_application_c=>sc_action-zi_pb_application-set_inactive
        iv_key        = <ls_context>-key
        iv_value      = abap_false ).
      ENDIF.
    ENDLOOP.
ENDMETHOD.

 

Approach 2 : RAP


  • In Behavior definition, Define Feature Control for custom actions with scope instance as we need to implement the action visibility based on selected instance’s status.

   

  • In Behavior implementation, Implement the method for instance feature control and set the visibility of custom actions:
METHOD get_instance_features.
** Read the status of current application record
    READ ENTITIES OF zi_pb_active_appl IN LOCAL MODE
    ENTITY Application
    FIELDS ( IsActive ) WITH CORRESPONDING #( keys )
    RESULT DATA(lt_context_data)
    FAILED failed.

    result = VALUE #( FOR ls_data IN lt_context_data
                        LET lv_active   = COND #( WHEN ls_data-IsActive IS NOT INITIAL 
                                                  THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled )
                            lv_inactive = COND #( WHEN ls_data-IsActive IS INITIAL 
                                                  THEN if_abap_behv=>fc-o-disabled ELSE if_abap_behv=>fc-o-enabled )
                        IN ( %tky                         = ls_data-%tky
                             %action-activeApplication    = lv_active
                             %action-InactiveApplication  = lv_inactive )
                     ).

  ENDMETHOD.

 

Output in FIORI App:


Application with status active is selected so only action “Set Inactive” is allowed and “Set Inactive” will be disabled in List page.

Application with status Inactive is selected so only action “Set Active” is allowed and “Set Active” will be disabled in List page.


1.2 Enable fields dynamically


We can either enable the fields on FIORI UI as read only statically at design time or dynamically at run time based on some application logic. For that, there would be different steps in different programming models.

Approach 1 : BOPF


  • Set Object Model annotation for CUD operations as EXTERNAL_CALCULATION in BO CDS view.
@ObjectModel:{

    semanticKey: ['application'],

    transactionalProcessingEnabled: true,
    compositionRoot: true,

    writeActivePersistence: 'zfar_active_appl',

    createEnabled: 'EXTERNAL_CALCULATION',
    updateEnabled: 'EXTERNAL_CALCULATION',
    deleteEnabled: 'EXTERNAL_CALCULATION'

}

  • Set Object Model Annotation with readOnly property as dynamic for Application ID and true for admin fields. With this, Admin fields (CreatedBy, CreatedAt) would always be read only and Application ID will be editable during creation and read only during update operation.
define view ZI_PB_APPLICATION
  as select from zfar_active_appl
{
      @ObjectModel.readOnly: 'EXTERNAL_CALCULATION'
  key applicationId,
      name,
      @ObjectModel.readOnly: true
      @Semantics.user.createdBy: true
      created_by
  • Now, Go to BOPF determination ACTION_AND_FIELD_CONTROL, navigate to implementing class and method EXECUTE and add following method call after reading the context node data:
      lo_property_helper->set_attribute_read_only(
        EXPORTING
          iv_attribute_name = zif_i_pb_application_c=>sc_node_attribute-zi_pb_application-application  " Name of the attribute for which the property is to be set
          iv_key            =  ls_attribute-key   " Key of the instance for which the property is to be set
      ).

Approach 2 : RAP


  • In Behavior definition, Define property for create and update operation for field ApplicationID
field ( mandatory : create, readonly : update ) ApplicationID;
field ( readonly ) CreatedAt, CreatedBy;

By defining the applicationID mandatory during Create operation, RAP framework will allow UI to enable applicationID and once created, It will be read only during Update operation.

However, we can always define this behavior dynamic at field level using feature control and in the Feature control implementation method, we can set its property as:

  METHOD feature_ctrl_method.
    " Read data required 
    READ ENTITY CDSEntityName 
         FIELDS ( field1 field2 )
           WITH VALUE #( FOR keyval IN keys ( %key = keyval-%key ) )
         RESULT DATA(read_result).
    
    " Return feature control information
    result = VALUE #( FOR variable IN read_result
             ( %key                          = variable-%key
    " Field control information
               %field-field1                 = if_abap_behv=>fc-f-read_only
               %field-field2                 = if_abap_behv=>fc-f-mandatory ) ).
  ENDMETHOD.
        

 

Conclusion:


In this blog, All the different business scenarios have been discussed , Data Model has been explained which will be used in subsequent blog posts in the series and we covered 2 scenarios to handle the visibility of custom actions and fields dynamically both in BOPF ( ABAP programming Model in FIORI ) and RAP ( RESTful ABAP programming model ).

In the next blog post, we will cover authorizations on standard CUD operations in both the programming models.

I hope this topic will be helpful for those who are transitioning from BOPF Model to RAP model and can easily compare different ABAP programming approach. In future posts, we will also see comparative analysis about UI developments and tools so stay tuned and please provide your feedback in the comment section.

 

 

 

Assigned Tags

      7 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Syambabu Allu
      Syambabu Allu

      Great Blog..Thank you for sharing in detailed.

      Thank you,

      Syam

      Author's profile photo Srinivas Rao
      Srinivas Rao

      Very nice blog post ! Really liked the way you have consolidated all the scenarios and how it can be achieved using BOPF and RAP...Thanks for this 🙂

      Author's profile photo Ashish Lodhi
      Ashish Lodhi

      Nice Blog Prabhjot Bhatia !

      Author's profile photo Wouter Peeters
      Wouter Peeters

      How is your overall feeling with the new RAP approach in comparison to BOPF? E.g. in regards to easiness of development and features.

      Author's profile photo Prabhjot Bhatia
      Prabhjot Bhatia
      Blog Post Author

      RAP is introduced to cover ABAP Programming for FIORI apps both in cloud as well as on premise. As compare to BOPF, I would say its relatively less complicated as far as multiple technical artifacts are concerned. Also, with the possibility of unmanaged and managed scenarios by selecting the appropriate implementation types, its very well arranged in RAP.

      Draft capabilities is another example which is easy to realise and easy to maintain in RAP.

      With service binding, its quite easy to create OData services even V4 services .

      For ABAP developers, EML is a new syntax to learn for RAP developments but its very well explained in SAP help portal and openSAP course for RAP programming model.

      Author's profile photo Weijian Chen
      Weijian Chen

      Thanks for sharing. Nice Blog!

      Author's profile photo Pritam Kunal
      Pritam Kunal

      nice blog, can you add message handling also on execution of custom actun button?