Skip to content

Latest commit

 

History

History
581 lines (394 loc) · 29.1 KB

README.md

File metadata and controls

581 lines (394 loc) · 29.1 KB

Home - RAP110

Exercise 2: Enhance the Data Model of the Base and Projected Business Object (BO)

Introduction

In the previous exercise, you've had a look at your exercise package ZRAP110_###, where ### is your assigned suffix (see Exercise 1).

In this exercise, you will enhance the CDS data model of the base BO and the BO projection. These enhancements include enabling OData Stream in the base BO data model and adding new elements by associations, virtual elements, and adjusting the value help definitions in the BO data model projection.

Exercises:

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

Further reading: CDS Annotations | Working with Large Objects | Using Virtual Elements in CDS Projection Views

About Virtual Elements

Click to expand!

Virtual elements represent transient fields in business applications. They are used to define additional CDS elements that are not persisted on the database, but calculated during runtime using ABAP classes that implement the virtual element interface. They are defined at the level of CDS projection views as additional elements within the SELECT list.

The OData service metadata do not differentiate between regular CDS elements with database persistence and virtual elements. Consequently, a virtual element appears in an application UI equal to any other element.

Read more: Using Virtual Elements in CDS Projection Views

Exercise 2.1: Enhance the Data Model of the Base Travel BO

Enhance the CDS data model of the base travel BO entity to support to enable the handling of large objects (aka OData stream).

🔵 Click to expand!

Exercise 2.1.1: Enhance the Data Model of the Base Travel BO Entity

^Top of page

Adjust the CDS data model of the base Travel BO entity in view entity datadefinitionZRAP110_R_TravelTP_### to enable the handling of large objects in your Fiori elements app.

By doing that, you will give end-users the option to upload and download images from your Travel app.

🟣 Click to expand!
  1. Go to the Project Explorer, open the CDS data definiton datadefinitionZRAP110_R_TravelTP_###.

  2. Enable the OData Stream by adding the appropriate annotations to the elements Attachment and MimeType as shown on the screenshot. Use the code snippets provided below .

    • For the element Attachment - which is used to store the LOB (aka stream) and must be bound to a MIME type:
      @Semantics.largeObject: { mimeType: 'MimeType',    //case-sensitive
                                fileName: 'FileName',    //case-sensitive
                                //acceptableMimeTypes: ['image/png', 'image/jpeg'],
                                contentDispositionPreference: #ATTACHMENT }
    • For the element MimeType - which is used to indicates the content type of the attachment:
       @Semantics.mimeType: true
    Base Travel BO view
    About the annotation `@Semantics.largeObject`

    Here is a short explanation of the attributes of the element annotation @Semantics.largeObject :

    • mimeType: It is a mandatory attribute which indicates the name of the field containing the type of a MIME object. The value is-case sentitive.
    • fileName: It is an optional attribute which indicates the name of the field containing the file name of a MIME object. The value is-case sentitive.
    • acceptableMimeTypes: It provides the list of acceptable MIME types for the related stream property to restrict or verify the user entry accordingly. If any subtype is accepted, this can be indicated by *.
    • contentDispositionPreference: It is used to define whether, depending on the browser settings, the file attachment is either displayed in the browser (setting #INLINE) or downloaded when selected (option #ATTACHMENT).

    Read more on Semantic Annotations

  3. Save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes. Close the data definition.

  4. You can check the result of this changes in the Travel app preview by refreshing the it in the browser (F5) or starting the again the Fiori elements App Preview in ADT.

    You will now have the possibility to upload a file on the travel details page, aka Object Page.

    Base Travel BO view

Exercise 2.2: Enhance the Data Model of the Projected Travel BO Entity

^Top of page

Enhance the CDS data model of the projected travel BO entity with new elements from associations and defining virtual elements, adjusting the defined value help definitions to enable front-end validations, and removing use case irrelevant elements.

🔵 Click to expand!

Exercise 2.2.1: Enhance the Travel BO projection view

Enhance the Travel BO projection view datadefinitionZRAP110_C_TravelTP_###, aka consumption view.

🟣 Click to expand!
  1. Performing classic adjustment tasks such as adding new elements from associations, specifying associated text elements, removing use case irrelevant elements have already been introduced and explained in RAP100.

    Replace the whole data definition of the travel BO projection view datadefinitionZRAP110_C_TravelTP_### with the source code from the document provided below.

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

    Hint: The changed lines are marked with a comment in the provided source code.

    ▶📄 Source code document: ddls iconCDS Projection View ZRAP110_C_TRAVELTP_###

  2. Now, go ahead and define the virtual element OverallStatusIndicator that will be used to specify the criticality of the travel overall status in the Travel app in the metadata extension later on. The end-user label of this element is Overall Status Indicator.

    The keyword virtual must be specified in front of the element and the name of the calculation class must be specified in the annotation @ObjectModel.virtualElementCalculatedBy. The ABAP class class iconZRAP110_CALC_TRAV_ELEM_### will be used to calculate this virtual element is specified.

    Uncomment in the Travel BO projection view datadefinitionZRAP110_C_TravelTP_### the code snippet below placed after the element OverallStatusText in the SELECT list as shown on the screenshot and replace the placeholder ### with your assigned suffix.

              @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZRAP110_CALC_TRAV_ELEM_###'
              @EndUserText.label: 'Overall Status Indicator'
      virtual OverallStatusIndicator : abap.int2,
    ABAP Class

    Info: Due to time constraint, a skelleton of the class *ABAP:ZRAP110_CALC_TRAV_ELEM_### has been already generated in your exercise package. You will enhance its implementation in the step 2.4.

  3. Save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes. Close the data definition.

Exercise 2.2.2: Calculate the Virtual Elements of the Travel BO Entity

Implement the logic of the virtual element OverallStatusIndicator in the ABAP Class class iconZRAP110_CALC_TRAV_ELEM_###, where ###is your assigned suffix.

🟣 Click to expand!
  1. Open your ABAP class class iconZRAP110_CALC_TRAV_ELEM_### and replace the entire code with the code provided below. Replace all occurences of the placeholder ### with your assigned suffix using Ctrl+F.

    CLASS zrap110_calc_trav_elem_### DEFINITION
      PUBLIC
      FINAL
      CREATE PUBLIC .
    
      PUBLIC SECTION.
        INTERFACES if_sadl_exit_calc_element_read .
    
      PROTECTED SECTION.
      PRIVATE SECTION.
    ENDCLASS.
    
    CLASS ZRAP110_CALC_TRAV_ELEM_### IMPLEMENTATION.
    
      METHOD IF_SADL_EXIT_CALC_ELEMENT_READ~CALCULATE.
        IF it_requested_calc_elements IS INITIAL.
          EXIT.
        ENDIF.
    
        LOOP AT it_requested_calc_elements ASSIGNING FIELD-SYMBOL(<fs_req_calc_elements>).
          CASE <fs_req_calc_elements>.
              "virtual elements from TRAVEL entity
            WHEN 'OVERALLSTATUSINDICATOR'.
              DATA lt_trav_original_data TYPE STANDARD TABLE OF ZRAP110_C_TravelTP_### WITH DEFAULT KEY.
              lt_trav_original_data = CORRESPONDING #( it_original_data ).
              LOOP AT lt_trav_original_data ASSIGNING FIELD-SYMBOL(<fs_trav_original_data>).
    
    *            <fs_trav_original_data> = zrap110_calc_trav_elem_###=>calculate_trav_status_ind( <fs_trav_original_data> ).
    
              ENDLOOP.    
              ct_calculated_data = CORRESPONDING #( lt_trav_original_data ).  
          ENDCASE.
        ENDLOOP.
      ENDMETHOD.
    
      METHOD IF_SADL_EXIT_CALC_ELEMENT_READ~GET_CALCULATION_INFO.
        IF iv_entity EQ 'ZRAP110_C_TRAVELTP_###'. "Travel BO node
          LOOP AT it_requested_calc_elements ASSIGNING FIELD-SYMBOL(<fs_travel_calc_element>).
            CASE <fs_travel_calc_element>.
              WHEN 'OVERALLSTATUSINDICATOR'.
                APPEND 'OVERALLSTATUS' TO et_requested_orig_elements.
    
            ENDCASE.
          ENDLOOP.
        ENDIF.
      ENDMETHOD.
    
    ENDCLASS.

    Brief explanation:

    Click to expand!
    • The class implements the virtual element interface IF_SADL_EXIT_CALC_ELEMENT_READ that must be implemented by calculation classes for virtual elements.

    • The method IF_SADL_EXIT_CALC_ELEMENT_READ~GET_CALCULATION_INFO provides a list of all elements that are required for calculating the values of the virtual elements in the requested entity. This method is called during runtime before the retrieval of data from the database to ensure that all necessary elements for calculation are filled with data.

    • The method IF_SADL_EXIT_CALC_ELEMENT_READ~CALCULATE executes the value calculation for the virtual element. This method is called during runtime after data is retrieved from the database. The elements needed for the calculation of the virtual elements are already inside the data table passed to this method. The method returns a table that contains the values of the requested virtual elements.

    Read more: Using Virtual Elements in CDS Projection

  2. Define the class method interface calculate_trav_status_ind in the public section of the class definition where the proper calculation of the virtual element OverallStatusIndicator will take place. The method is declared as class method to have the possibility to access it externaly, for example, from a function.

    For that, insert the code snippet provided below after the statement interfaces IF_SADL_EXIT_CALC_ELEMENT_READ. in the class definition and replace all occurences of the placeholder ### with your assigned suffix.

    CLASS-METHODS:
      calculate_trav_status_ind
        IMPORTING is_original_data TYPE ZRAP110_C_TravelTP_###
        RETURNING VALUE(result)    TYPE ZRAP110_C_TravelTP_###.

    Your source code should look like this:

    ABAP Class
  3. Press the light bulb symbol on the left side or use the ADT Quick Fix (Ctrl+1) to add the missing method implementations. Set the cursor before your method calculate_trav_status_ind and press CTRL + 1, select Add implementation for calculate_trav_status_ind.

    Your source code should look like this:

    ABAP Class
  4. Implement the methods calculate_trav_status_ind.

    The logic is quite simple: the criticality indicator ( 1 = red | 2 = orange | 3 = green) is bound to the overall travel status:

    • If travel status is accepted, then the criticality is 3, i.e. green.
    • If travel status is open, then the criticality is 2, i.e. orange.
    • If travel status is rejected, then the criticality is 1, i.e. red.

    For that, replace the empty method implementation of calculate_trav_status_ind with the code snippet provided below.

      METHOD calculate_trav_status_ind.   
        result = CORRESPONDING #( is_original_data ).
    
        "travel status indicator
        "(criticality: 1  = red | 2 = orange  | 3 = green)  
        CASE result-OverallStatus.
          WHEN 'X'.
            result-OverallStatusIndicator = 1.
          WHEN 'O'.
            result-OverallStatusIndicator = 2.
          WHEN 'A'.
            result-OverallStatusIndicator = 3.        
          WHEN OTHERS.
        ENDCASE.
      ENDMETHOD.   
    ABAP Class
  5. Now, uncomment the method call calculate_trav_status_ind within the method CALCULATE.

    <fs_trav_original_data> = zrap110_calc_trav_elem_###=>calculate_trav_status_ind( <fs_trav_original_data> ).

    ABAP Class
  6. Save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes. Close the ABAP class.

Exercise 2.3: Enhance the Data Model of the Projected Booking BO Entity

^Top of page

Enhance the CDS data model of the projected travel BO entity with new elements from associations and defining virtual elements, adjusting the defined value help definitions to fine-tune the usage of the specified additional binding, and removing use case irrelevant elements.

🔵 Click to expand!

Exercise 2.3.1: Enhance the Booking BO projection view

Enhance the Booking BO projection view ddls iconZRAP110_C_BookingTP_###.

Beside basic minor classic adjustments, you will add four (4) virtual elements to the data model:

  • BookingStatusIndicator that will be used to determine the criticality of the booking status on Fiori elements UIs in the metadata extension later on. End-user label is "Overall Status Indicator".
  • InitialDaysToFlight that will be used to calculate the initial number of days between the flight date and the booking date (flight date - booking date). the end-user label is "Initial Days to Flight".
  • RemainingDaysToFlight that will be used to calculate the remaining number of days before the flight (flight date - current date). End-user label is "Remaining Days to Flight".
  • DaysToFlightIndicator that will be used to calculate the criticality indicator for the remaining days to flight. The end-user label is "Days to Flight Indicator".
🟣 Click to expand!
  1. Open the CDS projection view datadefinitionZRAP110_C_BookingTP_###.

  2. Similarly to Exercise 2.2.1 basic adjustments will be carried out by simply replacing the complete data definition of your Booking BO projection view with the source code provided in the source code document linked below.

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

    ▶📄 Source code document: ddls iconCDS projection view ZRAP110_C_BookingTP_###

  3. Now, define the four (4) new virtual elements BookingStatusIndicator, InitialDaysToFlight, RemainingDaysToFlight, and RemainingDaysToFlight. Their values will be determined in the ABAP class ZRAP110_CALC_BOOK_ELEM_###.

    For that, uncomment the code snippet below placed after the element BookingStatusText in the SELECT list as shown on the screenshot and replace the placeholders ### with your assigned suffix.

    ABAP Class
    Source code
            @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZRAP110_CALC_BOOK_ELEM_###'
            @EndUserText.label: 'Booking Status Indicator'
    virtual BookingStatusIndicator : abap.int2,
    
            @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZRAP110_CALC_BOOK_ELEM_###'
            @EndUserText.label: 'Initial Days to Flight'
    virtual InitialDaysToFlight    : abap.int1,
    
            @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZRAP110_CALC_BOOK_ELEM_###'
            @EndUserText.label: 'Remaining Days to Flight'
    virtual RemainingDaysToFlight  : abap.int1,
    
            @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZRAP110_CALC_BOOK_ELEM_###'
            @EndUserText.label: 'Days to Flight Indicator'
    virtual DaysToFlightIndicator  : abap.int1,      
  4. Save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes. Close the data definition.

Exercise 2.3.2: Calculate the Virtual Elements of the Booking BO Entity

^Top of page

Implement the logic of the different virtual elements of the booking BO entity in the ABAP Class class iconZRAP110_CALC_BOOK_ELEM_###, where ###is your assigned suffix.

🟣 Click to expand!
  1. Open your ABAP class ABAP classZRAP110_CALC_BOOK_ELEM_### and replace the entire code with the code provided below. Replace all occurences of the placeholder ### with your assigned suffix using Ctrl+F.

    CLASS zrap110_calc_book_elem_### DEFINITION
      PUBLIC
      FINAL
      CREATE PUBLIC .
    
      PUBLIC SECTION.
        INTERFACES if_sadl_exit_calc_element_read .
    
      PROTECTED SECTION.
      PRIVATE SECTION.
    ENDCLASS.
    
    CLASS zrap110_calc_book_elem_### IMPLEMENTATION.
    
      METHOD if_sadl_exit_calc_element_read~calculate.
        IF it_requested_calc_elements IS INITIAL.
          EXIT.
        ENDIF.
        
        LOOP AT it_requested_calc_elements ASSIGNING FIELD-SYMBOL(<fs_req_calc_elements>).    
          CASE <fs_req_calc_elements>.
              "virtual elements from BOOKING entity
            WHEN 'INITIALDAYSTOFLIGHT'   OR 'REMAININGDAYSTOFLIGHT'
              OR 'DAYSTOFLIGHTINDICATOR' OR 'BOOKINGSTATUSINDICATOR'.    
              DATA lt_book_original_data TYPE STANDARD TABLE OF ZRAP110_C_BookingTP_### WITH DEFAULT KEY.
              lt_book_original_data = CORRESPONDING #( it_original_data ).
              LOOP AT lt_book_original_data ASSIGNING FIELD-SYMBOL(<fs_book_original_data>).
    
    *            <fs_book_original_data> = zrap110_calc_book_elem_###=>calculate_days_to_flight( <fs_book_original_data> ).
    
              ENDLOOP.
              ct_calculated_data = CORRESPONDING #( lt_book_original_data ).
          ENDCASE.
        ENDLOOP.
      ENDMETHOD.
        
      METHOD if_sadl_exit_calc_element_read~get_calculation_info.
        IF iv_entity EQ 'ZRAP110_C_BOOKINGTP_###'. "Booking BO node
          LOOP AT it_requested_calc_elements ASSIGNING FIELD-SYMBOL(<fs_booking_calc_element>).
            CASE <fs_booking_calc_element>.
              WHEN 'INITIALDAYSTOFLIGHT'.
                COLLECT `BOOKINGDATE` INTO et_requested_orig_elements.
                COLLECT `FLIGHTDATE` INTO et_requested_orig_elements.
              WHEN 'REMAININGDAYSTOFLIGHT'.
                COLLECT `FLIGHTDATE` INTO et_requested_orig_elements.
              WHEN 'DAYSTOFLIGHTINDICATOR'.
                COLLECT `FLIGHTDATE` INTO et_requested_orig_elements.
              WHEN 'BOOKINGSTATUSINDICATOR'.
                COLLECT `BOOKINGSTATUS` INTO et_requested_orig_elements.
            ENDCASE.
          ENDLOOP.
        ENDIF.    
      ENDMETHOD.
    
    ENDCLASS.
  2. Define the class method interface calculate_days_to_flight in the public section of the class definition.

    For that, insert the code snippet provided below after the statement interfaces IF_SADL_EXIT_CALC_ELEMENT_READ. in the class definition and replace all occurences of the placeholder ### with your assigned suffix.

      CLASS-METHODS:
        calculate_days_to_flight
          IMPORTING is_original_data TYPE ZRAP110_C_BookingTP_###
          RETURNING VALUE(result)    TYPE ZRAP110_C_BookingTP_###.

    Your source code should look like this:

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

  4. Press the light bulb symbol on the left side or use the ADT Quick Fix (Ctrl+1) to add the missing method implementations. Set the cursor before your method calculate_days_to_flight and press CTRL + 1, select Add implementation for calculate_days_to_flight.

    Your source code should look like this:

    ABAP Class
  5. Implement the method calculate_days_to_flight which calculates the value of the virtual element defined in the booking BO entity.

    For that, replace the empty method implementation of calculate_days_to_flight with the code snippet provided below.

      METHOD calculate_days_to_flight.
        DATA(today) = cl_abap_context_info=>get_system_date( ).
    
        result = CORRESPONDING #( is_original_data ).
    
        "VE InitialDaysToFlight: initial days to flight
        DATA(initial_days) = result-FlightDate - result-BookingDate.
        IF initial_days > 0 and initial_days < 999.
    *    IF initial_days > 0 .
          result-InitialDaysToFlight =  initial_days.
        ELSE.
          result-InitialDaysToFlight = 0.
        ENDIF.
    
        "VE RemainingDaysToFlight: remaining days to flight
        DATA(remaining_days) = result-FlightDate - today.
        IF remaining_days < 0 OR remaining_days > 999.
          result-RemainingDaysToFlight = 0.
        ELSE.
          result-RemainingDaysToFlight =  result-FlightDate - today.
        ENDIF.
    
        "VE DaysToFlightIndicator: remaining days to flight *indicator*
        "(dataPoint: 1 = red | 2 = orange | 3 = green | 4 = grey | 5 = bleu)
        IF remaining_days >= 6.
          result-DaysToFlightIndicator = 3.       "green
        ELSEIF remaining_days <= 5 AND remaining_days >= 3.
          result-DaysToFlightIndicator = 2.       "orange
        ELSEIF remaining_days <= 2 AND remaining_days >= 0.
          result-DaysToFlightIndicator = 1.       "red
        ELSE.
          result-DaysToFlightIndicator = 4.       "grey
        ENDIF.
    
        "VE BookingStatusIndicator: booking status indicator
        "(criticality: 1  = red | 2 = orange  | 3 = green)
        CASE result-BookingStatus.
          WHEN 'X'.
            result-BookingStatusIndicator = 1.
          WHEN 'N'.
            result-BookingStatusIndicator = 2.
          WHEN 'B'.
            result-BookingStatusIndicator = 3.
          WHEN OTHERS.
        ENDCASE.
      ENDMETHOD.
    About the virtual elements
    • BookingStatusIndicator: For the UI coloring - 1 = red (Cancelled) | 2 = orange (Open) | 3 = green (Booked)
    • InitialDaysToFlight: The initial number of days between the flight date and the booking date (flight date - booking date).
    • RemainingDaysToFlight: The number of days until departure from today.
    • DaysToFlightIndicator: The criticality/coloring for the remaining days to flight
    • Colors: 1 = red | 2 = orange | 3 = green | 4 = grey | 5 = bleu
  6. Now, uncomment the method call calculate_trav_status_ind within the method CALCULATE.

    <fs_book_original_data> = zrap110_calc_book_elem_###=>calculate_days_to_flight( <fs_book_original_data> ).

    ABAP Class
  7. Save save icon (Ctrl+S) and activate activate icon (Ctrl+F3) the changes. Close the ABAP class.

Exercise 2.4: Preview and Test the enhanced Travel App

^Top of page

Test the enhanced SAP Fiori elements application.

🔵 Click to expand!
  1. Refresh your browser or start the SAP Fiori elements app preview from your service binding ../servicebinding ZRAP110_UI_TRAVEL_O4_### by double-clickin the Travel entity set.

    If you haven't created any entries, please do one travel entry now.

  2. Click Go on the app and check the result.

    ABAP Class
  3. Press the respective Gear icon and check their calculated values.

    ABAP Class

    Now add the missing column (virtual elements) Overall Status Indicator on the list report and click OK.

    ABAP Class
  4. Now you can see the Overall Status Indicator.

    ABAP Class
  5. Select your entry.

    ABAP Class

    Now click Edit.

    ABAP Class

    Now you can see, that you are able to upload attachement on the Travel object page.

    ABAP Class

Summary

^Top of page

Now that you've...

  • enabled the OData stream handling in the base BO to upload files
  • added elements to the selection list and element/view annotations in the consumption view,
  • added and implemented virtual elements on the consumption layer
  • checked the preview,

you can continue with the next exercise – Exercise 3: Enhance the BO Behavior Definition and Projection