EML – PART II

Treatment in progress…
You're done! You are in the list.

In this article, we’ll continue to look at how to interact with Business Objects created via ABAP RAP. To do this, we’ll be using EML (Entity Manipulation Language), part of the ABAP language, to access RAP BOs.

We will discuss :

  • Instance actions: Defines a RAP action that offers non-standard behavior. By default, an action relates to an instance of a RAP BO entity and modifies the state of the instance ( There are also static actions, which we won’t go into: Static actions are not linked to an instance of a RAP BO entity, but concern the entire entity ).
  • Factory actions : Factory actions are used to create instances of RAP BO entities. Their purpose is to copy specific values from an existing instance (there are also static factory actions, which we won’t go into here: they are used to create instances with pre-populated default values).
  • Deep insert: Here’s an example of how to create an instance and its child entities in a single EML declaration.

The code is available on Abapeur’s GitLab.

For our example, we’ll use the demo RAP BO provided by SAP on BTP, ABAP Environment: /DMO/I_Travel_M

Example 1 : Instance Action

Here we’ll use the “acceptTravel” action. This action will accept a trip by changing its status from “O” to “A” in the /DMO/TRAVEL_M table:

Before executing the EML:

Code:

    DATA : keys          TYPE TABLE FOR ACTION IMPORT /DMO/I_Travel_M~acceptTravel.

    keys = VALUE #( ( %tky-%key-travel_id = '00002772' )
                    ( %tky-%key-travel_id = '00002815' ) ).


    MODIFY ENTITY /DMO/I_Travel_M
        EXECUTE acceptTravel FROM VALUE #( FOR key IN keys INDEX INTO idx (
                                                                    %key = CORRESPONDING #( key )
                                                                    ) )
        RESULT DATA(result)
        FAILED DATA(failed)
        REPORTED DATA(reported).

    COMMIT ENTITIES
    RESPONSE OF /dmo/i_travel_m
    FAILED DATA(failed_commit)
    REPORTED DATA(reported_commit).

We see here in debug that in the output parameter RESULT, the OVERALL_STATUS is changed to “A”.

Note: the return parameter can be configured in the behavior definition. Here, it’s a RESULT of type “$self”, i.e. a return of the same type as the entity itself.

After COMMIT:

Example 2 : Factory action

The “copyTravel” action is used to create a new instance of the entity by copying an existing instance.

    DATA : keys          TYPE TABLE FOR ACTION IMPORT /DMO/I_Travel_M~copyTravel.

    keys = VALUE #( (
    %cid = '1'
    %tky-%key-travel_id = '00002772' ) ).


    MODIFY ENTITY /DMO/I_Travel_M
        EXECUTE copyTravel FROM keys
        MAPPED DATA(mapped)
        FAILED DATA(failed)
        REPORTED DATA(reported).

    COMMIT ENTITIES
    RESPONSE OF /dmo/i_travel_m
    FAILED DATA(failed_commit)
    REPORTED DATA(reported_commit).

Here we copy the instance of the “travel_id” 00002772.

In this case, as it’s a creation, we must use the %CID in the same way as for a CREATE ( See explanations in part I ).

In debug :

After COMMIT:

Example 3 : Deep Insert

Here we’re going to create a Travel and an associated Booking, all in a single call.

As we’re creating these in a single call, there will be no COMMIT between the creation of the Travel and the Booking. We therefore need to specify in the %CID_REF field the %CID used to create the Travel. In this way, we refer to the unique ID in memory of the Travel being created, and can associate the desired Booking with it.

    DATA:
      travels      TYPE TABLE FOR CREATE /DMO/I_Travel_M\\travel,
      bookings_cba TYPE TABLE FOR CREATE /DMO/I_Travel_M\\travel\_booking.

    travels = VALUE #( ( %cid = '1'
                                    agency_id = '070049'
                                    customer_id = '000072'
                                    begin_date = cl_abap_context_info=>get_system_date( ) + 1
                                    end_date = cl_abap_context_info=>get_system_date( ) + 2
                                    overall_status = 'O'
                                    %control = VALUE #( agency_id = if_abap_behv=>mk-on
                                                        customer_id = if_abap_behv=>mk-on
                                                        begin_date = if_abap_behv=>mk-on
                                                        end_date = if_abap_behv=>mk-on
                                                        overall_status = if_abap_behv=>mk-on )
                                 ) ).
    bookings_cba =  value #( (  %cid_ref  = '1'      "refers to the root (travel instance)
                         %target   = value #( (  %cid = '1_1' " Preliminary ID for new booking instance
                                                           carrier_id = '111'
                                                           connection_id = '1234'
                                                           Customer_ID = '000006'
                                                           Flight_Date = cl_abap_context_info=>get_system_date( ) + 10
                                                           booking_date = cl_abap_context_info=>get_system_date( )
                                                           booking_status = 'B' ) ) ) ).

    MODIFY ENTITIES OF /DMO/I_Travel_M
      ENTITY travel
        CREATE FIELDS ( agency_id customer_id begin_date end_date booking_fee total_price currency_code overall_status description )
          WITH travels
        CREATE BY \_Booking FIELDS ( booking_date customer_id carrier_id connection_id flight_date booking_status )
          WITH bookings_cba
          MAPPED DATA(mapped)
          FAILED DATA(failed)
          REPORTED DATA(reported).

    COMMIT ENTITIES
    RESPONSE OF /dmo/i_travel_m
    FAILED DATA(failed_commit)
    REPORTED DATA(reported_commit).

Here we create the Travels and Bookings_cba variables and make a single call to create the 2 at once using “MODIFY ENTITIES OF /DMO/I_Travel_M ENTITY travel” and “CREATE BY _Booking”.

Conclusion

Here we’ve taken a look at more advanced EML concepts, analyzing the workings of Actions and Deep Inserts.