Introduction
Dans notre dernier article (lien) nous avions vu comment les tables entities nous permettraient de simplifier la création de nos CDS en combinant les fonctionnalités des tables classiques DDIC et des CDS en 1 seul objet.
Cependant, nous relevions le fait qu’il était encore impossible de créer des opérations de modification sur ces Business Object via RAP.
- Il est désormais possible d’implémenter et de développer des opérations transactionelles en utilisant RAP avec les table entities, et d’appeler cet objet via EML dans des programmes ABAP ou via OData dans des applications Fiori/Web API.
- Nous verrons également les limitations que nous avons rencontré lors de nos tests.
- Dans cet exemple, nous reprendrons le cas que nous avions développé et visible sur notre GitLab.
Les modifications apportées à ces objets sont également disponibles sur un nouveau repository.
I. Créer les BDEF
Pour rappel, notre exemple représentait les différentes commande reçues par une boulangerie.
Pour cela, nous avons d’abord essayé en utilisant le RAP Generator Object comme vu dans un précédent article (lien), mais il semblerait qu’il ne soit pas encore possible d’effectuer ces créations en automatique pour l’instant.


Nous créons donc manuellement les 2 BDEF qui nous intéressent pour représenter nos commandes et les items associés.
Dans le but de simplifier l’exemple, nous n’ajoutons pas l’association avec la table entity représentant les pâtisseries référencée dans la boulangerie mais nous aborderons ce sujet dans un article prochain évoquant les cross associations désormais disponible en RAP.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
managed implementation in class zbp_i_bakery_orders unique; strict ( 2 ); //with cross associations; define behavior for ZI_BAKERY_ORDERS //alias <alias_name> lock master authorization master ( instance ) //etag master <field_name> { create ( authorization : global ); update; delete; field ( readonly ) uuid; field ( numbering : managed ) uuid; association _bakeryOrdersItems { create; } } define behavior for ZI_BAKERY_ORDERS_ITEMS //alias <alias_name> lock dependent by _bakeryOrders authorization dependent by _bakeryOrders //etag master <field_name> { update; delete; field ( readonly ) uuid, item; //, pastryid; field ( numbering : managed ) item; association _bakeryOrders; // association _pastry abbreviation pastry // { // create; // link action link_pastry; // unlink action unlink_pastry; // inverse function inverse_function; // } } |
Ici nous pouvons voir que nous avons les définitions des opérations nécessaires.
Comme chaque ligne de commande est identifié par un UUID unique, nous le générons en automatique via un numbering (managed).
Idem pour le UUID des items (chaque item referencé a un UUID d’une commande à son propre UUID unique).
Également, nous avons activé le create-by-association sur notre composition.
Comme pour n’importe quel autre objet rap managed, il est ensuite possible d’ajouter des validations, determinations, checks d’autorisations, actions, etc…
A noter :
- Nous n’avons pas activé le draft sur cet objet RAP, car les tables entities ne supportent pas encore cette fonctionnalité (lien). Cependant il aurait été possible de créer manuellement une table qui aurait été utilisée pour sauvegarder les drafts.
- Nous avons du remplacé le type enum dans notre table entity ZC_NAKERY_ORDERS_ITEMS car non supporté.

II. Tests
1. Test EML
Nous avons créé ici un petit cas de test qui montre que suite à la création de cet objet RAP, nous pouvons interagir avec le BO via EML.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
CLASS zcl_test_table_entities DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_oo_adt_classrun . PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_test_table_entities IMPLEMENTATION. METHOD if_oo_adt_classrun~main. DATA lt_test TYPE TABLE FOR CREATE zi_bakery_orders. DATA lt_orders TYPE TABLE FOR CREATE zi_bakery_orders. DATA lt_items TYPE TABLE FOR CREATE zi_bakery_orders\_bakeryOrdersItems. " Create parent order lt_orders = VALUE #( ( %cid = '1' deliveryAddress = '1 rue du test - Lille' orderDate = '20251001' %control = VALUE #( deliveryAddress = if_abap_behv=>mk-on orderDate = if_abap_behv=>mk-on ) ) ). " Create child items via association lt_items = VALUE #( ( %cid_ref = '1' %target = VALUE #( ( %cid = '1-1' quantity = 2 unit = 'PC' amount = 10 currency = 'EUR' pastryid = '1111' %control = VALUE #( quantity = if_abap_behv=>mk-on unit = if_abap_behv=>mk-on amount = if_abap_behv=>mk-on currency = if_abap_behv=>mk-on pastryid = if_abap_behv=>mk-on ) ) ) ) ). MODIFY ENTITIES OF zi_bakery_orders ENTITY zi_bakery_orders CREATE FROM lt_orders ENTITY zi_bakery_orders CREATE BY \_bakeryOrdersItems FROM lt_items FAILED DATA(lt_failed) REPORTED DATA(lt_reported) MAPPED DATA(lt_mapped). COMMIT ENTITIES. ENDMETHOD. ENDCLASS. |
- Via une opération create : nous créons une commande
- Via une opération create-by-entity : Nous créons un item à la commande

Ces données sont bien sauvegardées dans les CDS entities.


2. Test OData et Fiori
Nous avons également créé une application Fiori en utilisant l’outil de création via ADT.

Mais il semblerait que le trial BTP ait quelques soucis pour le moment, nous mettrons à jour l’article une fois la correction effectuée par SAP.

Idem avec le swagger :


Conclusion
Vous pouvez désormais utiliser les cds tables entities comme objet RAP pour toutes les opérations CRUD.
Il reste encore quelques détails à apporter à cette nouvelle fonctionnalité, mais ça ne saurait tarder.