Skip to content

Latest commit

 

History

History
698 lines (448 loc) · 35.9 KB

README.md

File metadata and controls

698 lines (448 loc) · 35.9 KB

Home - RAP110

Exercise 3: Enhance the BO Behavior Definition and Projection

Introduction

In the previous exercise, you've enhanced the data model of the base Travel BO entity, the projected Travel BO entity, and the projected booking BO entity (see Exercise 2).

In this exercise, you will enhance the transactional behavior of your Travel BO. You will define the Late Numbering for drawing the primary of the travel and the booking entities, the static and dynamic feature control for fields, standard and nonstandard operations, validations, instance and factory actions, determinations, and functions.

Exercises:

Reminder: Do not forget to replace the suffix placeholder ### with your assigned suffix in the exercise steps below.

About Numbering | Validations | Actions | Determinations | Functions | Dynamic Feature Control

ℹ Click to expand!

Numbering

ℹ Click to expand!

Numbering is about setting values for primary key fields of entity instances during runtime. Different types of numbering are supported in RAP which can be divided into two main categories:

  • Early numbering: In an early numbering scenario, the primary key value is set instantly after the modify request for the CREATE is executed. The key values can be passed externally by the consumer or can be set internally by the framework or an implementation of the FOR NUMBERING method.
  • Late numbering: In a late numbering scenario, the key values are always assigned internally without consumer interaction after the point of no return in the interaction phase has passed, and the SAVE sequence is triggered. The latter will be implemented in the present exercise

Further reading: Numbering

Frontend validation & Backend validations

ℹ Click to expand!

Validations are used to ensure the data consistency.
As the name suggests, front-end validations are performed on the UI. They are used to improve the user experience by providing faster feedback and avoiding unnecessary roundtrips. In the RAP context, front-end validations are defined using CDS annotation or UI logic.
On the other hand, back-end validations are performed on the back-end. They are defined in the BO behavior definitions and implemented in the respective behavior pools.
Frontend validations can be easily bypassed - e.g. by using EML APIs in the RAP context. Therefore, backend validations are a MUST to ensure the data consistency.

In RAP, front-end validations are defined with the attribute usedForValidation in value helps defined with the element annotation @Consumption.valueHelpDefinition.

Further reading: Validations

Actions

ℹ Click to expand!

In the RAP context, an action is a non-standard operation that change the data of a BO instance.

Actions are specified in behavior definitions and implemented in ABAP behavior pools. By default, actions are related to instances of a BO entity. The addition static allows you to define a static actions that are not bound to any instance but relates to the complete entity. The addition internal define a private action that can only be called within the given BO.

Two main categories of actions can be implemented in RAP:

  • Non-factory actions: Defines a RAP action which offers non-standard behavior. The custom logic must be implemented in the RAP handler method FOR MODIFY. An action per default relates to a RAP BO entity instance and changes the state of the instance. An action is related to an instance by default. Non-factory actions can be instance-bound (default) or static.
  • Factory actions: Factory actions are used to create RAP BO entity instances. Factory actions can be instance-bound (default) or static. Instance-bound factory actions can copy specific values of an instance. Static factory actions can be used to create instances with prefilled default values.

Further reading: Actions | CDS BDL - non-standard operations | ABAP EML - response_param
Further reading: RAP BO Contract | RAP BO Provider API (derived types, %cid, implicit response parameters,...)

Further reading: Actions

Determinations

ℹ Click to expand!

A determination is an optional part of the business object behavior that modifies instances of business objects based on trigger conditions. A determination is implicitly invoked by the RAP framework if the trigger condition of the determination is fulfilled. Trigger conditions can be modify operations and modified fields. A determination can be triggered on modify or on save.

Further reading: Determinations

Static and Dynamic Feature Control

ℹ Click to expand!

As an application developer you may want to determine based on certain attributes of your business object entity, which fields should be read-only or mandatory or which functionality like update or actions are allowed. As this property is related to an instance of this business object it is called Dynamic Feature Control.

Further reading: Adding Static and Dynamic Feature Control

Exercise 3.1: How to handle this exercise 💡

^Top of page

💡 There are two (2) ways to complete this exercise:

  • Option 1️⃣: This is the recommended option. Carry out this step (3.1) to replace the whole content of your behavior definiton with the provided source code and then proceed directly with step 3.8 of the present exercise. Of course you can quickly go over the steps 3.2-3.7 to understand the enhanced behavior.

  • Option 2️⃣: Skip this step (3.1) and carry out the steps 3.2-3.9 in sequence.

🔵 Click to expand!
  1. Open the base behavior definition bdefZRAP110_R_TRAVELTP_### of the Travel BO.

  2. Enhance the behavior definition of the Travel BO with late numbering, validations, actions, determinations and a function. The static field control and the feature control will also be enhanced.

    For that, replace the whole source code of your behavior definition object with the source code from the document provided below.

    Replace all occurences of the placeholder ### with your assigned suffix using Ctrl+F.

    ▶📄 Source code document: bdefCDS Behavior Definition ZRAP110_R_TRAVELTP_###

  3. Save save icon (Ctrl+S) the changes.

    You're now getting errors indicating that the fields DRAFTUUID and PARENTDRAFTUUID which are required in the draft tables by late numering are currently missing.

    this is due to the fact that any draft entity needs to have a key in order to be managed properly by the RAP frameworks in the interaction phase, until a primary key is drawn during late phase of the save sequence. To achieve this, a uuid-based key is required for the draft entities. Therefore, the travel and booking draft tables needs to be re-created.

  4. Recreate the draft table for travel entities: tablZRAP110_DTRAV###.

    Set your cursor on the table name, press Ctrl+1, and select the entry Recreate draft table zrap110_dtrav### for entity zrap110_r_traveltp_###. in the Quick Assist view.

    The draft table is now enhanced.

    Draft table
  5. Save save icon and activate activate icon the changes.

    Close the travel database table definition and go back to the behavior definition.

  6. Now, recreate the draft table for booking entities: tablZRAP110_DBOOK###.

    Set your cursor on the table name, press Ctrl+1, and select the entry Recreate draft table zrap110_dtrav### for entity zrap110_r_traveltp_###. in the Quick Assist view.

    The draft table is now enhanced.

    Draft table
  7. Save save icon and activate activate icon the changes.

    Close the booking database table definition and go back to the behavior definition.

  8. As last step, save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes in the behavior definition.

  9. You can now go ahead directly with Exercise 3.8 to adjust the behavior implementation classes, aka behavior pools, of both BO entities_travel_ and _ booking_.

Exercise 3.2: Define the Late Numbering and the Static Field Control

^Top of page

Define the late numbering and the static field control for the travel and booking entities in the BO behavior definition bdef icon ZRAP110_R_TRAVELTP_### of the Travel BO.

🔵 Click to expand!

Exercise 3.2.1: Define the Late Numbering and the Static Field Control for the Travel BO entity

🟣 Click to expand!
  1. Open the behavior definition bdef iconZRAP110_R_TravelTP_### of your Travel BO.

  2. Specify the late numbering statement provided below just after the statement authorization master( global ), just before the opening curly bracket { of the root BO entity travel bdefZRAP110_R_TRAVELTP_### as shown on the screenshot.

    late numbering

    By doing this, ADT is now requiring an implementation class to be provided at the top level, directly after the keyword managed at the top of the editor.

    You can hover the error for more details.

    BO Behavior Definition
  3. You will implement the late numbering in the behavior implementation class of the travel root entity. Therefore, move the statement implementation in class zrap110_BP_TravelTP_### unique to the top as shown on the screenshot.

    BO Behavior Definition
  4. Recreate the draft table for travel entities: tablZRAP110_DTRAV###.

    Any draft entity needs to have a key in order to be managed properly by the RAP frameworks in the interaction phase, until a primary key is drawn during the save sequence. To achieve this, a uuid-based key is required for the draft entities. Therefore, the existing travel draft table needs to be recreated.

    Set your cursor on the table name, press Ctrl+1, and select the entry Recreate draft table zrap110_dtrav### for entity zrap110_r_traveltp_###. in the Quick Assist view.

    The draft table is now enhanced.

    Draft table
  5. Save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes.

    Close the database table definition and go ahead with the next step in the behavior definition.

  6. Specify the static field control for the Travel BO entity:

    • TravelID should be set to read-only as it will be set by the late numbering logic at runtime.
    • TotalPrice should be set to read-only as will be calculated based on the booking fee (BookingFee) and the flight price of the associated booking entities FlightPrice.
    • BeginDate and EndDate should be specified as mandatory.

    Insert the code snippet provided below to the behavior definition as shown on the screenshot.

    Replace the readonly TravelID with following:

      field ( readonly ) TravelID;
      field ( readonly ) TotalPrice;
      field ( mandatory ) BeginDate, EndDate;  
    Draft table
  7. Save save icon (Ctrl+S) the changes and go ahead with the next step.

Exercise 3.2.2: Define the Late Numbering and the Static Field Control for the Booking BO entity

🟣 Click to expand!
  1. Now go to the behavior definition bdefZRAP110_R_TRAVELTP_### of the booking child entity located at the bottom of the behavior definition object.

    Add the late numbering statement just after the statement authorization master( global ), before the opening curly bracket {.

    late numbering
    BO Behavior Definition

    Now, mutiple error are displayed in ADT. This is due to the fact that a key is required for the draft entity in order to be managed properly by the RAP frameworks in the interaction phase, until a primary key is created during the save sequence.

  2. Recreate the draft table for booking entities: tablZRAP110_DBOOK###.

    Simply set the mouse cursor on the table name, press Ctrl+1, and select the entry Recreate draft table zrap110_dbook### for entity zrap110_r_bookingtp_###. in the Quick Assist view.

    The draft table is now enhanced.

    Draft table
  3. Save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes.

    Close the database table definition and go ahead with the next step in the behavior definition.

  4. Specify the static field control for the Booking BO entity:

    • BookingID should be set to read-only as this a key field and will be set by the late numbering logic at runtime.
    • CustomerID, CarrierID, Flightdate, and BookingStatus should be specified as mandatory.

    Replace the statement field ( readonly : update ) BookingID; with following:

      field ( readonly ) BookingID;
      field ( mandatory ) CustomerID, CarrierID, Flightdate, BookingStatus;  
    Draft table
  5. Save save icon the changes and go ahead with the next step.

Exercise 3.3: Define the Validations

^Top of page

Define following validations: to ensure the consitency of the entered data: In the present exercise, you're going to define and implement three back-end validations - validateCustomer, validateAgency, and validateDates - to respectively check if the customer ID and the agency ID that are entered by the consumer are valid, and if the begin date is in the future and the end date is after the begin date. These validations are only performed in the back-end (not on the UI). The validations are triggered independently of the consumer, i.e. Fiori UIs or EML APIs.

Note: Validations are used to ensure the data consistency. They have been already handled in the RAP100 exercise document. Therefore, we will not go into details about them again. We will simply quickly define and implement some validations that will be use to display other capabilities.

🔵 Click to expand!

Exercise 3.3.1: Define the Validations of the Travel BO entity

🟣 Click to expand!
  1. Define three (3) validations to check the values of CustomerID, AgencyID, BeginDate and EndDate of the travel root entity. The validations will always be triggered on save, i.e. when has to be persisted.

    Insert the code snippet provided below in the behavior definition of the travel root entity bdefZRAP110_R_TRAVELTP_### as shown on the screeshot below.

     // validation(s)
      validation validateCustomer on save { create; field CustomerID; }
      validation validateAgency on save { create; field AgencyID; }
      validation validateDates on save { create; field BeginDate, EndDate; }     
    BO Behavior Definition
  2. Add the validations to the draft determine action Prepare to allow the draft data to be validated before its transition to active data.

      draft determine action Prepare
      {
        validation validateCustomer;
        validation validateAgency;
        validation validateDates;
      }  
    BO Behavior Definition
  3. Save save icon (Ctrl+S) the changes.

Exercise 3.3.2: Define the Validations of the Booking BO entity

🟣 Click to expand!
  1. Define a validation to check the values of BookingStatus. The validation will always be triggered on save.

    Insert the code snippet provided below in the behavior definition bdefZRAP110_R_TRAVELTP_### of the booking child entity.

      //validation(s)
      validation validateBookingStatus on save { create; field BookingStatus; }  
    BO Behavior Definition
  2. Add the new validation to the draft determine action Prepare of the Travel root entity.

        validation Booking~validateBookingStatus;
    BO Behavior Definition
  3. Save save icon (Ctrl+S) the changes and go ahead with the next step.

Exercise 3.4: Define the Actions

^Top of page

Now you will define five (5) different actions for the Travel entity.

  • Instance actions acceptTravel and rejectTravel - used to respectively set the overall status of a travel entity to accepted or rejected.
  • Internal instance action recalcTotalPrice - used to recalculate the total price of a travel entity each time either flight price, booking fee, or currency has changed.
  • Static factory action createTravel with input parameter - used to create new travel entities with a booking entity directly - with default values. In a later exercise (Exercise 7 precisely), this action will be marked as default to be used as replacement for the standard create operation. The CDS abstract entity **ZRAP110_A_Create_Travel_###** will be used to define the structure of the input parameter.
  • Determine action checkDates - used to call the validation validateDates on request.

Further reading: Action Definition

🔵 Click to expand!

Exercise 3.4.1: Define the Actions of the Travel BO entity

🟣 Click to expand!
  1. Define different actions in the behavior definition of the travel root entity bdefZRAP110_R_TRAVELTP_###.

    Insert the code snippet provided below and replace the placeholder ### with your assigned suffix.

      //action(s)
      action acceptTravel result [1] $self;   
      action rejectTravel result [1] $self;   
      internal action recalcTotalPrice;  
      static factory action createTravel parameter ZRAP110_A_Create_Travel_### [1]; 
      determine action checkDates 
      {
        validation validateDates;
      }  
    BO Behavior Definition
  2. Save save icon (Ctrl+S) the changes and go ahead with the next step.

    Brief explanation:

    ℹ Click to expand!
    • Actions are instance-bound by default.
    • The instance actions acceptTravel and rejectTravel return a single travel entity (result [1] $self).
    • The action recalcTotalPrice has the option internal and can, therefore, only be accessed from the business logic inside the BO implementation such as from a determination or from another action. It has no result parameter.
    • With the option static, the factory action createTravel is not bound to any instance but relates to the complete entity. It has an input parameter and creates an entity instance.
    • The CDS abstract entity ZRAP110_A_Create_Travel_### is used to define the structure of the input parameter.
    • The action checkDates with the option determine can be called on request via EML or via an action the UI to execute the validation validateDates.

Exercise 3.5: Define the Determinations

^Top of page

For the travel BO entity, define the on modify determinations setInitialTravelValues to set default values of a travel entity instance during its creation and calculateTotalPrice to trigger the calculation of the total price of a travel entity instance during its creation and each time BookingFee or CurrencyCode has changed.

For the booking BO entity, define the on modify determinations setInitialBookingValues to set the default value of a booking entity instance during its creation and calculateTotalPrice to trigger the calculation of the total price of the parent travel entity instance during its creation and each time FlightPrice or CurrencyCode has changed.

🔵 Click to expand!

Exercise 3.5.1: Define the Determinations of the Travel BO entity

🟣 Click to expand!
  1. Define the following on modify determinations:

    • setInitialTravelValues - to set the default value of BeginDate, EndDate, CurrencyCode, and OverallStatus during the creation of a travel entity instance.
    • calculateTotalPrice - to trigger the calculation of the total price of a travel entity on modify at creation time and each time BookingFee or CurrencyCode has changed.

    For that, insert the code snippet provided below in the behavior definition of the travel root entity bdefZRAP110_R_TRAVELTP_### as shown on the screenshot.

      //determination(s)
      determination setInitialTravelValues on modify { create; }
      determination calculateTotalPrice on modify { create; field BookingFee, CurrencyCode; }          
    BO Behavior Definition
  2. Save save icon (Ctrl+S) the changes and go ahead with the next step.

Exercise 3.5.2: Define the Determinations of the Booking BO entity

🟣 Click to expand!
  1. Define the following on modify determinations:

    • setInitialBookingValues - to set the default value of TravelID, CustomerID, and BookingDate during the creation of a travel entity instance on modify.
    • calculateTotalPrice - to trigger the calculation of the total price of a travel entity on modify at creation time and each time BookingFee or CurrencyCode has changed.

    For that, insert the code snippet provided below in the behavior definition of the booking child entity bdefZRAP110_R_TravelTP_### as shown on the screenshot.

      //determination(s)
      determination setInitialBookingValues on modify { create; } //copy & paste
      determination calculateTotalPrice on modify { create; field FlightPrice, CurrencyCode; }  //**  
    BO Behavior Definition
  2. Save save icon (Ctrl+S) the changes and go ahead with the next step.

Exercise 3.6: Define the Functions

^Top of page

For the booking BO entity, define the instance function getDaysToFlight to calculate the value of the virtual elements BookingStatusIndicator, InitialDaysToFlight, RemainingDaysToFlight, and DaysToFlightIndicator defined in the booking BO projection view ddlsZRAP110_C_TravelTP_### for a given booking entity instance.

🔵 Click to expand!

Exercise 3.6.1: Define the Function of the Booking BO entity

🟣 Click to expand!
  1. The CDS abstract entity ZRAP110_A_DAYSTOFLIGHT_### provided in your exercise package ZRAP110_### will be used to define the type of the return structure of the result parameter.

    BO Behavior Definition
    Source code
    @EndUserText.label: 'Abstract entity for Days To Flight'
    define abstract entity ZRAP110_A_DaysToFlight_###
    {
      initial_days_to_flight   : abap.int4;
      remaining_days_to_flight : abap.int4;
      booking_status_indicator : abap.int4;
      days_to_flight_indicator : abap.int4;
    }  
  2. Define the instance function getDaysToFlight in the booking child entity bdefZRAP110_R_TravelTP_### as shown on the screenshot. Replace the placeholder ### with your assigned suffix.

    //function(s)
    function getDaysToFlight result [1] ZRAP110_A_DaysToFlight_###; 
    BO Behavior Definition
  3. Save save icon (Ctrl+S) the changes and go ahead with the next step.

Exercise 3.7: Define the Dynamic Feature Control

^Top of page

You will now define the dynamic feature control for some of the standard and nonstandard operations of the Travel entity.

🔵 Click to expand!

Exercise 3.7.1: Define the Dynamic Feature Control of the Travel BO entity

🟣 Click to expand!
  1. Define the dynamic instance feature control for ...

    • the standard operations update and delete
    • the standard operation create by association for _Booking_
    • the instance actions acceptTravel and rejectTravel, and the
    • the draft action Edit

    To achieve this add the statement below in the behavior definition of the Travel root entity bdefZRAP110_R_TRAVELTP_### as shown on the screenshot.

    ( features : instance )
    BO Behavior Definition
  2. Save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes.

Exercise 3.8: Adjust the Behavior Implementation Classes

^Top of page

You will now adjust the behavior implementation classes, aka behavior pools, of the travel and booking entity to reflect the enhancements specified in both behavior definitions.

🔵 Click to expand!

Exercise 3.8.1: Adjust the Behavior Implementation Class of the Travel BO entity.

🟣 Click to expand!

You will now adjust the behavior implementation class (aka behavior pool) of the Travel entity ABAP classZRAP110_BP_TRAVELTP_###.

  1. First, adjust the behavior pool for the late numbering.

    The Late numbering is always implemented in the method adjust_number of the local saver class of the root BO entity. Therefore, the local saver class and the method must be defined in the behavior pool of the travel entity.

    For that, go to the behavior definition of the travel entity bdefZRAP110_R_TRAVELTP_###, set the cursor on late numbering and press Ctrl+1 to start the ADT Quick Fix.

    Select Add required method adjust_number in new local saver class in the _Quick Assist view to update the behavior pool accordingly.

    BO Behavior Definition

    The local saver class lsc_zrap110_r_traveltp_### has been added to the behavior pool of the travel BO entity ABAP classZRAP110_BP_TRAVELTP_###.

  2. Now, go ahead and adjust the local handler class for the other enhancements defined in the behavior definition of the travel entity.

    For that, set the cursor on one of the new actions, determinations, or validations, e.g. acceptTravel, and press Ctrl+1.

    Select Add all 10 missing methods of entity zrap110_bp_traveltp_### in local handler class lhc_travel in the _Quick Assist view to generate the missing methods.

    BO Behavior Definition

    The local handler class lhc_travel will be updated accordingly.

  3. Also define the constant travel_status in the private section of the local handler class definition lhc_travel. It comprises the allowed values of the element TravelStatus.

    ⚠ Make sure to define the constant in the local handler class lhc_travel - not in the local saver class.

    It comprises the allowed values of the fields BookingStatus

    Use the code snippet provided below

      CONSTANTS:
      "travel status
      BEGIN OF travel_status,  
        open          TYPE c LENGTH 1 VALUE 'O', "Open
        accepted      TYPE c LENGTH 1 VALUE 'A', "Accepted
        rejected      TYPE c LENGTH 1 VALUE 'X', "Rejected
      END OF travel_status.
    behavior pool
  4. Save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes

Exercise 3.8.2: Adjust the Behavior Implementation Class of the Booking BO entity

🟣 Click to expand!

You will now adjust the behavior implementation class (aka behavior pool) of the booking entity ABAP classZRAP110_BP_BookingTP_###

  1. Now go to the behavior definition bdefZRAP110_R_TravelTP_###, set the cursor on one of the new determinations, validations or the function, e.g. validateBookingStatus, and press Ctrl+1.

    Select Add all 4 missing methods of entity zrap110_bp_bookingtp_### in local handler class lhc_booking in the _Quick Assist view to generate the missing methods.

    BO Behavior Definition

    The local handler class lhc_booking will be updated accordingly.

  2. Also define the constant booking_status in the private section of the local handler class definition lhc_travel. It comprises the allowed values of the element BookingStatus.

    Use the code snippet provided below

      CONSTANTS:
      "booking status
      BEGIN OF booking_status,
        new      TYPE c LENGTH 1 VALUE 'N', "New
        booked   TYPE c LENGTH 1 VALUE 'B', "Booked
        canceled TYPE c LENGTH 1 VALUE 'X', "Canceled
      END OF booking_status.
    behavior pool
  3. Save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes.

Exercise 3.9: Enhance the BO Behavior Projection

^Top of page

You will now expose the new actions defined in the base BO behavior in the BO behavior projection.

INFO: Validations and determinations are automatically orchestrated and called by the RAP frameworks at the specified trigger time. They do not need to be explicetly exposed in the BO projection in order to be used.

🔵 Click to expand!
  1. Open the behavior projection bdefZRAP110_C_TRAVELTP_### and add the new actions acceptTravel, rejectTravel, createTravel, and checkDates using the keyword expose.

    Use the code snippet provided below for te purpose as shown on the screenshot.

      use action acceptTravel;
      use action rejectTravel;
      use action createTravel;
    
      use action checkDates;
    BO Behavior Definition
  2. Save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes. Close the behavior projection.

Summary

^Top of page

Attention
Due to the specification of late numbering, you will not be able to create new travel or booking instances due to the fact that no key is set at this stage. But no problem, you will tackle it in the next exercise.

Now that you've...

  • enhanced the transactional behavior definition of both BO entities, Travel and Booking with
    • Late Numbering
    • static field control,
    • validations,
    • actions,
    • determinations,
    • functions,
    • dynamic feature control,
  • recreated database tables and adjusted the implementation class definition of the implementation classes with ADT Quick Fixes, and
  • exposed the new base BO behavior to the projection layer,

you can continue with the next exercise – Exercise 4: Implement the Base BO Behavior - Late Numbering