Dans cet article, nous allons continuer de voir comment interagir avec les Business Objects créés via ABAP RAP. Pour cela, nous utilisons EML ( Entity Manipulation Language ) qui fait partie du langage ABAP, et permet d’accéder aux BO RAP.
Nous aborderons les :
- Instance actions : Définit une action RAP qui offre un comportement non standard. Par défaut, une action se rapporte à une instance d’entité RAP BO et modifie l’état de l’instance ( Il existe également les static actions que nous n’aborderons pas : Les actions statiques ne sont pas liées à une instance d’une entité RAP BO, mais concernent l’entité complète ).
- Factory actions : Les factory actions sont utilisées pour créer des instances d’entités RAP BO. Leur objectif est de copier des valeurs spécifiques d’une instance existante ( Il existe également les static factory actions que nous n’aborderons pas : elles sont utilisées pour créer des instances avec des valeurs par défaut pré-remplies ).
- Deep insert : Nous allons voir un exemple de création d’instance et de ses entités enfant crées en une seule déclaration EML.
Le code est disponible sur le GitLab de Abapeur.
Pour notre exemple, nous allons utiliser le RAP BO de démo mis à disposition par SAP sur BTP, ABAP Environment : /DMO/I_Travel_M

Exemple 1 : Instance Action
Ici nous allons utiliser l’action « acceptTravel ». Cette action va permettre d’accepter un voyage en passant le statut de « O » a « A » dans la table /DMO/TRAVEL_M :
Avant exécution de l’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).

Nous voyons ici en debug que dans le output parameter RESULT, le OVERALL_STATUS est changé a « A ».
Note : Le paramètre de retour peut être configure dans le behavior definition, ici c’est précise un RESULT de type « $self » soit un retour du même type que l’entité elle-même

Après le COMMIT :

Exemple 2 : Factory action
L’action « copyTravel » va être utiliser pour créer une nouvelle instance de l’entité en copiant une instance existante.
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).
Ici nous copions l’instance du « travel_id » 00002772.
Dans ce cas, comme il s’agit d’une création, nous devons utiliser le %CID de la même manière que lors d’un CREATE ( Voir explications dans la partie I ).
En debug :

Après le COMMIT :

Exemple 3 : Deep Insert
Ici nous allons creer un Travel et un Booking associé, le tout dans un seul appel.
Comme nous faisons ces créations dans un seul appels, il n’y aura pas de COMMIT entre la création du Travel et celui du Booking. Il faut donc préciser dans le champs %CID_REF le %CID utilisé pour créer le Travel. Ainsi nous faisons référence a l’ID unique en mémoire du Travel en cours de création et pouvons y associer le Booking souhaité.
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).
Ici nous créons les variables Travels et Bookings_cba et faisons un seul appel pour créer les 2 d’un coup en utilisant « MODIFY ENTITIES OF /DMO/I_Travel_M ENTITY travel » et « CREATE BY \_Booking«

Conclusion
Nous avons pu voir ici des notions plus avancées en EML en analysant le fonctionnement des Actions et des Deep Insert.