Skip to Content
Technical Articles

ABAP RAP : Enabling custom actions with a dialog for additional input fields

Prerequisites:

  • Knowledge on ABAP Restful Application Programming
  • Knowledge on Entity Manipulation Language (EML)
  • [Optional] Hands on exercises in OpenSAP course https://open.sap.com/courses/cp13.

This blog gives you an idea to develop a custom action with a dialog for additional input fields that are needed based on scenario.

  • Use case:
    • There is a purchase contract that needs to be extended to next year by buyer.
  • Business logic:
    • Only extend those validities which are running on existing valid to
      • [i.e. continue business with same supplier].
    • Don’t touch items which are older than existing valid to.
      • [i.e. no need to continue business with this supplier]

In my example: 

Old valid to: Jun 30, 2021

New valid to: Dec 31, 2021

Item #10 runs on Jun 30,2021 hence it is expected to extend till Dec 31, 2021

Item #20 ends on Mar 31, 2021 hence it is not expected to touch.

Click the button Extend and to see results on Object page and item page

 

Implementation steps:

  1. Create a data model with Header (Parent), Item (Child), Conditions (Grand Child) having fields “Valid from”, “Valid to “.
  2. Create an abstract CDS entity with required input fields.
@EndUserText.label: 'Abstract entity to extend the validity'
@Metadata.allowExtensions: true
define abstract entity ZRK_A_Doc_Extend 
 // with parameters parameter_name : parameter_type 
  {
    extend_till : /dmo/end_date;
    comments : abap.string( 300 );
    
}

3.Enrich the entity with UI annotations such as labels.

@Metadata.layer: #CORE
annotate entity ZRK_A_Doc_Extend
    with 
{
   @EndUserText.label: 'New validity to:'
   extend_till; 
   @EndUserText.label: 'Enter your comments:'
   comments;
    
}

4. In Behavior Definition, define action “extendDoc” with parameter using the abstract entity                created in step#2.

  action extendDoc parameter ZRK_A_Doc_Extend result [1] $self;

       5. Implement the core ABAP logic for extend in Behavior Pool Class

METHOD extendDoc.

    DATA : lt_update_doc  TYPE TABLE FOR UPDATE zrk_i_doc_head.
    DATA(lt_keys) = keys.
    DATA(lv_today) = cl_abap_context_info=>get_system_date( ).

    LOOP AT lt_keys ASSIGNING FIELD-SYMBOL(<fs_key>).

      IF <fs_key>-%param-extend_till < lv_today.

        APPEND VALUE #( %tky                = <fs_key>-%tky ) TO failed-head.

        APPEND VALUE #( %tky                = <fs_key>-%tky
                        %msg                = new_message(  id       = 'ZRK_CM_DOC'
                                                            number   = '001' " Document cannot be extended into the past
                                                            severity = if_abap_behv_message=>severity-error )
                        %element-ValidTo = if_abap_behv=>mk-on ) TO reported-head.

        DELETE lt_keys.


      ELSE.
        DATA(lv_new_valid_to) = <fs_key>-%param-extend_till.
      ENDIF.

    ENDLOOP.

    " Once the validations are passed, proceed with extending document.
    CHECK lt_keys IS NOT INITIAL.

    READ ENTITIES OF zrk_i_doc_head IN LOCAL MODE
        ENTITY Head
        FIELDS ( ValidFrom ValidTo )
        WITH CORRESPONDING #( keys )
        RESULT DATA(lt_doc_head).


    CHECK lt_doc_head IS NOT INITIAL.

    LOOP AT lt_doc_head ASSIGNING FIELD-SYMBOL(<fs_head>).

      " Capture old valid to
      DATA(lv_old_valid_to) = <fs_head>-ValidTo.

      " Read items from entity
      READ ENTITIES OF zrk_i_doc_head IN LOCAL MODE
          ENTITY Head BY \_Items
          FIELDS ( ValidFrom ValidTo )
          WITH VALUE #( ( %tky = <fs_head>-%tky ) )
          RESULT DATA(lt_items).

      " Loop through items that are running on old valid to
      LOOP AT lt_items ASSIGNING FIELD-SYMBOL(<fs_item>)
                            WHERE ValidFrom LE lv_old_valid_to
                               AND ValidTo GE lv_old_valid_to.

        " Modify item with new valid to
        <fs_item>-ValidTo = lv_new_valid_to.

        " Read conditions from entity
        READ ENTITIES OF zrk_i_doc_head IN LOCAL MODE
            ENTITY Items BY \_Conds
            FIELDS ( ValidFrom ValidTo )
            WITH VALUE #( ( %tky = <fs_item>-%tky ) )
            RESULT DATA(lt_conds).

            LOOP AT lt_conds ASSIGNING FIELD-SYMBOL(<fs_conds>)
                                    WHERE ValidFrom LE lv_old_valid_to
                                     AND ValidTo GE lv_old_valid_to..

              <fs_conds>-ValidTo = lv_new_valid_to.

            ENDLOOP.

            " Modify conditions entity
            MODIFY ENTITIES OF zrk_i_doc_head IN LOCAL MODE
                ENTITY Conds
                UPDATE FIELDS ( ValidTo )
                WITH CORRESPONDING #( lt_conds ).


      ENDLOOP.

      " Modify Items entity
      MODIFY ENTITIES OF zrk_i_doc_head IN LOCAL MODE
            ENTITY Items
            UPDATE FIELDS ( ValidTo )
            WITH CORRESPONDING #( lt_items ).


    ENDLOOP.

    " Modify header entity
    MODIFY ENTITIES OF zrk_i_doc_head IN LOCAL MODE
        ENTITY Head
        UPDATE
        FIELDS ( ValidTo )
        WITH VALUE #( FOR <fs_doc> IN lt_doc_head
                        ( %tky = <fs_doc>-%tky
                          validTo = COND #( WHEN lv_new_valid_to IS NOT INITIAL
                          THEN lv_new_valid_to
                          ELSE <fs_doc>-ValidTo )  ) )
        REPORTED DATA(lt_update_reported).

    reported = CORRESPONDING #( DEEP lt_update_reported ).

    " Return result to UI
    READ ENTITIES OF zrk_i_doc_head IN LOCAL MODE
        ENTITY Head
        ALL FIELDS
        WITH CORRESPONDING #( keys )
        RESULT lt_doc_head.

    result = VALUE #( FOR <fs_doc_head> IN lt_doc_head ( %tky = <fs_doc_head>-%tky
    %param = <fs_doc_head> ) ).

  ENDMETHOD.

6. Position the Action button on List Report and Object Page using annotations.

  @UI: {

  lineItem: [
      { type: #FOR_ACTION,  dataAction: 'ExtendDoc' , label: 'Extend' , position: 90 } ] ,

  identification : [
      { type: #FOR_ACTION,  dataAction: 'ExtendDoc' , label: 'Extend' , position: 90 } ]
  }

7. Generate the service Binding using OData V4 . [ If you use OData V2, then you have to enrich metadata in fiori app from webide or business studio ]

Service%20binding%20for%20document%20app%20with%20Odata%20V4

Service binding for document app with OData V4

Everything is set and its ready for user action:) Hope it helps in learning advanced ABAP RAP.

 

15 Comments
You must be Logged on to comment or reply to a post.
  • Hello Ramjee,

    I am trying to do basically the same thing, but for me it does not work as expected.

    I added a button using @UI.identification and UI.lineItem annotations, that should open a dialog box with input fields.

    I created the abstract entity :

    @EndUserText.label: 'Abstract Entity for Release Information'
    @Metadata.allowExtensions: true
    define abstract entity ZOV_A_SYSTEM_RELEASE {
    system_release : z_release_version;
    }

    and the metadata extension for UI labels:

    @Metadata.layer: #CORE
    annotate entity ZOV_A_SYSTEM_RELEASE with
    {
    @EndUserText.label: 'Release'
    system_release;

    }

     

    I added the action in the Behaviour definition:

    action SelectRelease parameter ZOV_A_SYSTEM_RELEASE;

     

    The result in my app is the following: the dialog box opens, I can see the field maintained in the abstract entity, but no annotations are taken into consideration. No label is displayed. Just the field as written in the entity ( system_release ), not even the description from the data element.

    Any idea what am I missing?

    • Hi Oana,

      Did you try to refresh the app ? Sometimes metadata reflection on UI takes more time.

      Is it in trail system so that I can have look ?

       

      Best wishes,

      Ramjee Korada

    • Hello Oana,

      It is just the version of your Odata binding type, use OData V4 - UI instead of V2

       

      So now its works, and there checkboxes instead of radiobuttons=)

      BR, Aynur

      • Hi Aynur,

        Thanks for highlighting. I was using V4 for quite sometime and did not realize that others might be using still V2.

        I have updated the blog with this point.

        BR,

        Ramjee

  • Thanks Ramjee for sharing. I'm not getting the popup being shown up although the abstract entity and its metadata is created properly. When triggering the action by pushing the corresponding button, it jumps directly to the behavior implementation where I can see the parameters defined in the abstract entity in blank (obviously 🙂 ) but no popup asks me for the input data.

    Would you have an idea about how I can solve it? I already refresh the system a couple of times 🙂

    Thx

  • Dear Ramjee,

    The popup and entity work fine, but there are some problems caused by changing binding type of my service to OData V4 - UI from V2.

    Those are currency and unit of measure assignments for fields. So the error popup is like this:

    How did manage this? And which data types did you use for that?

    BR, Aynur

     

    /
    • Hello Aynur,

      This problem is solved when you enter respective Uom ( for quantity ) , Currency for ( Amount ) in object page.

      However, It does not allow me to activate abstract entity with UoM field. 

      Once I added semantics, I am able to see the values entered from the dialog in debugging.

       

      BR,

      Ramjee

      • Hello Ramjee,

        Actually, I had problem with UOM fields using that annotation. In Odata V2 it was ok to use any type of amout (INT4, DEC 15/2), while here with Odata V4 it causes errors, like: invalid type '\TYPE=STRING'.

        Now, based on your screenshot I got that we should use 3 decimals after comma=)

        That worked! Thanks!

        BR, Aynur

        /
  • Hi Ramjee,

    Could you please explain, what needs to be added for OData V2 from the UI end ? Please try to provide a screenshot explanation for OData V2.

    Thanks,

    Vignesh.

  • Hi Ramjee,

     

    we use OData V2 in our project and changing to Odata V4 is not possible at the time.

    You wrote "If you use OData V2, then you have to enrich metadata in fiori app from webide or business studio". But I can't do this in my annotation file. Can you give an example, how this works?

     

    Thanks, Romina.

  • I am facing an issue

    When am trying to add an action . it is giving error in service binding  -  Duplicate action external name .

    There is no action with the same name . When am trying to expose the action in Behavior Implementation (Projection of Behavior Definition) . then this error comes, and without that the action button is not available in UI .

    Can you please help me.

     

    Thank you

    Regards

    Venkat Srikantan