Les Actions sont au coeur de la logique metier dans RAP. Mais quel type d’Action choisir et quand ? Cet article compare toutes les options de traitement et montre, a travers des exemples de reservation de vol, comment chaque type est implemente.
Vue d’ensemble des types d’Action
RAP propose differents types d’Actions pour differents cas d’utilisation :
| Type d’Action | Liaison | Objectif | Exemple |
|---|---|---|---|
| Instance Action | Liee a l’entite | Operation sur l’instance selectionnee | Annuler une reservation |
| Static Action | Pas de liaison d’instance | Operations en masse, creation | Liberer toutes les reservations en attente |
| Factory Action | Liee a l’entite | Creer une nouvelle instance a partir d’une existante | Copier une reservation |
| Action avec parametre | Instance ou Static | Entrees utilisateur avant execution | Annulation avec motif |
| Action avec resultat | Instance ou Static | Retour de donnees | Recalculer le prix |
Instance Action : Operation sur une entite
Les Instance Actions operent sur une ou plusieurs instances selectionnees. C’est le type d’Action le plus courant.
Behavior Definition
managed implementation in class zbp_i_flightbooking unique;strict ( 2 );
define behavior for ZI_FlightBooking alias FlightBookingpersistent table zflight_booklock masterauthorization master ( instance ){ create; update; delete;
// Instance Action sans parametre action confirmBooking result [1] $self;
// Instance Action avec retour de statut action cancelBooking result [1] $self;
// Instance Action sans resultat action markAsNoShow;}Implementation
CLASS lhc_flightbooking DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS confirmBooking FOR MODIFY IMPORTING keys FOR ACTION FlightBooking~confirmBooking RESULT result.
METHODS cancelBooking FOR MODIFY IMPORTING keys FOR ACTION FlightBooking~cancelBooking RESULT result.
METHODS markAsNoShow FOR MODIFY IMPORTING keys FOR ACTION FlightBooking~markAsNoShow.ENDCLASS.
CLASS lhc_flightbooking IMPLEMENTATION. METHOD confirmBooking. " Confirmer les reservations MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking UPDATE FIELDS ( booking_status ) WITH VALUE #( FOR key IN keys ( %tky = key-%tky booking_status = 'C' " Confirmed ) ).
" Lire les donnees mises a jour READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
" Retourner le resultat result = VALUE #( FOR booking IN bookings ( %tky = booking-%tky %param = booking ) ).
" Message de succes APPEND VALUE #( %msg = new_message_with_text( severity = if_abap_behv_message=>severity-success text = |{ lines( bookings ) } reservation(s) confirmee(s)| ) ) TO reported-flightbooking. ENDMETHOD.
METHOD cancelBooking. " D'abord verifier si l'annulation est autorisee READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking FIELDS ( booking_status flight_date ) WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
LOOP AT bookings INTO DATA(booking). " Seules les reservations ouvertes ou confirmees peuvent etre annulees IF booking-booking_status <> 'O' AND booking-booking_status <> 'C'. APPEND VALUE #( %tky = booking-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = |La reservation au statut { booking-booking_status } ne peut pas etre annulee| ) ) TO reported-flightbooking. APPEND VALUE #( %tky = booking-%tky ) TO failed-flightbooking. CONTINUE. ENDIF.
" Effectuer l'annulation MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking UPDATE FIELDS ( booking_status cancellation_date ) WITH VALUE #( ( %tky = booking-%tky booking_status = 'X' " Cancelled cancellation_date = cl_abap_context_info=>get_system_date( ) ) ). ENDLOOP.
" Lire et retourner le resultat READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(updated_bookings).
result = VALUE #( FOR bk IN updated_bookings ( %tky = bk-%tky %param = bk ) ). ENDMETHOD.
METHOD markAsNoShow. " Action simple sans retour de resultat MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking UPDATE FIELDS ( booking_status no_show_date ) WITH VALUE #( FOR key IN keys ( %tky = key-%tky booking_status = 'N' " No-Show no_show_date = cl_abap_context_info=>get_system_date( ) ) ).
" Seulement un message, pas de result APPEND VALUE #( %msg = new_message_with_text( severity = if_abap_behv_message=>severity-success text = 'Marque comme No-Show' ) ) TO reported-flightbooking. ENDMETHOD.ENDCLASS.Cardinalite du Result
| Syntaxe | Signification | Utilisation |
|---|---|---|
result [1] $self | Exactement une instance de la meme entite | Standard pour les changements de statut |
result [0..1] $self | Optionnellement une instance | Quand le resultat n’est pas garanti |
result [0..*] $self | N’importe quel nombre d’instances | Operations en masse |
result [1] EntityName | Une autre entite | Navigation vers une entite associee |
| (pas de result) | Pas de retour | Operations fire-and-forget |
Static Action : Operations en masse et creation
Les Static Actions ne sont pas liees a une instance. Elles sont typiquement utilisees pour des operations globales.
Behavior Definition
define behavior for ZI_FlightBooking alias FlightBooking{ // Static Action pour operation en masse static action releaseAllPending;
// Static Action avec resultat static action createQuickBooking result [1] $self;
// Static Action avec Feature Control static action ( features: global ) sendDailyReport;
// Pour le Global Feature Control static features;}Implementation
CLASS lhc_flightbooking IMPLEMENTATION. METHOD releaseAllPending. " Trouver toutes les reservations avec statut 'Pending" SELECT * FROM zflight_book WHERE booking_status = 'P" INTO TABLE @DATA(pending_bookings).
IF pending_bookings IS INITIAL. APPEND VALUE #( %msg = new_message_with_text( severity = if_abap_behv_message=>severity-information text = 'Aucune reservation en attente trouvee' ) ) TO reported-flightbooking. RETURN. ENDIF.
" Mettre tous en 'Confirmed" MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking UPDATE FIELDS ( booking_status ) WITH VALUE #( FOR booking IN pending_bookings ( booking_id = booking-booking_id booking_status = 'C' " Confirmed ) ).
APPEND VALUE #( %msg = new_message_with_text( severity = if_abap_behv_message=>severity-success text = |{ lines( pending_bookings ) } reservations liberees| ) ) TO reported-flightbooking. ENDMETHOD.
METHOD createQuickBooking. " Creer une reservation rapide avec valeurs par defaut DATA(today) = cl_abap_context_info=>get_system_date( ). DATA(user) = cl_abap_context_info=>get_user_technical_name( ).
MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking CREATE FIELDS ( flight_date customer_id flight_id booking_status flight_price currency_code created_by created_at ) WITH VALUE #( ( %cid = 'QUICK_BOOKING" flight_date = today + 14 " Dans 2 semaines customer_id = get_default_customer( user ) flight_id = get_next_available_flight( today + 14 ) booking_status = 'P' " Pending flight_price = 299 currency_code = 'EUR" created_by = user created_at = cl_abap_context_info=>get_system_time( ) ) ) MAPPED DATA(mapped).
" Lire la reservation creee READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking ALL FIELDS WITH VALUE #( ( %tky = mapped-flightbooking[ 1 ]-%tky ) ) RESULT DATA(created_bookings).
" Retourner le resultat avec %cid_ref result = VALUE #( ( %cid_ref = 'QUICK_BOOKING" %param = created_bookings[ 1 ] ) ).
APPEND VALUE #( %msg = new_message_with_text( severity = if_abap_behv_message=>severity-success text = 'Reservation rapide creee' ) ) TO reported-flightbooking. ENDMETHOD.
METHOD get_global_features. " Verifier si l'utilisateur a l'autorisation pour le rapport DATA(has_report_auth) = check_report_authorization( ).
result = VALUE #( %action-sendDailyReport = COND #( WHEN has_report_auth = abap_true THEN if_abap_behv=>fc-o-enabled ELSE if_abap_behv=>fc-o-disabled ) ). ENDMETHOD.ENDCLASS.Factory Action : Nouvelle instance a partir d’une existante
Les Factory Actions creent une nouvelle instance basee sur une existante. Ideal pour les scenarios de copie et de modeles.
Behavior Definition
define behavior for ZI_FlightBooking alias FlightBooking{ // Factory Action cree une copie factory action copyBooking [1];
// Factory Action avec parametres factory action rebookToDate parameter ZA_RebookParams [1];}Implementation
CLASS lhc_flightbooking IMPLEMENTATION. METHOD copyBooking. " Lire les reservations originales READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
DATA: lt_mapped TYPE RESPONSE FOR MAPPED EARLY zi_flightbooking.
LOOP AT bookings INTO DATA(booking). DATA(lv_cid) = |COPY_{ sy-tabix }|.
" Creer une copie avec nouveau statut MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking CREATE FIELDS ( flight_date customer_id flight_id flight_price currency_code booking_status created_by created_at ) WITH VALUE #( ( %cid = lv_cid flight_date = booking-flight_date customer_id = booking-customer_id flight_id = booking-flight_id flight_price = booking-flight_price currency_code = booking-currency_code booking_status = 'P' " Nouvelle reservation en Pending created_by = cl_abap_context_info=>get_user_technical_name( ) created_at = cl_abap_context_info=>get_system_time( ) ) ) MAPPED DATA(mapped_single).
" Agreger mapped APPEND VALUE #( %cid_ref = keys[ sy-tabix ]-%cid_ref %key = mapped_single-flightbooking[ 1 ]-%key ) TO mapped-flightbooking. ENDLOOP.
APPEND VALUE #( %msg = new_message_with_text( severity = if_abap_behv_message=>severity-success text = |{ lines( bookings ) } reservation(s) copiee(s)| ) ) TO reported-flightbooking. ENDMETHOD.
METHOD rebookToDate. " Lire les reservations originales READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
LOOP AT keys ASSIGNING FIELD-SYMBOL(<key>). READ TABLE bookings INTO DATA(booking) WITH KEY booking_id = <key>-booking_id.
" Nouvelle date depuis le parametre DATA(new_date) = <key>-%param-NewFlightDate.
" Validation IF new_date < cl_abap_context_info=>get_system_date( ). APPEND VALUE #( %tky = <key>-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'La nouvelle date doit etre dans le futur' ) ) TO reported-flightbooking. APPEND VALUE #( %tky = <key>-%tky ) TO failed-flightbooking. CONTINUE. ENDIF.
" Creer une nouvelle reservation avec la nouvelle date DATA(lv_cid) = |REBOOK_{ sy-tabix }|.
MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking CREATE FIELDS ( flight_date customer_id flight_id flight_price currency_code booking_status original_booking_id ) WITH VALUE #( ( %cid = lv_cid flight_date = new_date customer_id = booking-customer_id flight_id = booking-flight_id flight_price = booking-flight_price currency_code = booking-currency_code booking_status = 'P' " Pending original_booking_id = booking-booking_id " Reference a la reservation originale ) ) MAPPED DATA(mapped_single).
" Mettre la reservation originale en 'Rebooked" MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking UPDATE FIELDS ( booking_status ) WITH VALUE #( ( %tky = <key>-%tky booking_status = 'R' " Rebooked ) ).
APPEND VALUE #( %cid_ref = <key>-%cid_ref %key = mapped_single-flightbooking[ 1 ]-%key ) TO mapped-flightbooking. ENDLOOP. ENDMETHOD.ENDCLASS.Action avec parametre de resultat
Les Actions peuvent retourner des resultats structures qui vont au-dela de $self.
Abstract Entity pour le resultat
@EndUserText.label: 'Resultat de calcul de prix"define abstract entity ZA_PriceCalculation{ BookingId : abap.numc(10); NetPrice : abap.curr(15,2); TaxAmount : abap.curr(15,2); TotalPrice : abap.curr(15,2); Currency : abap.cuky; DiscountPct : abap.dec(5,2); DiscountText : abap.string(100);}Behavior Definition
define behavior for ZI_FlightBooking alias FlightBooking{ // Action avec type de resultat propre action recalculatePrice result [1] ZA_PriceCalculation;
// Action qui retourne une autre entite action createInvoice result [1] ZI_Invoice;}Implementation
METHOD recalculatePrice. " Lire les donnees de reservation READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking FIELDS ( booking_id flight_price currency_code customer_id ) WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
LOOP AT bookings INTO DATA(booking). " Determiner la remise client DATA(discount_pct) = get_customer_discount( booking-customer_id ). DATA(net_price) = booking-flight_price * ( 1 - discount_pct / 100 ). DATA(tax_amount) = net_price * '0.19'. DATA(total_price) = net_price + tax_amount.
" Mettre a jour le prix dans la reservation MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking UPDATE FIELDS ( flight_price ) WITH VALUE #( ( %tky = booking-%tky flight_price = total_price ) ).
" Remplir la structure de resultat APPEND VALUE #( %tky = booking-%tky %param = VALUE za_pricecalculation( BookingId = booking-booking_id NetPrice = net_price TaxAmount = tax_amount TotalPrice = total_price Currency = booking-currency_code DiscountPct = discount_pct DiscountText = COND #( WHEN discount_pct > 0 THEN |Remise fidelite : { discount_pct }%| ELSE 'Pas de remise' ) ) ) TO result. ENDLOOP.ENDMETHOD.Gestion des erreurs dans les Actions
Les Actions robustes doivent gerer correctement les erreurs et les signaler a l’utilisateur.
Pattern : Validation avant execution
METHOD processBooking. DATA: lt_failed TYPE TABLE FOR FAILED EARLY zi_flightbooking, lt_reported TYPE TABLE FOR REPORTED EARLY zi_flightbooking.
" Lire les reservations READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
LOOP AT bookings INTO DATA(booking). " === PHASE DE VALIDATION ===
" Erreur 1 : Verifier le statut IF booking-booking_status = 'X'. APPEND VALUE #( %tky = booking-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Les reservations annulees ne peuvent pas etre traitees' ) ) TO lt_reported. APPEND VALUE #( %tky = booking-%tky ) TO lt_failed. CONTINUE. ENDIF.
" Erreur 2 : Verifier la date IF booking-flight_date < cl_abap_context_info=>get_system_date( ). APPEND VALUE #( %tky = booking-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'La date de vol est dans le passe' ) %element-flight_date = if_abap_behv=>mk-on ) TO lt_reported. APPEND VALUE #( %tky = booking-%tky ) TO lt_failed. CONTINUE. ENDIF.
" Avertissement : Prix eleve IF booking-flight_price > 2000. APPEND VALUE #( %tky = booking-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-warning text = |Prix superieur a 2 000 { booking-currency_code }| ) %element-flight_price = if_abap_behv=>mk-on ) TO lt_reported. " PAS d'entree failed pour Warning ! ENDIF.
" === PHASE D'EXECUTION === TRY. " Executer la logique metier MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking UPDATE FIELDS ( booking_status processed_at ) WITH VALUE #( ( %tky = booking-%tky booking_status = 'D' " Done processed_at = cl_abap_context_info=>get_system_time( ) ) ).
CATCH cx_root INTO DATA(lx_error). " Erreur inattendue APPEND VALUE #( %tky = booking-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = |Erreur systeme : { lx_error->get_text( ) }| ) ) TO lt_reported. APPEND VALUE #( %tky = booking-%tky ) TO lt_failed. ENDTRY. ENDLOOP.
" Transmettre les erreurs et messages failed-flightbooking = lt_failed. reported-flightbooking = lt_reported.
" Resultat pour les reservations reussies READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(updated_bookings).
result = VALUE #( FOR bk IN updated_bookings WHERE ( booking_status = 'D' ) ( %tky = bk-%tky %param = bk ) ).ENDMETHOD.Pattern : Succes partiels
METHOD batchProcess. DATA: lv_success_count TYPE i, lv_error_count TYPE i.
READ ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(bookings).
LOOP AT bookings INTO DATA(booking). IF can_process( booking ). " Traiter MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ENTITY FlightBooking UPDATE FIELDS ( booking_status ) WITH VALUE #( ( %tky = booking-%tky booking_status = 'D' ) ).
lv_success_count = lv_success_count + 1. ELSE. " Collecter les erreurs mais continuer APPEND VALUE #( %tky = booking-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = |Reservation { booking-booking_id } : Traitement impossible| ) ) TO reported-flightbooking. APPEND VALUE #( %tky = booking-%tky ) TO failed-flightbooking.
lv_error_count = lv_error_count + 1. ENDIF. ENDLOOP.
" Message recapitulatif IF lv_success_count > 0 AND lv_error_count > 0. APPEND VALUE #( %msg = new_message_with_text( severity = if_abap_behv_message=>severity-warning text = |{ lv_success_count } traite(s), { lv_error_count } echec(s)| ) ) TO reported-flightbooking. ELSEIF lv_success_count > 0. APPEND VALUE #( %msg = new_message_with_text( severity = if_abap_behv_message=>severity-success text = |{ lv_success_count } reservations traitees| ) ) TO reported-flightbooking. ENDIF.ENDMETHOD.Matrice de decision : Quelle Action quand ?
| Exigence | Type d’Action | Exemple |
|---|---|---|
| Changement de statut d’une reservation | Instance Action | confirmBooking, cancelBooking |
| Liberer toutes les reservations ouvertes | Static Action | releaseAllPending |
| Copier une reservation | Factory Action | copyBooking |
| Annulation avec motif | Instance Action + Parametre | cancelWithReason |
| Nouvelle reservation sans modele | Static Action + Result | createQuickBooking |
| Report a une nouvelle date | Factory Action + Parametre | rebookToDate |
| Recalculer et afficher le prix | Instance Action + Result Entity | recalculatePrice |
| Creer une facture depuis une reservation | Instance Action + autre entite | createInvoice |
Quand Instance vs. Static ?
┌─────────────────────────────────────────────────────────────────┐│ L'Action a-t-elle besoin ││ du contexte d'instance ? ││ │ ││ ┌───────────┴───────────┐ ││ │ │ ││ ▼ ▼ ││ [ OUI ] [ NON ] ││ │ │ ││ ┌──────────┴──────────┐ │ ││ │ │ ▼ ││ ▼ ▼ STATIC ACTION ││ Cree une nouvelle Modifie une ││ instance ? existante ? ││ │ │ ││ ▼ ▼ ││ FACTORY INSTANCE ││ ACTION ACTION │└─────────────────────────────────────────────────────────────────┘Quand avec ou sans parametre ?
| Scenario | Avec parametre | Sans parametre |
|---|---|---|
| Entree utilisateur requise | Dialogue popup | |
| Confirmation sans details | Execution directe | |
| Infos supplementaires optionnelles | Parametre avec defauts | |
| Action avec choix | Parametre avec Value Help |
Quand utiliser Result ?
| Scenario | Type de Result |
|---|---|
| L’UI doit etre mise a jour | result [1] $self |
| Fire-and-Forget | Pas de Result |
| Afficher le resultat du calcul | result [1] ZA_ResultEntity |
| Operation en masse avec resultats individuels | result [0..*] $self |
| Entite associee creee | result [1] OtherEntity |
Bonnes pratiques
1. Convention de nommage coherente
" Verbes pour les Actionsaction confirmBooking ...action cancelBooking ...action recalculatePrice ...
" Eviter les substantifsaction confirmation ... " Pas clair ce qui se passeaction cancellation ...2. Toujours specifier Result pour le rafraichissement UI
" L'UI est mise a jour apres l'Actionaction confirmBooking result [1] $self;
" L'UI reste sur l'ancien etataction confirmBooking; " Sans result3. Detecter les erreurs tot
METHOD myAction. " Validation D'ABORD, avant toute modification READ ENTITIES ... LOOP AT ... IF NOT valid( ). " Signaler l'erreur et CONTINUE CONTINUE. ENDIF. ENDLOOP.
" Seulement apres la validation : effectuer les modifications MODIFY ENTITIES ...ENDMETHOD.4. Utiliser IN LOCAL MODE
" Contourne la verification d'autorisation au sein de l'ActionREAD ENTITIES OF zi_flightbooking IN LOCAL MODE ...MODIFY ENTITIES OF zi_flightbooking IN LOCAL MODE ...5. Combiner avec Feature Control
" Behavior Definitionaction ( features: instance ) cancelBooking result [1] $self;determination setFeatures on modify { field booking_status; }
" Implementation : cancelBooking active seulement pour les reservations ouvertesResume
| Type d’Action | Quand l’utiliser | Keys presentes | Cree une instance |
|---|---|---|---|
| Instance | Operation sur la selection | Oui | Non |
| Static | Operation globale | Non | Optionnel |
| Factory | Copie, modeles | Oui | Oui |
Le bon choix du type d’Action fait la difference entre une interface utilisateur intuitive et une confuse. Utilisez les Instance Actions pour les operations individuelles, les Static Actions pour les actions globales et les Factory Actions pour creer de nouvelles instances a partir d’existantes.
Articles complementaires : RAP Actions et Functions pour les fondamentaux, Actions avec Popup pour les Actions avec dialogue, Messages RAP pour la gestion des erreurs et Feature Control pour l’activation dynamique.