From 2b792fc7fa08fb9d031a5d4411e5d9850678c36a Mon Sep 17 00:00:00 2001 From: Ruthiel Trevisan Date: Mon, 26 Aug 2024 10:14:02 +0100 Subject: [PATCH] Correction of exercise README.md files - Small typos - Formating coherence - Removing white spaces --- exercises/ex00/README.md | 84 +++--- exercises/ex01/README.md | 192 ++++++------ exercises/ex02/README.md | 378 ++++++++++++------------ exercises/ex03/README.md | 608 +++++++++++++++++++------------------- exercises/ex04/README.md | 91 +++--- exercises/ex05/README.md | 158 +++++----- exercises/ex06/README.md | 274 ++++++++--------- exercises/ex07/README.md | 240 +++++++-------- exercises/ex08/README.md | 119 ++++---- exercises/ex09/README.md | 182 ++++++------ exercises/ex10/README.md | 171 +++++------ exercises/ex11/README.md | 458 ++++++++++++++-------------- exercises/ex11b/README.md | 156 +++++----- exercises/ex12/README.md | 95 +++--- 14 files changed, 1625 insertions(+), 1581 deletions(-) diff --git a/exercises/ex00/README.md b/exercises/ex00/README.md index 818e382..d1a84a5 100644 --- a/exercises/ex00/README.md +++ b/exercises/ex00/README.md @@ -4,19 +4,21 @@ ## Introduction - -- [Create an ABAP Cloud Project in ADT](#create-an-abap-cloud-project-in-adt) +- [Create an ABAP Cloud Project in ADT](#create-an-abap-cloud-project-in-adt) - [Helpful Information](#helpful-information) - Find/Replace - ABAP Pretty Printer @@ -26,8 +28,8 @@ -> **Note:** -> The screenshots in this document have been taken using the suffix or assigned suffix **`810`** and the system **`D23`**. +> **Note:** +> The screenshots in this document have been taken using the suffix or assigned suffix **`810`** and the system **`D23`**. > We **do not recommend** using assigned suffix **`810`** or **`000`**. -> +> > Please note that ADT dialogs and views as well as SAP Fiori UIs may change in upcoming releases. ## Create an ABAP Cloud Project in ADT + [^Top of page](#) > If not done already, you will first create an **ABAP Cloud Project** in your ADT installation to create a connection to the SAP BTP ABAP environment system. +-->
🔵 Click to expand! - + 1. If not done already, open the **ABAP** perspective as shown in the screenshot below. ![Open ABAP Perspective](../images/abap_perspective.png) -2. If not done already, now create the **ABAP Cloud Project** as shown in the screenshots below. - +2. If not done already, now create the **ABAP Cloud Project** as shown in the screenshots below. + For **step 4** in the screenshot below, you will either import or copy and paste the 🔑 **service key** of the SAP BTP ABAP environment system on which you'll be performing the exercises. Then click **_Next_** to continue. - ![Create ABAP Project Cloud 1/2](../images/steampunk_systemlogon1.png) - + ![Create ABAP Project Cloud 1/2](../images/steampunk_systemlogon1.png) + For **step 7** in the screenshot below, use the email and password of your ABAP user to log in to the system. - - You can keep the default **_Project name_** and click **_Finish_** to create the new ABAP Cloud Project in the **_Project Explorer_** view. - ![Create ABAP Project Cloud 2/2](../images/steampunk_systemlogon2.png) + You can keep the default **_Project name_** and click **_Finish_** to create the new ABAP Cloud Project in the **_Project Explorer_** view. -
+ ![Create ABAP Project Cloud 2/2](../images/steampunk_systemlogon2.png) + ## Helpful Information + [^Top of page](#) > This section contains some helpful information for the exercises: _Find/Replace_ functionality, modern ABAP syntax, and useful ADT shortcuts. @@ -108,12 +111,12 @@ Please inform the SAP staff during the event if you have not yet received the em ### Find/Replace -In the course of these exercises you will frequently see the task to "_replace the placeholder **`###`** with your assigned suffix_", where *###* is your assigned suffix. +In the course of these exercises you will frequently see the task to "_replace the placeholder **`###`** with your assigned suffix_", where _###_ is your assigned suffix. For this it's recommended to make use of the **Find/Replace** feature of the Eclipse Editor. It can be opened either via the menu (**_Edit -> Find/Replace..._**) or via **Ctrl+F**. - - ![find and replace](../images/find01.png) - + +![find and replace](../images/find01.png) + Choosing **Replace All** allows you to replace all ocurrences of **`###`** with your assigned suffix. ### ABAP Pretty Printer (ABAP Formatter) @@ -124,9 +127,8 @@ For this make use of the shortcut **`Shift + F1`** The modern, declarative, and expression-oriented ABAP language syntax will be used in the different exercises. It allows developers to write more simple and concise source code using new language features like inline declarations, constructor expressions. -> **Find more information in the ABAP Keyword Documentation**: [ABAP - Programming Language](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_reference.htm) +> **Find more information in the ABAP Keyword Documentation**: [ABAP - Programming Language](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_reference.htm) - ### Useful ADT Shortcuts Here are some useful ADT keyboard shortcuts for the ABAP development in Eclipse. @@ -135,12 +137,12 @@ Here are some useful ADT keyboard shortcuts for the ABAP development in Eclipse. More useful ADT shortcuts can be found here: [Link](https://blogs.sap.com/2013/11/21/useful-keyboard-shortcuts-for-abap-in-eclipse/). -> **Info**: You can display the full list of available shortcuts in the **Show Key Assit** in ADT by pressing **Ctrl+Shift+L**. - +> **Info**: You can display the full list of available shortcuts in the **Show Key Assist** in ADT by pressing **Ctrl+Shift+L**. + +## Summary -## Summary [^Top of page](#) You can continue with the next exercise - **[Exercise 1: Inspect your Exercise Package - RAP BO & Business Service](../ex01/README.md)** diff --git a/exercises/ex01/README.md b/exercises/ex01/README.md index 69e495e..7e12db0 100644 --- a/exercises/ex01/README.md +++ b/exercises/ex01/README.md @@ -2,18 +2,18 @@ # Exercise 1: Generate and Inspect your Exercise Package -## Introduction +## Introduction In this exercise, you will generate and make yourself familiar with your exercise package **`ZRAP110_###`**, where **`###`** is your assigned suffix. - -This generated package will contain an OData-V4-based UI service and all the RAP artifacts required for this workshop. The UI service is based on a managed Business Object (BO) with two entities, _travel_ and _booking_, with generic transactional behavior - i.e. CRUD: Create, Read, Update, and Delete. +This generated package will contain an OData-V4-based UI service and all the RAP artifacts required for this workshop. The UI service is based on a managed Business Object (BO) with two entities, _travel_ and _booking_, with generic transactional behavior - i.e. CRUD: Create, Read, Update, and Delete. -For your convenience, the class **`ZDMO_GEN_RAP110_SINGLE`** is provided to you to generate the package **`ZRAP110_###`** alongside with the aforementioned RAP business object after execution. You can find the steps in Exercise 1.1. +For your convenience, the class **`ZDMO_GEN_RAP110_SINGLE`** is provided to you to generate the package **`ZRAP110_###`** alongside with the aforementioned RAP business object after execution. You can find the steps in Exercise 1.1. ### Exercises @@ -21,133 +21,130 @@ For your convenience, the class **`ZDMO_GEN_RAP110_SINGLE`** is provided to you - [1.2 - Access your exercise Package](#exercise-12-access-your-exercise--package) - [1.3 - Brief Explanation of the generated ABAP Artefacts](#exercise-13-brief-explanation-of-the-generated-abap-artefacts) - [1.4 - Test the _Travel_ App](#exercise-14-test-the-travel-app) -- [Summary](#summary) +- [Summary](#summary) ## Exercise 1.1: Generate your ![package](../images/adt_package.png) Package -> For **⚠ ASUG 2023 TechConnect** users -> Please skip step 1.1., because the packages have been pre-generated for convenience in the dedicated workshop system. - +> For **⚠ ASUG 2023 TechConnect** users +> Please skip step 1.1., because the packages have been pre-generated for convenience in the dedicated workshop system. +
🔵 Click to expand! 1. Right-click **Favorite Objects** and click **Add Object**. - package + package -3. Search for **`ZDMO_GEN_RAP110_SINGLE`**, select it and click **OK**. +2. Search for **`ZDMO_GEN_RAP110_SINGLE`**, select it and click **OK**. - package + package -5. Right-click **`ZDMO_GEN_RAP110_SINGLE`**, select **Run As** > **ABAP Application (Console) F9**. +3. Right-click **`ZDMO_GEN_RAP110_SINGLE`**, select **Run As** > **ABAP Application (Console) F9**. - package + package -7. Now your package is created. Check the ABAP console. **⚠Copy the suffix for later use.** +4. Now your package is created. Check the ABAP console. **⚠Copy the suffix for later use.** - package + package -
## Exercise 1.2: Access your exercise ![package](../images/adt_package.png) Package [^Top of page](#) > Add your package to **_Favorite Packages_** - +
🔵 Click to expand! - + 1. Open your ABAP Cloud project, right-click **Favorite Packages** and select **Add Package**. - - package - -2. Search for your package **`ZRAP110_###`** , select it and click **OK**. - + + package + +2. Search for your package **`ZRAP110_###`** , select it and click **OK**. + > ⚠ `###` is your **suffix and GroupID**. - package - + package + 3. Now your ABAP package is added to favorite packages. - - package - -
+ package + + ## Exercise 1.3: Brief Explanation of the generated ABAP Artefacts + [^Top of page](#) > Get to know the generated **ABAP development objects**. ->> **Regarding ⚠ warnings about missing CDS access controls** ->> Please ignore the warnings about missing access control that will be displayed for the CDS views entities `ZRAP110_R_TravelTP_###`, `ZRAP110_C_TravelTP_###`, `ZRAP110_R_BookingTP_###`, and `ZRAP110_C_BookingTP_###`. These is due to the view annotation `@AccessControl.authorizationCheck: #CHECK` specified in these entities. ->> Due to time constraints, we will not define CDS access control in this workshop. ->> ->> You can suppress these warnings by changing the annotation value to `#NOT_REQUIRED`. +> > **Regarding ⚠ warnings about missing CDS access controls** +> > Please ignore the warnings about missing access control that will be displayed for the CDS views entities `ZRAP110_R_TravelTP_###`, `ZRAP110_C_TravelTP_###`, `ZRAP110_R_BookingTP_###`, and `ZRAP110_C_BookingTP_###`. These is due to the view annotation `@AccessControl.authorizationCheck: #CHECK` specified in these entities. +> > Due to time constraints, we will not define CDS access control in this workshop. +> > +> > You can suppress these warnings by changing the annotation value to `#NOT_REQUIRED`.
🔵 Click to expand! - 1. Go to the **Project Explorer**, select your package ![package](../images/adt_package.png)**`ZRAP110_###`** and check all generated ABAP repository objects +1. Go to the **Project Explorer**, select your package ![package](../images/adt_package.png)**`ZRAP110_###`** and check all generated ABAP repository objects - table - - Below is a brief explanation of the generated artefacts for the different RAP layers: Base BO, BO Projection, Business Service, and addtional help classes. - - **Base Business Object (BO) Layer** + table + Below is a brief explanation of the generated artefacts for the different RAP layers: Base BO, BO Projection, Business Service, and addtional help classes. - **Base BO Nodes _Travel_ and _Booking_** - - | **Object Name** | **Description** | - |:----------------------------- |:------------------------ | - | ![ddls icon](../images/adt_ddls.png)**`ZRAP110_R_TravelTP_###`** | (aka _Root Base BO view_): This **data definition** defines the data model of the root entity _Travel_ which is the only node of our business object). | - | ![../ddls icon](../images/adt_ddls.png)**`ZRAP110_R_BookingTP_###`** | (aka _Child Base BO view_): This **data definition** defines the data model of the child entity _Booking_ which is the only node of our root BO entity). | - | ![../bdef icon](../images/adt_bdef.png)**`ZRAP110_R_TravelTP_###`** | (aka _Base BO behavior): This **behavior definition** contains the definition of the standard transactional behavior of the root base _Travel_ BO entity and the child base _Booking_ BO entity. It is a _managed_ and _draft-enabled_ implementation. | - | ![../tabl icon](../images/adt_tabl.png)**`ZRAP110_ATRAV###`** and **`ZRAP110_ABOOK###`** | (aka _Active tables_): These **database tables** are used to persist the consistent data from _travel_ and _booking_ instances respectively at runtime. It is managed by the RAP framework. | - | ![../tabl icon](../images/adt_tabl.png)**`ZRAP110_DTRAV###`** and **`ZRAP110_DBOOK###`** | (aka _Draft tables_): These **database tables** are used to temporary store the data from draft _travel_ and _booking_ instances at runtime. It is managed by the RAP framework. | - | ![../class icon](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and **`ZRAP110_BP_TRAVELTP_###`** | (aka _Behavior pool_): These **ABAP classes** are used to provide the implementation of the behavior defined in the behavior definition `ZRAP110_R_TravelTP_###` and `ZRAP110_R_BookingTP_###` of the base _Travel_ and _Booking_ BO nodes. | + **Base Business Object (BO) Layer** - ______________________________________________________________________________________ - - **BO Node Projection Nodes _Travel_ and _Booking_** + **Base BO Nodes _Travel_ and _Booking_** - The BO projection represents the consumption specific view on the BO data model and behavior. + | **Object Name** | **Description** | + | :------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | + | ![ddls icon](../images/adt_ddls.png)**`ZRAP110_R_TravelTP_###`** | (aka _Root Base BO view_): This **data definition** defines the data model of the root entity _Travel_ which is the only node of our business object). | + | ![../ddls icon](../images/adt_ddls.png)**`ZRAP110_R_BookingTP_###`** | (aka _Child Base BO view_): This **data definition** defines the data model of the child entity _Booking_ which is the only node of our root BO entity). | + | ![../bdef icon](../images/adt_bdef.png)**`ZRAP110_R_TravelTP_###`** | (aka _Base BO behavior): This **behavior definition** contains the definition of the standard transactional behavior of the root base \_Travel_ BO entity and the child base _Booking_ BO entity. It is a _managed_ and _draft-enabled_ implementation. | + | ![../tabl icon](../images/adt_tabl.png)**`ZRAP110_ATRAV###`** and **`ZRAP110_ABOOK###`** | (aka _Active tables_): These **database tables** are used to persist the consistent data from _travel_ and _booking_ instances respectively at runtime. It is managed by the RAP framework. | + | ![../tabl icon](../images/adt_tabl.png)**`ZRAP110_DTRAV###`** and **`ZRAP110_DBOOK###`** | (aka _Draft tables_): These **database tables** are used to temporary store the data from draft _travel_ and _booking_ instances at runtime. It is managed by the RAP framework. | + | ![../class icon](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and **`ZRAP110_BP_TRAVELTP_###`** | (aka _Behavior pool_): These **ABAP classes** are used to provide the implementation of the behavior defined in the behavior definition `ZRAP110_R_TravelTP_###` and `ZRAP110_R_BookingTP_###` of the base _Travel_ and _Booking_ BO nodes. | - | **Object Name** | **Description** | - |:----------------------------- |:------------------------ | - | ![../ddls icon](../images/adt_ddls.png)**`ZRAP110_C_TravelTP_###`** | (aka _BO projection view_): This **data definition** is used to define the projected data model of the root entity _Travel_ relevant for the present scenario. Currently almost all fields of the underlying base BO view are exposed and the definition of metadata extension is allowed using the view annotations `@Metadata.allowExtensions: true`. | - | ![../ddls icon](../images/adt_ddls.png)**`ZRAP110_C_BookingTP_###`** | (aka _BO projection view_): This **data definition** is used to define the projected data model of the child entity _Booking_ relevant for the present scenario. | - | ![../bdef icon](../images/adt_bdef.png)**`ZRAP110_C_TravelTP_###`** | (aka _BO behavior projection_): This **behavior definition** exposes the subset of the underlying base _Travel_ and _Booking_ BO entities which is relevant for the present scenario using the keyword **`use`**. | - | ![../ddlx icon](../images/adt_ddlx.png)**`ZRAP110_C_TravelTP_###`** and **`ZRAP110_C_BookingTP_###`** | These **metadata extension** are used to annotate the views `ZRAP100_C_TravelTP_###` and `ZRAP100_C_BookingTP_###`respectively and their elements with UI semantics via CDS annotations. | + *** - ______________________________________________________________________________________ - - **Business Service** + **BO Node Projection Nodes _Travel_ and _Booking_** - | **Object Name** | **Description** | - |:----------------------------- |:------------------------ | - | ![srvd icon](../images/adt_srvd.png)**`ZRAP110_UI_TRAVELTP_###`** | A service definition is used to define the relevant entity sets for our service and also to provide local aliases if needed. Only the _Travel_ entity set is exposed in the present scenario. | - | ![srvb icon](../images/adt_srvb.png)**`ZRAP110_UI_TRAVELTP_O4_###`** | This service binding is used to expose the generated service definition as OData V4 based UI service. Other binding types (protocols and scenarios) are supported in the service binding wizard. | + The BO projection represents the consumption specific view on the BO data model and behavior. - ______________________________________________________________________________________ - - **Additional generated ABAP Classes** - + | **Object Name** | **Description** | + | :---------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | + | ![../ddls icon](../images/adt_ddls.png)**`ZRAP110_C_TravelTP_###`** | (aka _BO projection view_): This **data definition** is used to define the projected data model of the root entity _Travel_ relevant for the present scenario. Currently almost all fields of the underlying base BO view are exposed and the definition of metadata extension is allowed using the view annotations `@Metadata.allowExtensions: true`. | + | ![../ddls icon](../images/adt_ddls.png)**`ZRAP110_C_BookingTP_###`** | (aka _BO projection view_): This **data definition** is used to define the projected data model of the child entity _Booking_ relevant for the present scenario. | + | ![../bdef icon](../images/adt_bdef.png)**`ZRAP110_C_TravelTP_###`** | (aka _BO behavior projection_): This **behavior definition** exposes the subset of the underlying base _Travel_ and _Booking_ BO entities which is relevant for the present scenario using the keyword **`use`**. | + | ![../ddlx icon](../images/adt_ddlx.png)**`ZRAP110_C_TravelTP_###`** and **`ZRAP110_C_BookingTP_###`** | These **metadata extension** are used to annotate the views `ZRAP100_C_TravelTP_###` and `ZRAP100_C_BookingTP_###`respectively and their elements with UI semantics via CDS annotations. | + + *** + + **Business Service** + + | **Object Name** | **Description** | + | :------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | ![srvd icon](../images/adt_srvd.png)**`ZRAP110_UI_TRAVELTP_###`** | A service definition is used to define the relevant entity sets for our service and also to provide local aliases if needed. Only the _Travel_ entity set is exposed in the present scenario. | + | ![srvb icon](../images/adt_srvb.png)**`ZRAP110_UI_TRAVELTP_O4_###`** | This service binding is used to expose the generated service definition as OData V4 based UI service. Other binding types (protocols and scenarios) are supported in the service binding wizard. | - | **Object Name** | **Description** | - |:----------------------------- |:------------------------ | - | ![srvd icon](../images/adt_class.png)**`ZRAP110_CALC_TRAV_ELEM_###`** | These **ABAP classes** are used to provide the implementation of the travel virtual elements calculation. | - | ![srvb icon](../images/adt_class.png)**`ZRAP110_CALC_BOOK_ELEM_###`** | These **ABAP classes** are used to provide the implementation of the booking virtual elements calculation. | + *** + + **Additional generated ABAP Classes** + + | **Object Name** | **Description** | + | :-------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------- | + | ![srvd icon](../images/adt_class.png)**`ZRAP110_CALC_TRAV_ELEM_###`** | These **ABAP classes** are used to provide the implementation of the travel virtual elements calculation. | + | ![srvb icon](../images/adt_class.png)**`ZRAP110_CALC_BOOK_ELEM_###`** | These **ABAP classes** are used to provide the implementation of the booking virtual elements calculation. | ---
+## Exercise 1.4: Test the _Travel_ App -## Exercise 1.4: Test the _Travel_ App [^Top of page](#) > Now, check the local service endpoint of your service binding **`ZRAP110_UI_TRAVEL_O4_###`**, and use the preview to test the _Travel_ app by creating, updating an deleting _travel_ instances and _booking_ instances. @@ -156,24 +153,24 @@ For your convenience, the class **`ZDMO_GEN_RAP110_SINGLE`** is provided to you 🔵 Click to expand! +1. Open the service binding ![srvb icon](../images/adt_srvb.png)**`ZRAP110_UI_TRAVEL_O4_###`** and click on the link **`Publish local service endpoint`** in the **Service Version Details** section. - 1. Now start the **_Fiori elements App Preview_** for the **`Travel`** entity set. - - For that, either select the entity set **`Travel`** in the **Entity Set and Associations** section and press the **Preview** button or simply doubleclicking on it. - - The _Travel_ app will be started in your browser. - - table + table -2. Create, update and delete _travel_ and _booking_ entries. - - table + This steps may take some seconds. Do not close the **_Service Binding_** editor during this process. +--> + +1. Now start the **_Fiori elements App Preview_** for the **`Travel`** entity set. + + For that, either select the entity set **`Travel`** in the **Entity Set and Associations** section and press the **Preview** button or simply double-clicking on it. + + The _Travel_ app will be started in your browser. + + table + +2. Create, update and delete _travel_ and _booking_ entries. + + table Only the generic CRUD - i.e. create, read, update, and delete - logic is available for now. You will enhance the BO behavior in the next exercises. @@ -182,9 +179,10 @@ For your convenience, the class **`ZDMO_GEN_RAP110_SINGLE`** is provided to you ## Summary [^Top of page](#) -Now that you've... -- inspected the generated _Travel_ BO with its two entities _travel_ and _booking_, -- previewed the UI service, and +Now that you've... + +- inspected the generated _Travel_ BO with its two entities _travel_ and _booking_, +- previewed the UI service, and - played around with the Fiori elements _Travel_ app, you can continue with the next exercise – **[Exercise 2: Enhance the Data Model of the Base and Projected BO](../ex02/README.md)** diff --git a/exercises/ex02/README.md b/exercises/ex02/README.md index c9aa3e0..aa81473 100644 --- a/exercises/ex02/README.md +++ b/exercises/ex02/README.md @@ -1,24 +1,24 @@ [Home - RAP110](../../README.md) -# Exercise 2: Enhance the Data Model of the Base and Projected Business Object (BO) +# 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](../ex01/README.md)). -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. +In the previous exercise, you've had a look at your exercise package **`ZRAP110_###`**, where **`###`** is your assigned suffix (see [Exercise 1](../ex01/README.md)). +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: + - [2.1 - Enhance the Data Model of the Base _Travel_ BO Entity](#exercise-21-enhance-the-data-model-of-the-base-travel-bo) - [2.2 - Enhance the Data Model of the Projected _Travel_ BO Entity](#exercise-22-enhance-the-data-model-of-the-projected-travel-bo-entity) - [2.3 - Enhance the Data Model of the Projected _Booking_ BO Entity](#exercise-23-enhance-the-data-model-of-the-projected-booking-bo-entity) - [2.4 - Preview and Test the Enhanced Travel App](#exercise-24-preview-and-test-the-enhanced-travel-app) - [Summary](#summary) -> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your assigned suffix in the exercise steps below. - -> ℹ **Further reading**: [CDS Annotations](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/cds-annotations) | [Working with Large Objects](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/working-with-large-objects) | [Using Virtual Elements in CDS Projection Views](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/using-virtual-elements-in-cds-projection-views) +> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your assigned suffix in the exercise steps below. +> ℹ **Further reading**: [CDS Annotations](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/cds-annotations) | [Working with Large Objects](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/working-with-large-objects) | [Using Virtual Elements in CDS Projection Views](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/using-virtual-elements-in-cds-projection-views) ### About Virtual Elements @@ -34,8 +34,7 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO - -## Exercise 2.1: Enhance the Data Model of the Base _Travel_ BO +## 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). @@ -45,9 +44,9 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO ### 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 ![datadefinition](../images/adt_ddls.png)**`ZRAP110_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. +> Adjust the CDS data model of the base _Travel_ BO entity in view entity ![datadefinition](../images/adt_ddls.png)**`ZRAP110_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! @@ -74,32 +73,33 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO
About the annotation `@Semantics.largeObject` - Here is a short explanation of the attributes of the element 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). + - **`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](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/semantics-annotations) -
- - 3. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**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 +
+ +3. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**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.
@@ -112,75 +112,75 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO
🟣 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](https://github.com/SAP-samples/abap-platform-rap-workshops/tree/main/rap1xx/rap100#exercises). - +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](https://github.com/SAP-samples/abap-platform-rap-workshops/tree/main/rap1xx/rap100#exercises). + Replace the whole data definition of the _travel_ BO projection view ![datadefinition](../images/adt_ddls.png)**`ZRAP110_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 icon](../images/adt_ddls.png)[CDS Projection View ZRAP110_C_TRAVELTP_###](sources/EX02_DDLS_ZRAP110_C_TRAVELTP.txt) - - 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 icon](../images/adt_class.png)**`ZRAP110_CALC_TRAV_ELEM_###`** will be used to calculate this virtual element is specified. - + + ▶📄 **Source code document:** ![ddls icon](../images/adt_ddls.png)[CDS Projection View ZRAP110*C_TRAVELTP*###](sources/EX02_DDLS_ZRAP110_C_TRAVELTP.txt) + +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 icon](../images/adt_class.png)**`ZRAP110_CALC_TRAV_ELEM_###`** will be used to calculate this virtual element is specified. + Uncomment in the _Travel_ BO projection view ![datadefinition](../images/adt_ddls.png)**`ZRAP110_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. - + ```ABAP @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](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. Close the data definition. + + > ℹ **Info:** Due to time constraint, a skeleton 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](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**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 icon](../images/adt_class.png)**`ZRAP110_CALC_TRAV_ELEM_###`**, where `###`is your assigned suffix. +> Implement the logic of the virtual element **`OverallStatusIndicator`** in the ABAP Class ![class icon](../images/adt_class.png)**`ZRAP110_CALC_TRAV_ELEM_###`**, where `###` is your assigned suffix.
🟣 Click to expand! - 1. Open your ABAP class ![class icon](../images/adt_class.png)**`ZRAP110_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**. +1. Open your ABAP class ![class icon](../images/adt_class.png)**`ZRAP110_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**. ```ABAP 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(). CASE . "virtual elements from TRAVEL entity @@ -188,103 +188,103 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO 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(). - + * = zrap110_calc_trav_elem_###=>calculate_trav_status_ind( ). - - ENDLOOP. - ct_calculated_data = CORRESPONDING #( lt_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(). CASE . WHEN 'OVERALLSTATUSINDICATOR'. APPEND 'OVERALLSTATUS' TO et_requested_orig_elements. - + ENDCASE. ENDLOOP. ENDIF. ENDMETHOD. - + ENDCLASS. - ``` - - **Brief explanation**: + ``` + + **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](https://help.sap.com/docs/btp/fc4c71aa50014fd1b43721701471913d/319380e0cef94051ae9aa292ffadb59a.html) -
- - 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. - + - 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](https://help.sap.com/docs/btp/fc4c71aa50014fd1b43721701471913d/319380e0cef94051ae9aa292ffadb59a.html) + +
+ +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. + ```ABAP 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: - + ``` + + 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`**. + +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. - + +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. - + ```ABAP - METHOD calculate_trav_status_ind. + METHOD calculate_trav_status_ind. result = CORRESPONDING #( is_original_data ). "travel status indicator - "(criticality: 1 = red | 2 = orange | 3 = green) + "(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. + result-OverallStatusIndicator = 3. WHEN OTHERS. ENDCASE. - ENDMETHOD. - ``` - + ENDMETHOD. + ``` + ABAP Class - - 5. Now, uncomment the method call **`calculate_trav_status_ind`** within the method **`CALCULATE`**. - + +5. Now, uncomment the method call **`calculate_trav_status_ind`** within the method **`CALCULATE`**. + > ` = zrap110_calc_trav_elem_###=>calculate_trav_status_ind( ).` - - ABAP Class - - 6. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. Close the ABAP class. - + + ABAP Class + +6. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. Close the ABAP class. +
@@ -297,17 +297,17 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO
🔵 Click to expand! - ### Exercise 2.3.1: Enhance the _Booking_ BO projection view +### Exercise 2.3.1: Enhance the _Booking_ BO projection view + +> Enhance the _Booking_ BO projection view ![ddls icon](../images/adt_ddls.png)**`ZRAP110_C_BookingTP_###`**. +> +> Besides 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_". -> Enhance the _Booking_ BO projection view ![ddls icon](../images/adt_ddls.png)**`ZRAP110_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! @@ -326,8 +326,8 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO ABAP Class
- Source code - + Source code + ```ABAP @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZRAP110_CALC_BOOK_ELEM_###' @EndUserText.label: 'Booking Status Indicator' @@ -343,16 +343,17 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZRAP110_CALC_BOOK_ELEM_###' @EndUserText.label: 'Days to Flight Indicator' - virtual DaysToFlightIndicator : abap.int1, - ``` - + virtual DaysToFlightIndicator : abap.int1, + ``` +
- - 5. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. Close the data definition. - + +5. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. Close the data definition. +
-### Exercise 2.3.2: Calculate the Virtual Elements of the _Booking_ BO Entity +### 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 icon](../images/adt_class.png)**`ZRAP110_CALC_BOOK_ELEM_###`**, where `###`is your assigned suffix. @@ -360,51 +361,51 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO
🟣 Click to expand! - - - 1. Open your ABAP class ![ABAP class](../images/adt_class.png)**`ZRAP110_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**. + > + > ABAP Class --> + +1. Open your ABAP class ![ABAP class](../images/adt_class.png)**`ZRAP110_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**. ```ABAP 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(). + + LOOP AT it_requested_calc_elements ASSIGNING FIELD-SYMBOL(). CASE . "virtual elements from BOOKING entity WHEN 'INITIALDAYSTOFLIGHT' OR 'REMAININGDAYSTOFLIGHT' - OR 'DAYSTOFLIGHTINDICATOR' OR 'BOOKINGSTATUSINDICATOR'. + 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(). - + * = zrap110_calc_book_elem_###=>calculate_days_to_flight( ). - + 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(). @@ -420,13 +421,13 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO COLLECT `BOOKINGSTATUS` INTO et_requested_orig_elements. ENDCASE. ENDLOOP. - ENDIF. + ENDIF. ENDMETHOD. - + ENDCLASS. - ``` - - 2. Define the class method interface **`calculate_days_to_flight`** in the public section of the class definition. + ``` + +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. @@ -435,24 +436,24 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO 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: - + ``` + + Your source code should look like this: + ABAP Class - - 3. Save ![save icon](../images/adt_save.png) (**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`**. + +3. Save ![save icon](../images/adt_save.png) (**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. - + 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. + ```ABAP METHOD calculate_days_to_flight. DATA(today) = cl_abap_context_info=>get_system_date( ). @@ -500,8 +501,8 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO WHEN OTHERS. ENDCASE. ENDMETHOD. - ``` - + ``` +
About the virtual elements @@ -510,16 +511,16 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO - **`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 -
- - 7. Now, uncomment the method call **`calculate_trav_status_ind`** within the method **`CALCULATE`**. - +
+ +6. Now, uncomment the method call **`calculate_trav_status_ind`** within the method **`CALCULATE`**. + > ` = zrap110_calc_book_elem_###=>calculate_days_to_flight( ).` - - ABAP Class - - 8. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. Close the ABAP class. - + + ABAP Class + +7. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. Close the ABAP class. +
@@ -527,12 +528,12 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO ## Exercise 2.4: Preview and Test the enhanced Travel App [^Top of page](#) -> Test the enhanced SAP Fiori elements application. +> 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](../images/adt_srvb.png) **`ZRAP110_UI_TRAVEL_O4_###`** by double-clickin the _**Travel**_ entity set. + 1. Refresh your browser or start the SAP Fiori elements app preview from your service binding ![../servicebinding](../images/adt_srvb.png) **`ZRAP110_UI_TRAVEL_O4_###`** by double-clicking the _**Travel**_ entity set. If you haven't created any entries, please do one travel entry now. @@ -550,30 +551,31 @@ In this exercise, you will enhance the CDS data model of the base BO and the BO 4. Now you can see the **Overall Status Indicator**. - ABAP Class + ABAP Class + +5. Select your entry. + + 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 + + ABAP Class + + Now you can see, that you are able to upload attachement on the _Travel_ object page. + + ABAP Class
+## Summary -## Summary [^Top of page](#) -Now that you've... +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 +- 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](../ex03/README.md)** diff --git a/exercises/ex03/README.md b/exercises/ex03/README.md index e31419b..9f334d5 100644 --- a/exercises/ex03/README.md +++ b/exercises/ex03/README.md @@ -3,12 +3,13 @@ # 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](../ex02/README.md)). -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. +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](../ex02/README.md)). +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 non-standard operations, validations, instance and factory actions, determinations, and functions. ### Exercises: + - [3.1 - How to handle this exercise](#exercise-31-how-to-handle-this-exercise-) 💡 - [3.2 - Define the Late Numbering and the Static Field Control](#exercise-32-define-the-late-numbering-and-the-static-field-control) - [3.3 - Define the Validations](#exercise-33-define-the-validations) @@ -17,18 +18,17 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B - [3.6 - Define the Functions](#exercise-36-define-the-functions) - [3.7 - Define the Dynamic Feature Control](#exercise-37-define-the-dynamic-feature-control) - [3.8 - Adjust the Behavior Implementation Classes](#exercise-38-adjust-the-behavior-implementation-classes) -- [3.9 - Enhance the BO Behavior Projection](#exercise-39-enhance-the-bo-behavior-projection) +- [3.9 - Enhance the BO Behavior Projection](#exercise-39-enhance-the-bo-behavior-projection) - [Summary](#summary) -> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your assigned suffix in the exercise steps below. - +> **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 +#### Numbering
ℹ Click to expand! @@ -36,56 +36,56 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B > 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](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/numbering) -
+
-#### Frontend validation & Backend validations +#### Frontend validation & Backend validations
ℹ Click to expand! -> Validations are used to ensure the data consistency. +> 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. +> 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](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/validations) +> +> **Further reading**: [Validations](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/validations) -
+ -#### Actions +#### 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. +> 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](https://help.sap.com/viewer/923180ddb98240829d935862025004d6/Cloud/en-US/83bad707a5a241a2ae93953d81d17a6b.html) **|** [CDS BDL - non-standard operations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_nonstandard.htm) **|** [ABAP EML - response_param](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapeml_response.htm) -> **Further reading**: [RAP BO Contract](https://help.sap.com/docs/BTP/923180ddb98240829d935862025004d6/3a402c5cf6a74bc1a1de080b2a7c6978.html) **|** [RAP BO Provider API (derived types, %cid, implicit response parameters,...)](https://help.sap.com/docs/BTP/923180ddb98240829d935862025004d6/2a3da8a5b19e4f6b953e9a11fb5cc747.html?version=Cloud) +> **Further reading**: [RAP BO Contract](https://help.sap.com/docs/BTP/923180ddb98240829d935862025004d6/3a402c5cf6a74bc1a1de080b2a7c6978.html) **|** [RAP BO Provider API (derived types, %cid, implicit response parameters,...)](https://help.sap.com/docs/BTP/923180ddb98240829d935862025004d6/2a3da8a5b19e4f6b953e9a11fb5cc747.html?version=Cloud) > -> **Further reading**: [Actions](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/actions) +> **Further reading**: [Actions](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/actions) -
+ -#### Determinations +#### 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. +> 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](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/determinations) +> **Further reading**: [Determinations](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/determinations)
@@ -95,41 +95,39 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B ℹ 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](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/adding-static-and-dynamic-feature-control) -
+ - + + +## Exercise 3.1: How to handle this exercise 💡 -## 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. +> +> - **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 ![bdef](../images/adt_bdef.png)**`ZRAP110_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**. + Replace all occurences of the placeholder `###` with your assigned suffix using **Ctrl+F**. ▶📄 **Source code document:** ![bdef](../images/adt_bdef.png)[CDS Behavior Definition ZRAP110_R_TRAVELTP_###](sources/EX03_BDEF_ZRAP110_R_TRAVELTP.txt) 3. Save ![save icon](../images/adt_save.png) (**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: ![tabl](../images/adt_tabl.png)**`ZRAP110_DTRAV###`**. + 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 recreated. + 4. Recreate the draft table for _travel_ entities: ![tabl](../images/adt_tabl.png)**`ZRAP110_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. @@ -137,11 +135,11 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B Draft table - 5. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + 5. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. Close the _travel_ database table definition and go back to the behavior definition. - 4. Now, recreate the draft table for _booking_ entities: ![tabl](../images/adt_tabl.png)**`ZRAP110_DBOOK###`**. + 4. Now, recreate the draft table for _booking_ entities: ![tabl](../images/adt_tabl.png)**`ZRAP110_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. @@ -149,24 +147,23 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B Draft table - 5. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + 5. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. Close the _booking_ database table definition and go back to the behavior definition. - 6. As last step, save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes in the behavior definition. - - 7. You can now go ahead directly with **[Exercise 3.8](#exercise-38-adjust-the-behavior-implementation-classes)** to adjust the behavior implementation classes, aka behavior pools, of both BO entities_travel_ and _ booking_. - -
+ 6. As last step, save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes in the behavior definition. +7. You can now go ahead directly with **[Exercise 3.8](#exercise-38-adjust-the-behavior-implementation-classes)** 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](../images/adt_bdef.png) **`ZRAP110_R_TRAVELTP_###`** of the _Travel_ BO. +[^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](../images/adt_bdef.png) **`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 @@ -176,103 +173,103 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B 1. Open the behavior definition ![bdef icon](../images/adt_bdef.png)**`ZRAP110_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_ ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`** as shown on the screenshot. +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_ ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`** as shown on the screenshot. ```ABAP 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. - + +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: ![tabl](../images/adt_tabl.png)**`ZRAP110_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. - + +4. Recreate the draft table for _travel_ entities: ![tabl](../images/adt_tabl.png)**`ZRAP110_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](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. - + +5. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**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: - + +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: + - **`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**. - ```ABAP + Insert the code snippet provided below to the behavior definition as shown on the screenshot. + + Replace the readonly **`TravelID`** with following: + + ```ABAP field ( readonly ) TravelID; field ( readonly ) TotalPrice; - field ( mandatory ) BeginDate, EndDate; - ``` - + field ( mandatory ) BeginDate, EndDate; + ``` + Draft table - - 7. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) the changes and go ahead with the next step. - + +7. Save ![save icon](../images/adt_save.png) (**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 +### 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 ![bdef](../images/adt_bdef.png)**`ZRAP110_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 **`{`**. ```ABAP 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: ![tabl](../images/adt_tabl.png)**`ZRAP110_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](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**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: - ```ABAP - field ( readonly ) BookingID; - field ( mandatory ) CustomerID, CarrierID, Flightdate, BookingStatus; - ``` - - Draft table - - 5. Save ![save icon](../images/adt_save.png) the changes and go ahead with the next step. - +2. Recreate the draft table for _booking_ entities: ![tabl](../images/adt_tabl.png)**`ZRAP110_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](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**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: + + ```ABAP + field ( readonly ) BookingID; + field ( mandatory ) CustomerID, CarrierID, Flightdate, BookingStatus; + ``` + + Draft table + +5. Save ![save icon](../images/adt_save.png) the changes and go ahead with the next step. +
@@ -287,7 +284,7 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B
🔵 Click to expand! - + ### Exercise 3.3.1: Define the Validations of the _Travel_ BO entity
@@ -305,21 +302,21 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B ``` 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. - - ```ABAP - draft determine action Prepare - { - validation validateCustomer; - validation validateAgency; - validation validateDates; - } - ``` - - BO Behavior Definition - 3. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) the changes. +2. Add the validations to the **`draft determine action Prepare`** to allow the draft data to be validated before its transition to active data. + + ```ABAP + draft determine action Prepare + { + validation validateCustomer; + validation validateAgency; + validation validateDates; + } + ``` + + BO Behavior Definition + +3. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) the changes.
@@ -347,73 +344,76 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B BO Behavior Definition - 3. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) the changes and go ahead with the next step. + 3. Save ![save icon](../images/adt_save.png) (**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_. +> 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. +> - 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](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/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 ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`**. - - Insert the code snippet provided below and replace the placeholder `###` with your assigned suffix. - - ```ABAP - //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](../images/adt_save.png) (**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`. -
- +1. Define different actions in the behavior definition of the _travel_ root entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`**. + + Insert the code snippet provided below and replace the placeholder `###` with your assigned suffix. + + ```ABAP + //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](../images/adt_save.png) (**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.
@@ -423,22 +423,23 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B
🟣 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 ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`** as shown on the screenshot. - - ```ABAP - //determination(s) - determination setInitialTravelValues on modify { create; } - determination calculateTotalPrice on modify { create; field BookingFee, CurrencyCode; } - ``` - BO Behavior Definition - - 2. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) the changes and go ahead with the next step. +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 ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`** as shown on the screenshot. + + ```ABAP + //determination(s) + determination setInitialTravelValues on modify { create; } + determination calculateTotalPrice on modify { create; field BookingFee, CurrencyCode; } + ``` + + BO Behavior Definition + +2. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) the changes and go ahead with the next step.
@@ -448,26 +449,27 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B 🟣 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. + - **`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 ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TravelTP_###`** as shown on the screenshot. - + ```ABAP //determination(s) determination setInitialBookingValues on modify { create; } //copy & paste - determination calculateTotalPrice on modify { create; field FlightPrice, CurrencyCode; } //** + determination calculateTotalPrice on modify { create; field FlightPrice, CurrencyCode; } //** ``` - + BO Behavior Definition - - 2. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) the changes and go ahead with the next step. - + +2. Save ![save icon](../images/adt_save.png) (**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 ![ddls](../images/adt_ddls.png)`ZRAP110_C_TravelTP_###` for a given _booking_ entity instance. @@ -475,18 +477,18 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B
🔵 Click to expand! -### Exercise 3.6.1: Define the Function of the _Booking_ BO entity +### Exercise 3.6.1: Define the Function of the _Booking_ BO entity
- 🟣 Click to expand! + 🟣 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. + 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 - + ```ABAP @EndUserText.label: 'Abstract entity for Days To Flight' define abstract entity ZRAP110_A_DaysToFlight_### @@ -495,35 +497,36 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B 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 ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TravelTP_###`** as shown on the screenshot. Replace the placeholder `###` with your assigned suffix. - - ```ABAP - //function(s) - function getDaysToFlight result [1] ZRAP110_A_DaysToFlight_###; - ``` - - BO Behavior Definition - - 3. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) the changes and go ahead with the next step. - + +2. Define the instance function **`getDaysToFlight`** in the _booking_ child entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TravelTP_###`** as shown on the screenshot. Replace the placeholder `###` with your assigned suffix. + + ```ABAP + //function(s) + function getDaysToFlight result [1] ZRAP110_A_DaysToFlight_###; + ``` + + BO Behavior Definition + +3. Save ![save icon](../images/adt_save.png) (**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. +> You will now define the dynamic feature control for some of the standard and non-standard operations of the **_Travel_** entity.
🔵 Click to expand! -### Exercise 3.7.1: Define the Dynamic Feature Control of the _Travel_ BO entity +### Exercise 3.7.1: Define the Dynamic Feature Control of the _Travel_ BO entity
🟣 Click to expand! @@ -532,23 +535,24 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B - 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 ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`** as shown on the screenshot. - + - the draft action **`Edit`** + + To achieve this add the statement below in the behavior definition of the _Travel_ root entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`** as shown on the screenshot. + ```ABAP ( features : instance ) ``` - - BO Behavior Definition - - 2. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. - + + BO Behavior Definition + +2. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**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. @@ -556,78 +560,79 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B
🔵 Click to expand! -### Exercise 3.8.1: Adjust the Behavior Implementation Class of the _Travel_ BO entity. +### Exercise 3.8.1: Adjust the Behavior Implementation Class of the _Travel_ BO entity.
- 🟣 Click to expand! + 🟣 Click to expand! -> You will now adjust the behavior implementation class (aka behavior pool) of the _Travel_ entity ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`**. +> You will now adjust the behavior implementation class (aka behavior pool) of the _Travel_ entity ![ABAP class](../images/adt_class.png)**`ZRAP110_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 ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`**, set the cursor on **`late numbering`** and press **Ctrl+1** to start the ADT Quick Fix. - + + For that, go to the behavior definition of the _travel_ entity ![bdef](../images/adt_bdef.png)**`ZRAP110_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 class](../images/adt_class.png)**`ZRAP110_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 - - ```ABAP - 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](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes + + The local saver class **`lsc_zrap110_r_traveltp_###`** has been added to the behavior pool of the _travel_ BO entity ![ABAP class](../images/adt_class.png)**`ZRAP110_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 + + ```ABAP + 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](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes
-### Exercise 3.8.2: Adjust the Behavior Implementation Class of the _Booking_ BO entity +### 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 class](../images/adt_class.png)**`ZRAP110_BP_BookingTP_###`** - 1. Now go to the behavior definition ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TravelTP_###`**, set the cursor on one of the new determinations, validations or the function, e.g. **`validateBookingStatus`**, and press **Ctrl+1**. + 1. Now go to the behavior definition ![bdef](../images/adt_bdef.png)**`ZRAP110_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 - + + 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 + ```ABAP CONSTANTS: "booking status @@ -636,22 +641,22 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B 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](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. - + ``` + + behavior pool + +3. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**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. +> **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! @@ -667,27 +672,29 @@ In this exercise, you will enhance the transactional behavior of your _Travel_ B use action checkDates; ``` - - BO Behavior Definition - - 2. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. Close the behavior projection. - -
-## Summary + BO Behavior Definition + +2. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. Close the behavior projection. + +
+ +## Summary + [^Top of page](#) -> ⚠ **Attention** ⚠ +> ⚠ **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 +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, + - 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, @@ -695,4 +702,3 @@ Now that you've... you can continue with the next exercise – **[Exercise 4: Implement the Base BO Behavior - Late Numbering](../ex04/README.md)** --- - diff --git a/exercises/ex04/README.md b/exercises/ex04/README.md index dcc1153..cf067e6 100644 --- a/exercises/ex04/README.md +++ b/exercises/ex04/README.md @@ -1,49 +1,50 @@ +# Exercise 4: Implement the Base BO Behavior - Late Numbering -# Exercise 4: Implement the Base BO Behavior - Late Numbering +## Introduction -## Introduction +In the previous exercise (see [Exercise 3](../ex03/README.md)), you've enhanced the BO Behavior Definition and Projection. -In the previous exercise (see [Exercise 3](../ex03/README.md)), you've enhanced the BO Behavior Definition and Projection. - -In the present exercise, you will define and implement the base BO behavior for late numbering. +In the present exercise, you will define and implement the base BO behavior for late numbering. ### Exercises - + - [4.1 - Implement the Late Numbering](#exercise-41-implement-the-late-numbering) - [4.2 - Preview and Test the Enhanced Travel App](#exercise-42-preview-and-test-the-enhanced-travel-app) -- [Summary](#summary) +- [Summary](#summary) + +> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned assigned suffix in the exercise steps below. -> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned assigned suffix in the exercise steps below. +### About Numbering -### About 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: + +> 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. The latter will be implemented in the present exercise. -> - 📌**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. -> +> - 📌**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. +> > **Further reading**: [Numbering](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/numbering) - +
## Exercise 4.1: Implement the Late Numbering + [^Top of page](#) > Implement the late numbering for the _travel_ and the _booking_ BO entities in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`**, aka **behavior pool**. Both, the primary key of the _travel_ and the _booking_ instances will be implemented in the same class: _create_ travel entity instances and _create_ booking instance _by association_. Late numbering was defined in [Exercise 3.2](../ex03#exercise-32-define-the-late-numbering-and-the-static-field-control). -> +> > Late numbering is always implemented in the method `adjust_numbers` of the local saver class of the root entity. -> +> > PS: A simplified implementation of number ranges is provided in this exercise.
🔵 Click to expand! - 1. Open the behavior implementation class of the _Travel_ entity ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and navigate to the method **`adjust_numbers`** of the local saver class **`LSC_TRAVEL`** +1. Open the behavior implementation class of the _Travel_ entity ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and navigate to the method **`adjust_numbers`** of the local saver class **`LSC_TRAVEL`** + +2. Insert the source code provided below in the method implementation as shown on the screenshot. - 2. Insert the source code provided below in the method implementation as shown on the screenshot. - Replace all occurences of the placeholder `###` with your assigned suffix using **Ctrl+F**. ```ABAP @@ -56,7 +57,7 @@ In the present exercise, you will define and implement the base BO behavior for cl_numberrange_runtime=>number_get( EXPORTING nr_range_nr = '01' - object = 'ZRAP110###' "Fallback: '/DMO/TRV_M' + object = 'ZRAP110###' "Fallback: '/DMO/TRV_M' quantity = CONV #( lines( mapped-travel ) ) IMPORTING number = DATA(number_range_key) @@ -75,19 +76,19 @@ In the present exercise, you will define and implement the base BO behavior for travel_id_max += 1. -TravelID = travel_id_max. ENDLOOP. - ENDIF. + ENDIF. "--------------insert the code for the booking entity below --------- - + ``` - + Travel MDE - - 3. Enhance the logic for drawing primary keys for _Booking_ BO entity instances created by association. - + +3. Enhance the logic for drawing primary keys for _Booking_ BO entity instances created by association. + Insert the source code provided below after the `ENDIF` of the previoud code block. - + Replace all occurences of the placeholder `###` with your assigned suffix using **Ctrl+F**. - + ```ABAP "Child BO entity: Booking IF mapped-booking IS NOT INITIAL. @@ -112,16 +113,17 @@ In the present exercise, you will define and implement the base BO behavior for -BookingID = max_booking_id. ENDLOOP. ENDLOOP. - ENDIF. + ENDIF. ``` - + Travel MDE - - 4. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + +4. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes.
-## Exercise 4.2: Preview and Test the Enhanced Travel App +## Exercise 4.2: Preview and Test the Enhanced Travel App + [^Top of page](#) > You can now preview and test the changes by creating a new _travel_ instance with _booking_ instances in the _Travel_ app. @@ -129,27 +131,27 @@ In the present exercise, you will define and implement the base BO behavior for
🔵 Click to expand! -1. Refresh your application in the browser using **F5** if the browser is still open - +1. Refresh your application in the browser using **F5** if the browser is still open - or go to your service binding ![srvb icon](../images/adt_srvb.png)**`ZRAP110_UI_TRAVEL_O4_###`** and start the Fiori elements App preview for the **`Travel`** entity set. -2. Create a new _Travel_ instance. +2. Create a new _Travel_ instance. Travel MDE 3. Enter all information and click **Create** under **Booking**. - + Travel MDE - + 4. Now enter all information for booking and click **Apply**. Travel MDE - + 5. Click **Create**. - + Travel MDE - + 6. Check your result. - + Travel MDE
@@ -157,8 +159,9 @@ In the present exercise, you will define and implement the base BO behavior for ## Summary [^Top of page](#) -Now that you've... -- implemented the late numbering for the _travel_ and _booking_ BO entities, +Now that you've... + +- implemented the late numbering for the _travel_ and _booking_ BO entities, - previewed and test the enhanced Fiori elements app, you can continue with the next exercise – **[Exercise 5: Adjust the UI Semantics in the Metadata Extensions](../ex05/README.md)** diff --git a/exercises/ex05/README.md b/exercises/ex05/README.md index 404752f..e03ac16 100644 --- a/exercises/ex05/README.md +++ b/exercises/ex05/README.md @@ -6,167 +6,169 @@ In the previous exercise, you've implemented the late numbering for the late numbering for drawing the primary keys of the _travel_ and the _booking_ BO entities at a later time, during the first storing of the data (see [Exercise 4](../ex04/README.md)). - -In this exercise, you will adjust the layout of the list reports and object pages of your _Travel_ App by enhancing the metadata extension ![metadataextension](../images/adt_ddlx.png) of the _travel_ and the _booking_ BO entities with UI semantics in form of UI-specific annotations (`@UI`). +In this exercise, you will adjust the layout of the list reports and object pages of your _Travel_ App by enhancing the metadata extension ![metadataextension](../images/adt_ddlx.png) of the _travel_ and the _booking_ BO entities with UI semantics in form of UI-specific annotations (`@UI`). ### Exercises: + - [5.1 - Adjust the UI Semantics in the _Travel_ Metadata Extension](#exercise-51-adjust-the-ui-semantics-in-the-travel-metadata-extension-) 💡 - [5.2 - Adjust the UI Semantics in the _Booking_ Metadata Extension](#exercise-52-adjust-the-ui-semantics-in-the-booking-metadata-extension-) 💡 - [5.3 - Preview and Test the Enhanced _Travel_ App](#exercise-53-preview-and-test-the-enhanced-travel-app) - [Summary](#summary) -> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your assigned suffix in the exercise steps below. +> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your assigned suffix in the exercise steps below. -### About UI Semantics in RAP +### About UI Semantics in RAP
Click to expand! #### Develop UI Semantics + > UI-specific CDS annotations can be used to solve the most common UI layout tasks in SAP Fiori elements apps built with RAP. > > **Read more**: [Develop UI Specifics](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/develop-ui-specifics) #### UI Annotations -> UI annotations represent semantic views on business data through the use of specific patterns that are independent of UI technologies. They can be defined either in the ABAP system using UI-specific ABAP CDS annotations or in the SAP Fiori tools. + +> UI annotations represent semantic views on business data through the use of specific patterns that are independent of UI technologies. They can be defined either in the ABAP system using UI-specific ABAP CDS annotations or in the SAP Fiori tools. > -> **Read more**: [All CDS Annotations](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/cds-annotations) | [UI Annotations](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/ui-annotations) +> **Read more**: [All CDS Annotations](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/cds-annotations) | [UI Annotations](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/ui-annotations) + +#### About the SAP Fiori elements Feature Showcase App for RAP and ABAP CDS -#### About the SAP Fiori elements Feature Showcase App for RAP and ABAP CDS > The SAP Fiori Elements Feature Showcase App for RAP provides a reference technical app that showcases the SAP Fiori Elements UI features which can be implemented using ABAP CDS annotations. The feature showcase app is developed using the ABAP RESTful Application Programming Model (RAP) for oData V4 and is transactional- and draft-enabled. > > **Read more**: [SAP Fiori elements Showcase App@SAP Blogs](https://blogs.sap.com/2022/12/19/the-sap-fiori-elements-feature-showcase-with-rap-and-abap-cds-annotations/) | [SAP Fiori elements Showcase App@GitHub](https://github.com/SAP-samples/abap-platform-fiori-feature-showcase) - -
+ ## Exercise 5.1: Adjust the UI Semantics in the _Travel_ Metadata Extension 💡 [^Top of page](#) > Adjust the appearence of the generated Fiori elements based Travel App by adding the action **`acceptTravel`**, **`rejectTravel`**, and **`createTravel`**, and specifying a colored-based indication of the overall travel status `OverallStatus` for the _travel_ BO entity. - > 💡 There are two (2) ways to complete exercise 5.1: -> -> - **Option 1️⃣**: **This is the recommended option**. Replace the complete source code of the metadata extension ![ddlx icon](../images/adt_ddlx.png)**`ZRAP110_C_TRAVELTP_###`** with the source code provided in the source code document linked below and replace the placeholder **`###`** with your assigned suffix. The changes are marked with an appropriate comment in the source code document. -Then **proceed directly with Exercise 5.2**. -> -> 📄 **Source code document**: ![ddlx icon](../images/adt_ddlx.png) [CDS Metadata extension ZRAP110_C_TravelTP_###](sources/EX05_DDLX_ZRAP110_C_TravelTP.txt) -> -> - **Option 2️⃣**: Carry out the steps described below in sequence. +> +> - **Option 1️⃣**: **This is the recommended option**. Replace the complete source code of the metadata extension ![ddlx icon](../images/adt_ddlx.png)**`ZRAP110_C_TRAVELTP_###`** with the source code provided in the source code document linked below and replace the placeholder **`###`** with your assigned suffix. The changes are marked with an appropriate comment in the source code document. +> Then **proceed directly with Exercise 5.2**. +> +> 📄 **Source code document**: ![ddlx icon](../images/adt_ddlx.png) [CDS Metadata extension ZRAP110*C_TravelTP*###](sources/EX05_DDLX_ZRAP110_C_TravelTP.txt) +> +> - **Option 2️⃣**: Carry out the steps described below in sequence.
🔵 Click to expand! - - 1. Open the CDS metadata extension of the projected _travel_ entity ![ddlx icon](../images/adt_ddlx.png)**`ZRAP110_C_TRAVELTP_###`**. - - 2. Specify the appearance of both instance actions **`acceptTravel`** and **`rejectTravel`** on the list report and the object page of the _travel_ entity. - + +1. Open the CDS metadata extension of the projected _travel_ entity ![ddlx icon](../images/adt_ddlx.png)**`ZRAP110_C_TRAVELTP_###`**. + +2. Specify the appearance of both instance actions **`acceptTravel`** and **`rejectTravel`** on the list report and the object page of the _travel_ entity. + For that, replace the annotation block placed before the element **`TravelID`** with the code snippet provided below as shown on the screenshot. - + ```ABAP @UI.lineItem: [ { position: 10 , importance: #HIGH } - ,{ type: #FOR_ACTION, dataAction: 'acceptTravel', label: 'Accept Travel' } - ,{ type: #FOR_ACTION, dataAction: 'rejectTravel', label: 'Reject Travel' } + ,{ type: #FOR_ACTION, dataAction: 'acceptTravel', label: 'Accept Travel' } + ,{ type: #FOR_ACTION, dataAction: 'rejectTravel', label: 'Reject Travel' } ] @UI.identification: [ { position: 10 , importance: #HIGH } ,{ type: #FOR_ACTION, dataAction: 'acceptTravel', label: 'Accept Travel' } //added line - ,{ type: #FOR_ACTION, dataAction: 'rejectTravel', label: 'Reject Travel' } //added line + ,{ type: #FOR_ACTION, dataAction: 'rejectTravel', label: 'Reject Travel' } //added line ] @UI.selectionField: [ { position: 10 - } ] + } ] ``` - + Travel MDE - - 3. Specify a color-based indicator for the overall status **`OverallStatus`** on the list report and the object page of the _travel_ entity instance. The criticality will be determined by the virtual element **`OverallStatusIndicator`**. - + +3. Specify a color-based indicator for the overall status **`OverallStatus`** on the list report and the object page of the _travel_ entity instance. The criticality will be determined by the virtual element **`OverallStatusIndicator`**. + For that, add the attribute **`criticality`** to the annotations `@UI.lineItem` and `@UI.identification` for the element **`OverallStatus`** as shown on the screenshot. - + ```ABAP , criticality: 'OverallStatusIndicator' - ``` - + ``` + Travel MDE - - 3. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. + +4. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes.
## Exercise 5.2: Adjust the UI Semantics in the _Booking_ Metadata Extension 💡 -[^Top of page](#) -> Enhance the _booking_ metadata extension![metadataextension](../images/adt_ddlx.png)**`ZRAP110_C_BOOKINGTP_###`** to change the appearence of the generated Fiori elements based Travel App. You will define the criticality for the booking status (**`BookingStatus`**) and display the virtual element **`RemainingDaysToFlight`** as _progress bar_ on the UI. +[^Top of page](#) +> Enhance the _booking_ metadata extension![metadataextension](../images/adt_ddlx.png)**`ZRAP110_C_BOOKINGTP_###`** to change the appearence of the generated Fiori elements based Travel App. You will define the criticality for the booking status (**`BookingStatus`**) and display the virtual element **`RemainingDaysToFlight`** as _progress bar_ on the UI > 💡 There are two (2) ways to complete exercise 5.2: -> +> > - **Option 1️⃣**: **This is the recommended option**. Replace the complete source code of the metadata extension ![ddlx icon](../images/adt_ddlx.png)**`ZRAP110_C_BOOKINGTP_###`** with the source code provided in the source code document linked below and replace the placeholder **`###`** with your assigned suffix. The changes are marked with an appropriate comment in the source code document. Then **proceed directly with Exercise 5.3**. -> -> 📄 **Source code document**: ![ddlx icon](../images/adt_ddlx.png) [CDS Metadata extension ZRAP110_C_BookingTP_###](sources/EX05_DDLX_ZRAP110_C_BookingTP.txt) -> -> - **Option 2️⃣**: Carry out the steps described below in sequence. +> +> 📄 **Source code document**: ![ddlx icon](../images/adt_ddlx.png) [CDS Metadata extension ZRAP110*C_BookingTP*###](sources/EX05_DDLX_ZRAP110_C_BookingTP.txt) +> +> - **Option 2️⃣**: Carry out the steps described below in sequence.
🔵 Click to expand! - 1. Open the CDS metadata extension ![ddlx icon](../images/adt_ddlx.png)**`ZRAP110_C_BOOKINGTP_###`**. - - 2. Specify the virtual element **`BookingStatusIndicator`** as criticality for the booking status by adding the attribute **`criticality`** to the element annotations `@UI.lineItem` and `@UI.identification` for the element `BookingStatus` as shown on the screenshot. - +1. Open the CDS metadata extension ![ddlx icon](../images/adt_ddlx.png)**`ZRAP110_C_BOOKINGTP_###`**. + +2. Specify the virtual element **`BookingStatusIndicator`** as criticality for the booking status by adding the attribute **`criticality`** to the element annotations `@UI.lineItem` and `@UI.identification` for the element `BookingStatus` as shown on the screenshot. + ```ABAP ,criticality: 'BookingStatusIndicator' - ``` + ``` - Booking MDE - - 3. Add the virtual element **`RemainingDaysToFlight`** to the list report and the object page, and specify its visualization as _progress bar_ using the annotation **`@UI.dataPoint`**. The virtual elements **`DaysToFlightIndicator`** and **`InitialDaysToFlight`** are respectively specified as its `criticality` and `targetValue`. - - Insert the code snippet below to the metadata extension after the element **`BookingStatus`** as shown on the screenshot. - - ```ABAP - @UI: { - dataPoint: { title: 'Days to Flight Indicator', - criticality: 'DaysToFlightIndicator', - targetValue: #(InitialDaysToFlight), - visualization: #PROGRESS }, - lineItem: [{ type: #AS_DATAPOINT, position: 110, importance: #HIGH}], - identification: [{ type: #AS_DATAPOINT, position: 110 }] } - RemainingDaysToFlight; - ``` - - Booking MDE - - 4. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. + Booking MDE + +3. Add the virtual element **`RemainingDaysToFlight`** to the list report and the object page, and specify its visualization as _progress bar_ using the annotation **`@UI.dataPoint`**. The virtual elements **`DaysToFlightIndicator`** and **`InitialDaysToFlight`** are respectively specified as its `criticality` and `targetValue`. + + Insert the code snippet below to the metadata extension after the element **`BookingStatus`** as shown on the screenshot. + + ```ABAP + @UI: { + dataPoint: { title: 'Days to Flight Indicator', + criticality: 'DaysToFlightIndicator', + targetValue: #(InitialDaysToFlight), + visualization: #PROGRESS }, + lineItem: [{ type: #AS_DATAPOINT, position: 110, importance: #HIGH}], + identification: [{ type: #AS_DATAPOINT, position: 110 }] } + RemainingDaysToFlight; + ``` + + Booking MDE + +4. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes.
-## Exercise 5.3: Preview and Test the Enhanced _Travel_ App +## Exercise 5.3: Preview and Test the Enhanced _Travel_ App + [^Top of page](#) > You can now preview and test the changes by creating a new _travel_ BO instance in the _Travel_ app. - -> ⚠**Please note**⚠ that clicking on the **Accept Travel** and **Reject Travel** buttons at this stage will lead to errors on the UI, because they are not yet implemented. +> ⚠**Please note**⚠ that clicking on the **Accept Travel** and **Reject Travel** buttons at this stage will lead to errors on the UI, because they are not yet implemented.
🔵 Click to expand! -1. Refresh your application in the browser using **F5** if the browser is still open - +1. Refresh your application in the browser using **F5** if the browser is still open - or go to your service binding ![srvb icon](../images/adt_srvb.png)**`ZRAP110_UI_TRAVEL_O4_###`** and start the Fiori elements App preview for the **`Travel`** entity set. - - Booking MDE - + + Booking MDE +
-## Summary +## Summary + [^Top of page](#) -Now that you've ... +Now that you've ... + - adjusted the UI semantics in the metadata extensions by with criticality and datapoint, - previewed the enhanced app, you can continue with the next exercise – **[Exercise 6: Implement the Base BO Behavior - Validations](../ex06/README.md)** --- - diff --git a/exercises/ex06/README.md b/exercises/ex06/README.md index e8839ab..f82fe7e 100644 --- a/exercises/ex06/README.md +++ b/exercises/ex06/README.md @@ -2,30 +2,29 @@ # Exercise 6: Implement the Base BO Behavior - Validations -## Introduction +## Introduction In the previous exercise, you've enhanced the UI semantics of your _Travel_ app by enhancing the metadata extensions (see [Exercise 5](../ex05/README.md)). In the present exercise, you're going to implement back-end validations, `validateCustomer`, `validateAgency`, and `validateDates`, to respectively check if the customer ID and the agency name that is entered by the consumer are valid, and if the begin date is in the future and if the value of the end date is after the begin date. These validations are only performed in the back-end (not on the UI) and are triggered independently of the caller, i.e. Fiori UIs or EML APIs. > ℹ Similar validations were already handled in RAP100. Therefore, you will simply adopt the provided source code. We will use the validations for playing around with features such as **determine actions** and **side effects**. -> ### Exercises: + - [6.1 - Implement the Validations of the _Travel_ BO Entity](#exercise-61-implement-the-validations-of-the-travel-bo-entity-) 💡 -- [6.2 - Implement the Validations of the _Booking_ BO Entity](#exercise-62-implement-the-validations-of-the-booking-bo-entity) +- [6.2 - Implement the Validations of the _Booking_ BO Entity](#exercise-62-implement-the-validations-of-the-booking-bo-entity) - [6.3 - Preview and Test the enhanced Travel App](#exercise-63-preview-and-test-the-enhanced-travel-app) -- [Summary](#summary) +- [Summary](#summary) -> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned assigned suffix in the exercise steps below. +> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned assigned suffix in the exercise steps below. - ### About Validations
Click to expand! -A validation is an optional part of the business object behavior that checks the consistency of business object instances based on trigger conditions. +A validation is an optional part of the business object behavior that checks the consistency of business object instances based on trigger conditions. A validation is implicitly invoked by the business object’s framework if the trigger condition of the validation is fulfilled. Trigger conditions can be `MODIFY` operations and modified fields. The trigger condition is evaluated at the trigger time, a predefined point during the BO runtime. An invoked validation can reject inconsistent instance data from being saved by passing the keys of failed instances to the corresponding table in the `FAILED` structure. Additionally, a validation can return messages to the consumer by passing them to the corresponding table in the `REPORTED` structure. @@ -34,33 +33,34 @@ A validation is implicitly invoked by the business object’s framework if the t
## Exercise 6.1: Implement the Validations of the _Travel_ BO Entity 💡 + [^Top of page](#) > Enhance the behavior implementation class of the _travel_ entity with the business logic for the validation methods **`validateCustomer`**, **`validateAgency`**, and **`validateDates`**. > 💡 There are two (2) ways to complete exercise 6.1: -> -> - **Option 1️⃣**: **This is the recommended option**. Replace the whole content of your behavior implementation class of the _travel_ entity ![class](../images/adt_class.png)**ZRAP110_BP_TRAVELTP_###** with the provided source code document linked below and replace the placeholder **`###`** with your assigned suffix. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes, then **procedd directly with Exercise 6.2**. -> -> 📄 **Source code document:** ![class](../images/adt_class.png)[Behavior Implementation Class ZRAP110_BP_TRAVELTP_###](sources/EX06_CLASS_ZRAP110_BP_TRAVELTP.txt) > -> - **Option 2️⃣**: Carry out the steps described below (6.1) in sequence. +> - **Option 1️⃣**: **This is the recommended option**. Replace the whole content of your behavior implementation class of the _travel_ entity ![class](../images/adt_class.png)**ZRAP110*BP_TRAVELTP*###** with the provided source code document linked below and replace the placeholder **`###`** with your assigned suffix. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes, then **procedd directly with Exercise 6.2**. +> +> 📄 **Source code document:** ![class](../images/adt_class.png)[Behavior Implementation Class ZRAP110*BP_TRAVELTP*###](sources/EX06_CLASS_ZRAP110_BP_TRAVELTP.txt) +> +> - **Option 2️⃣**: Carry out the steps described below (6.1) in sequence.
🔵 Click to expand! ### Exercise 6.1.1: Implement the Validation `validateCustomer` of the _Travel_ BO Entity -> Implement the validation `validateCustomer` which checks if the customer ID (`CustomerID`) that is entered by the consumer is valid. +> Implement the validation `validateCustomer` which checks if the customer ID (`CustomerID`) that is entered by the consumer is valid. > An appropriate message should be raised and displayed on the UI for each invalid value.
🟣 Click to expand! - 1. In your implementation class of the _travel_ entity ![class](../images/adt_class.png) **`ZRAP110_BP_TRAVELTP_###`**, replace the current method implementation of **`validateCustomer`** with following code snippet. - +1. In your implementation class of the _travel_ entity ![class](../images/adt_class.png) **`ZRAP110_BP_TRAVELTP_###`**, replace the current method implementation of **`validateCustomer`** with following code snippet. + Replace all occurrences of the placeholder **`###`** with your assigned suffix. - + ```ABAP METHOD validateCustomer. "read relevant travel instance data @@ -113,29 +113,30 @@ A validation is implicitly invoked by the business object’s framework if the t %element-CustomerID = if_abap_behv=>mk-on ) TO reported-travel. ENDIF. - ENDLOOP. - ENDMETHOD. + ENDLOOP. + ENDMETHOD. ``` - - 2. Save ![save icon](../images/adt_save.png) the changes. + +2. Save ![save icon](../images/adt_save.png) the changes.
- + ### Exercise 6.1.2: Implement the Validation `validateAgency` of the _Travel_ BO Entity + [^Top of page](#) -> Implement the validation `validateAgency` which checks if the agency ID (element `AgencyID`) that is entered by the consumer is valid. +> Implement the validation `validateAgency` which checks if the agency ID (element `AgencyID`) that is entered by the consumer is valid. > An appropriate message should be raised and displayed on the UI for each invalid value.
🟣 Click to expand! - 1. In your implementation class of the _travel_ entity ![class](../images/adt_class.png) **`ZRAP110_BP_TRAVELTP_###`**, replace the current method implementation of **`validateAgency`** with following code snippet. - +1. In your implementation class of the _travel_ entity ![class](../images/adt_class.png) **`ZRAP110_BP_TRAVELTP_###`**, replace the current method implementation of **`validateAgency`** with following code snippet. + Replace all occurrences of the placeholder **`###`** with your assigned suffix. - + ```ABAP - METHOD validateAgency. + METHOD validateAgency. " Read relevant travel instance data READ ENTITIES OF ZRAP110_R_TravelTP_### IN LOCAL MODE ENTITY travel @@ -174,164 +175,167 @@ A validation is implicitly invoked by the business object’s framework if the t %element-AgencyID = if_abap_behv=>mk-on ) TO reported-travel. ENDIF. - ENDLOOP. - ENDMETHOD. + ENDLOOP. + ENDMETHOD. ``` - 2. Save ![save icon](../images/adt_save.png) the changes. +2. Save ![save icon](../images/adt_save.png) the changes. -
+
### Exercise 6.1.3: Implement the Validation `validateDates` of the _Travel_ BO Entity + [^Top of page](#) -> Implement the validation `validateDates` which checks if the begin date and the end date (elements `BeginDate` and `EndDate`) that are entered by the consumer is valid. +> Implement the validation `validateDates` which checks if the begin date and the end date (elements `BeginDate` and `EndDate`) that are entered by the consumer is valid. > An appropriate message should be raised and displayed on the UI for each invalid value.
🟣 Click to expand! - 1. In your implementation class of the _travel_ entity ![class](../images/adt_class.png) **`ZRAP110_BP_TRAVELTP_###`**, replace the current method implementation of **`validateDates`** with following code snippet. - - Replace all occurrences of the placeholder **`###`** with your assigned suffix. - - ```ABAP - METHOD validateDates. - READ ENTITIES OF ZRAP110_R_TravelTP_### IN LOCAL MODE - ENTITY travel - FIELDS ( BeginDate EndDate ) - WITH CORRESPONDING #( keys ) - RESULT DATA(travels). - - LOOP AT travels INTO DATA(travel). - APPEND VALUE #( %tky = travel-%tky - %state_area = 'VALIDATE_DATES' ) TO reported-travel. - - IF travel-EndDate < travel-BeginDate. "end_date before begin_date - APPEND VALUE #( %tky = travel-%tky ) TO failed-travel. - APPEND VALUE #( %tky = travel-%tky - %state_area = 'VALIDATE_DATES' - %msg = NEW /dmo/cm_flight_messages( - textid = /dmo/cm_flight_messages=>begin_date_bef_end_date - severity = if_abap_behv_message=>severity-error - begin_date = travel-BeginDate - end_date = travel-EndDate - travel_id = travel-TravelID ) - %element-BeginDate = if_abap_behv=>mk-on - %element-EndDate = if_abap_behv=>mk-on - ) TO reported-travel. +1. In your implementation class of the _travel_ entity ![class](../images/adt_class.png) **`ZRAP110_BP_TRAVELTP_###`**, replace the current method implementation of **`validateDates`** with following code snippet. - ELSEIF travel-BeginDate < cl_abap_context_info=>get_system_date( ). "begin_date must be in the future - APPEND VALUE #( %tky = travel-%tky ) TO failed-travel. - APPEND VALUE #( %tky = travel-%tky - %state_area = 'VALIDATE_DATES' - %msg = NEW /dmo/cm_flight_messages( - textid = /dmo/cm_flight_messages=>begin_date_on_or_bef_sysdate - severity = if_abap_behv_message=>severity-error ) - %element-BeginDate = if_abap_behv=>mk-on - %element-EndDate = if_abap_behv=>mk-on - ) TO reported-travel. - ENDIF. - ENDLOOP. - ENDMETHOD. - ``` + Replace all occurrences of the placeholder **`###`** with your assigned suffix. - 2. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. + ```ABAP + METHOD validateDates. + READ ENTITIES OF ZRAP110_R_TravelTP_### IN LOCAL MODE + ENTITY travel + FIELDS ( BeginDate EndDate ) + WITH CORRESPONDING #( keys ) + RESULT DATA(travels). + + LOOP AT travels INTO DATA(travel). + APPEND VALUE #( %tky = travel-%tky + %state_area = 'VALIDATE_DATES' ) TO reported-travel. -
+ IF travel-EndDate < travel-BeginDate. "end_date before begin_date + APPEND VALUE #( %tky = travel-%tky ) TO failed-travel. + APPEND VALUE #( %tky = travel-%tky + %state_area = 'VALIDATE_DATES' + %msg = NEW /dmo/cm_flight_messages( + textid = /dmo/cm_flight_messages=>begin_date_bef_end_date + severity = if_abap_behv_message=>severity-error + begin_date = travel-BeginDate + end_date = travel-EndDate + travel_id = travel-TravelID ) + %element-BeginDate = if_abap_behv=>mk-on + %element-EndDate = if_abap_behv=>mk-on + ) TO reported-travel. + + ELSEIF travel-BeginDate < cl_abap_context_info=>get_system_date( ). "begin_date must be in the future + APPEND VALUE #( %tky = travel-%tky ) TO failed-travel. + APPEND VALUE #( %tky = travel-%tky + %state_area = 'VALIDATE_DATES' + %msg = NEW /dmo/cm_flight_messages( + textid = /dmo/cm_flight_messages=>begin_date_on_or_bef_sysdate + severity = if_abap_behv_message=>severity-error ) + %element-BeginDate = if_abap_behv=>mk-on + %element-EndDate = if_abap_behv=>mk-on + ) TO reported-travel. + ENDIF. + ENDLOOP. + ENDMETHOD. + ``` + +2. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. + + - ## Exercise 6.2: Implement the Validations of the _Booking_ BO Entity + [^Top of page](#) - > Enhance the behavior implementation class of the _booking_ entity with the business logic for the validation method **``validateBookingStatus``**. - +> Enhance the behavior implementation class of the _booking_ entity with the business logic for the validation method **`validateBookingStatus`**. +
- 🔵 Click to expand! - + 🔵 Click to expand! + ### Exercise 6.2.1: Implement the Validation `validateBookingStatus` of the _Booking_ BO Entity -> Implement the validation `validateBookingStatus` which checks if the booking status (element `BookingStatus`) that is selected by the consumer is valid. -> +> Implement the validation `validateBookingStatus` which checks if the booking status (element `BookingStatus`) that is selected by the consumer is valid. +> > An appropriate message should be raised and displayed on the UI for each invalid value.
🟣 Click to expand! - 1. In your implementation class of the _booking_ entity ![class](../images/adt_class.png) **`ZRAP110_BP_BOOKINGTP_###`**, insert the code snippet provided below into the method implementation of **`validateBookingStatus`** as shown on the scrrenshot. - - Replace all occurrences of the placeholder **`###`** with your assigned suffix. - - ```ABAP - METHOD validateBookingStatus. - READ ENTITIES OF ZRAP110_R_TravelTP_### IN LOCAL MODE - ENTITY booking - FIELDS ( BookingStatus ) - WITH CORRESPONDING #( keys ) - RESULT DATA(bookings). - - LOOP AT bookings INTO DATA(booking). - CASE booking-BookingStatus. - WHEN booking_status-new. " New - WHEN booking_status-canceled. " Canceled - WHEN booking_status-booked. " Booked - WHEN OTHERS. - APPEND VALUE #( %tky = booking-%tky ) TO failed-booking. - APPEND VALUE #( %tky = booking-%tky - %msg = NEW /dmo/cm_flight_messages( - textid = /dmo/cm_flight_messages=>status_invalid - status = booking-BookingStatus - severity = if_abap_behv_message=>severity-error ) - %element-BookingStatus = if_abap_behv=>mk-on - %path = VALUE #( travel-TravelId = booking-TravelId ) - ) TO reported-booking. - ENDCASE. - ENDLOOP. - ENDMETHOD. - ``` - - > Note: the local constant `booking_status` was defined in the local handler class `lhc_booking` in - > _[Exercise 3.8.2: Adjust the Behavior Implementation Class of the Booking BO entity](../ex03/README.md#exercise-38-adjust-the-behavior-implementation-classes)_. - - 2. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. +1. In your implementation class of the _booking_ entity ![class](../images/adt_class.png) **`ZRAP110_BP_BOOKINGTP_###`**, insert the code snippet provided below into the method implementation of **`validateBookingStatus`** as shown on the scrrenshot. + + Replace all occurrences of the placeholder **`###`** with your assigned suffix. + + ```ABAP + METHOD validateBookingStatus. + READ ENTITIES OF ZRAP110_R_TravelTP_### IN LOCAL MODE + ENTITY booking + FIELDS ( BookingStatus ) + WITH CORRESPONDING #( keys ) + RESULT DATA(bookings). + + LOOP AT bookings INTO DATA(booking). + CASE booking-BookingStatus. + WHEN booking_status-new. " New + WHEN booking_status-canceled. " Canceled + WHEN booking_status-booked. " Booked + WHEN OTHERS. + APPEND VALUE #( %tky = booking-%tky ) TO failed-booking. + APPEND VALUE #( %tky = booking-%tky + %msg = NEW /dmo/cm_flight_messages( + textid = /dmo/cm_flight_messages=>status_invalid + status = booking-BookingStatus + severity = if_abap_behv_message=>severity-error ) + %element-BookingStatus = if_abap_behv=>mk-on + %path = VALUE #( travel-TravelId = booking-TravelId ) + ) TO reported-booking. + ENDCASE. + ENDLOOP. + ENDMETHOD. + ``` + + > Note: the local constant `booking_status` was defined in the local handler class `lhc_booking` in + > _[Exercise 3.8.2: Adjust the Behavior Implementation Class of the Booking BO entity](../ex03/README.md#exercise-38-adjust-the-behavior-implementation-classes)_. + +2. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes.
-
+ - ## Exercise 6.3: Preview and Test the enhanced Travel App + [^Top of page](#) -> Now the SAP Fiori elements app can be tested. +> Now the SAP Fiori elements app can be tested. -> ⚠**Please note**⚠ that clicking on the **Accept Travel** and **Reject Travel** buttons at this stage will lead to errors on the UI, because they are not yet implemented. +> ⚠**Please note**⚠ that clicking on the **Accept Travel** and **Reject Travel** buttons at this stage will lead to errors on the UI, because they are not yet implemented.
🔵 Click to expand! - 1. You can either refresh your application in the browser using **F5** if the browser is still open - or go to your service binding **`ZRAP110_UI_TRAVEL_O4_###`** and start the Fiori elements App preview for the **`Travel`** entity set. +1. You can either refresh your application in the browser using **F5** if the browser is still open - or go to your service binding **`ZRAP110_UI_TRAVEL_O4_###`** and start the Fiori elements App preview for the **`Travel`** entity set. - 2. Click **Create** to create a new entry. +2. Click **Create** to create a new entry. - 3. For example, select an `Sunshine Travel (70001)` as Agency ID, select a customer by starting to add a name `Theresia`, Nov 20, 2023 as starting date and Nov 16, 2023 as end date. The draft will be updated. +3. For example, select an `Sunshine Travel (70001)` as Agency ID, select a customer by starting to add a name `Theresia`, Nov 20, 2023 as starting date and Nov 16, 2023 as end date. The draft will be updated. - Preview - -3. Now click **Create**. You should get following error messages displayed: - *Begin Date 11/20/2023 must not be after End Date 11/16/2023* . + Preview + +4. Now click **Create**. You should get following error messages displayed: + _Begin Date 11/20/2023 must not be after End Date 11/16/2023_ . + + Preview - Preview -
-## Summary +## Summary + [^Top of page](#) -Now that you've... -- Added the logic for various validations in the behavior definition, +Now that you've... + +- Added the logic for various validations in the behavior definition, - previewed and tested the enhanced Fiori elements app, you can continue with the next exercise – **[Exercise 7: Implement the Base BO Behavior - Actions](../ex07/README.md)** diff --git a/exercises/ex07/README.md b/exercises/ex07/README.md index 0a16b78..d89d757 100644 --- a/exercises/ex07/README.md +++ b/exercises/ex07/README.md @@ -1,18 +1,19 @@ [Home - RAP110](../../README.md) -# Exercises 7: Enhance the BO Behavior – Actions +# Exercises 7: Enhance the BO Behavior – Actions ## Introduction In the previous exercise, you've defined and implemented validations (see [Exercise 6](../ex06/README.md)). In this exercise, you will implement the different actions defined for the _Travel_ Bo entity in [Exercise 3](../ex03/README.md): -- The instance actions **`acceptTravel`** and **`rejectTravel`** to accept or reject _travel_ instances with one click. -- The internal instance action **`reCalcTotalPrice`** to recalculate the total price of a _travel_ instance when needed. -- The static default factory instance action **`createTravel`** with parameter that will be used to replace the standard `create` operation. +- The instance actions **`acceptTravel`** and **`rejectTravel`** to accept or reject _travel_ instances with one click. +- The internal instance action **`reCalcTotalPrice`** to recalculate the total price of a _travel_ instance when needed. +- The static default factory instance action **`createTravel`** with parameter that will be used to replace the standard `create` operation. ### Exercises: + - [7.0: How to handle this exercise](#exercise-70-how-to-handle-this-exercise) - [7.1: Implement the Instance Actions `acceptTravel` and `rejectTravel`](#exercise-71-implement-the-instance-actions-accepttravel-and-rejecttravel) - [7.2: Implement the Internal Instance Action `reCalcTotalPrice`](#exercise-72-implement-the-internal-instance-action-recalctotalprice) @@ -20,76 +21,77 @@ In this exercise, you will implement the different actions defined for the _Trav - [7.4: Preview and Test the Enhanced _Travel_ App](#exercise-74-preview-and-test-the-enhanced-travel-app) - [Summary](#summary) ----- +--- -> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned assigned suffix in the exercise steps below. +> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned assigned suffix in the exercise steps below. ### About 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. +> 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 action that are not bound to any instance but relates to the complete entity. -> -> 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. +> +> 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](https://help.sap.com/viewer/923180ddb98240829d935862025004d6/Cloud/en-US/83bad707a5a241a2ae93953d81d17a6b.html) **|** [CDS BDL - non-standard operations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_nonstandard.htm) **|** [ABAP EML - response_param](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapeml_response.htm) -> ℹ **Further reading**: [RAP BO Contract](https://help.sap.com/docs/BTP/923180ddb98240829d935862025004d6/3a402c5cf6a74bc1a1de080b2a7c6978.html) **|** [RAP BO Provider API (derived types, %cid, implicit response parameters,...)](https://help.sap.com/docs/BTP/923180ddb98240829d935862025004d6/2a3da8a5b19e4f6b953e9a11fb5cc747.html?version=Cloud) +> ℹ **Further reading**: [Actions](https://help.sap.com/viewer/923180ddb98240829d935862025004d6/Cloud/en-US/83bad707a5a241a2ae93953d81d17a6b.html) **|** [CDS BDL - non-standard operations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_nonstandard.htm) **|** [ABAP EML - response_param](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapeml_response.htm) +> ℹ **Further reading**: [RAP BO Contract](https://help.sap.com/docs/BTP/923180ddb98240829d935862025004d6/3a402c5cf6a74bc1a1de080b2a7c6978.html) **|** [RAP BO Provider API (derived types, %cid, implicit response parameters,...)](https://help.sap.com/docs/BTP/923180ddb98240829d935862025004d6/2a3da8a5b19e4f6b953e9a11fb5cc747.html?version=Cloud)
- ## Exercise 7.0: How to handle this exercise [^Top of page](#) > Enhance the behavior implementation class of the _travel_ entity with the business logic for the action methods **`acceptTravel`**, **`rejectTravel`**, **`reCalcTotalPrice`**, and **`createTravel`**. - > 💡 There are two (2) ways to complete exercise 6.1: -> +> > - **Option 1️⃣**: **This is the recommended option**. Carry out this step (Exercise 7.0) and then **proceed directly with Exercise 7.4**. > -> - **Option 2️⃣**: Skip this step (7.0) and proceed with the steps 7.1-7.4 in sequence. +> - **Option 2️⃣**: Skip this step (7.0) and proceed with the steps 7.1-7.4 in sequence.
🔵 Click to expand! - - 1. Go to the behavior implementation class of the _travel_ entity ![class](../images/adt_class.png)**ZRAP110_BP_TRAVELTP_###** and adjust it. - + +1. Go to the behavior implementation class of the _travel_ entity ![class](../images/adt_class.png)**ZRAP110*BP_TRAVELTP*###** and adjust it. + For that, replace the whole source code on the **Local Types** tab with the source code provided in the source code document linked below and replace the placeholder **`###`** with your assigned suffix. - - ▶📄 **Source code document:** ![class](../images/adt_class.png)[Behavior Implementation Class ZRAP110_BP_TRAVELTP_###](sources/EX07_CLASS_ZRAP110_BP_TRAVELTP.txt) - - 2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - - 3. Now, specify the static factory action **`createTravel`** as **default** in the behavior definition of the _travel_ entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`**. - - For that, add the keyword **`default`** after the keyword **`static`** as shown on the screenshot below. - - Travel BDEF - - 4. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - + + ▶📄 **Source code document:** ![class](../images/adt_class.png)[Behavior Implementation Class ZRAP110*BP_TRAVELTP*###](sources/EX07_CLASS_ZRAP110_BP_TRAVELTP.txt) + +2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + +3. Now, specify the static factory action **`createTravel`** as **default** in the behavior definition of the _travel_ entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`**. + + For that, add the keyword **`default`** after the keyword **`static`** as shown on the screenshot below. + + Travel BDEF + +4. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + Now, the static default factory action **`createTravel`** will be automatically called by the SAP Fiori elements UI instead of the standard **`create`** operation. - - 5. You can now **proceed directly with Exercise 7.4**. + +5. You can now **proceed directly with Exercise 7.4**.
## Exercise 7.1: Implement the Instance Actions `acceptTravel` and `rejectTravel` + [^Top of page](#) > You will now implement the logic of the instance actions **`acceptTravel`** and **`rejectTravel`** in the local handler class `Lhc_travel` of the behavior pool of the _travel_ BO entity. These actions are used to set the overall status of a given _travel_ instance respectively to _accepted_ or _rejected_ in one click. Both actions have been defined in [Exercise 3.4](../ex03/README.md): -> > ` action acceptTravel result [1] $self; ` -> > ` action rejectTravel result [1] $self; ` -> -> The definition, implementation and exposuse of instance actions is covered and explained in [RAP100](https://github.com/SAP-samples/abap-platform-rap100#exercises). Therefore, simply copy the business logic provided as code snippet below in your _travel_ behavior pool ![ABAP class](../images/adt_class.png)`ZRAP110_BP_TRAVELTP_###` to enhance the functionality of your _Travel_ app. -> +> +> > ` action acceptTravel result [1] $self;` +> > ` action rejectTravel result [1] $self;` +> +> The definition, implementation and exposure of instance actions is covered and explained in [RAP100](https://github.com/SAP-samples/abap-platform-rap100#exercises). Therefore, simply copy the business logic provided as code snippet below in your _travel_ behavior pool ![ABAP class](../images/adt_class.png)`ZRAP110_BP_TRAVELTP_###` to enhance the functionality of your _Travel_ app. +> > These instance actions will be needed in [Exercise 11: Enhance the BO Behavior with Business Events](../ex11/README.md).
@@ -98,14 +100,14 @@ In this exercise, you will implement the different actions defined for the _Trav ### Exercise 7.1.1: Implement the InstanceActions `acceptTravel` > Implement the action behavior in the local handler method `acceptTravel` of the behavior pool of the _travel_ entity. - +
🟣 Click to expand! - 1. Go to the method **`acceptTravel`** of the local handler class `lhc_travel` in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provide below. - + 1. Go to the method **`acceptTravel`** of the local handler class `lhc_travel` in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provide below. + Replace all occurences of the placeholder `###` with your assigned suffix. - + ```ABAP ************************************************************************** * Instance-bound action acceptTravel @@ -127,10 +129,10 @@ In this exercise, you will implement the different actions defined for the _Trav result = VALUE #( FOR travel IN travels ( %tky = travel-%tky %param = travel ) ). ENDMETHOD. ``` - - 2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - -
+ +2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + +
### Exercise 7.1.2: Implement the Instance Actions `rejectTravel` @@ -139,10 +141,10 @@ In this exercise, you will implement the different actions defined for the _Trav
🟣 Click to expand! - 1. Go to the method **`rejectTravel`** of the local handler class `lhc_travel` in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provide below. - + 1. Go to the method **`rejectTravel`** of the local handler class `lhc_travel` in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provide below. + Replace all occurences of the placeholder `###` with your assigned suffix. - + ```ABAP ************************************************************************** * Instance-bound action rejectTravel @@ -164,33 +166,35 @@ In this exercise, you will implement the different actions defined for the _Trav result = VALUE #( FOR travel IN travels ( %tky = travel-%tky %param = travel ) ). ENDMETHOD. ``` - - 2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + +2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes.
## Exercise 7.2: Implement the Internal Instance Action `reCalcTotalPrice` + [^Top of page](#) -> You will now implement the logic of the internal instance action **`reCalcTotalPrice`** in the local handler class `lhc_travel` of the behavior pool of the _travel_ BO entity. This action is used to calculate the total price of a given _travel_ instance. The total price is the sum of the booking fee (`BookingFee`) of a _travel_ entity instance and the flight price (`FlightPrice`) of each associated _booking_ entity instances. The currency (`CurrencyCode`) is considered in this calculation. +> You will now implement the logic of the internal instance action **`reCalcTotalPrice`** in the local handler class `lhc_travel` of the behavior pool of the _travel_ BO entity. This action is used to calculate the total price of a given _travel_ instance. The total price is the sum of the booking fee (`BookingFee`) of a _travel_ entity instance and the flight price (`FlightPrice`) of each associated _booking_ entity instances. The currency (`CurrencyCode`) is considered in this calculation. > This action has been defined in [Exercise 3.4](../ex03/README.md): -> > ` internal action recalcTotalPrice; ` -> +> +> > ` internal action recalcTotalPrice;` +> > The implementation of **internal instance actions** is similar to the one of classic instance actions such as `acceptTravel` and `rejectTravel`. The only difference is that internal actions are private and can only be used within the given BO. -> +> > The internal instance action `reCalcTotalPrice` will be needed in [Exercise 8](../ex11/README.md) to enable the recalculation of `TotalPrice` at specific trigger point.
🔵 Click to expand! - 1. Go to the method **`reCalcTotalPrice`** of the local handler class `lhc_travel` in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provide below. - + 1. Go to the method **`reCalcTotalPrice`** of the local handler class `lhc_travel` in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provide below. + > ⚠ Please note: Only few currency codes conversion factors are currently maintained in the present system D23. - + Replace all occurences of the placeholder `###` with your assigned suffix. - + ```ABAP ************************************************************************** * Internal instance-bound action calculateTotalPrice @@ -259,42 +263,44 @@ In this exercise, you will implement the different actions defined for the _Trav ENTITY travel UPDATE FIELDS ( TotalPrice ) WITH CORRESPONDING #( travels ). - + ENDMETHOD. ``` - - 2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - + +2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. +
- ## Exercise 7.3: Implement the Static Factory Action with Parameter `createTravel` + [^Top of page](#) > You will now implement the logic of the static factory action (with parameter) **`createTravel`** in the local handler class `lhc_travel` of the behavior pool of the _travel_ BO entity ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`**. The action has been defined in [Exercise 3.4](../ex03/README.md): -> > ` static factory action createTravel parameter ZRAP110_A_Create_Travel_### [1]; ` -> -> Then you will specify the action as **`default static factory action`** in the behavior definition![bdef](../images/adt_bdef.png) of the _travel_ entity . - -> ℹ **Info about Factory Action:** -> - With **factory actions**, you can create entity instances by executing an action. -> - **Static actions** are not bound to any instance but relate to the complete entity. So, instance factory actions can be useful if you want to copy specific values of an instance, whereas static factory actions can be used to create instances with prefilled default values. A factory action always has the result cardinality [1]. +> +> > ` static factory action createTravel parameter ZRAP110_A_Create_Travel_### [1];` +> +> Then you will specify the action as **`default static factory action`** in the behavior definition![bdef](../images/adt_bdef.png) of the _travel_ entity . + +> ℹ **Info about Factory Action:** +> +> - With **factory actions**, you can create entity instances by executing an action. +> - **Static actions** are not bound to any instance but relate to the complete entity. So, instance factory actions can be useful if you want to copy specific values of an instance, whereas static factory actions can be used to create instances with prefilled default values. A factory action always has the result cardinality [1]. > - The **default** option specifies a static factory action as the new `create` operation that will be called by the SAP Fiori elements UI instead of the standard **`create`** operation. -> -> The implementation of an **instance-bound factory action** is covered and explained in [RAP100](https://github.com/SAP-samples/abap-platform-rap100#exercises). +> +> The implementation of an **instance-bound factory action** is covered and explained in [RAP100](https://github.com/SAP-samples/abap-platform-rap100#exercises).
🔵 Click to expand! 1. You can have a look at the CDS abstract entity ![ddls](../images/adt_ddls.png)`ZRAP110_A_Create_Travel_###`. It will be used to define the structure of the input parameter. - +
Have a look at the source code of the abstract entity - - CDS abstract entity - + + CDS abstract entity + Below is the formatted source code: - + ```ABAP @EndUserText.label: 'Parameter for Creating Travel+Booking' define abstract entity ZRAP110_A_Create_Travel_### @@ -317,11 +323,11 @@ In this exercise, you will implement the different actions defined for the _Trav } ```
- - 2. Now, go to the method **`createTravel`** of the local handler class `lhc_travel` in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provide below. - + +2. Now, go to the method **`createTravel`** of the local handler class `lhc_travel` in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provide below. + Replace all occurences of the placeholder `###` with your assigned suffix. - + ```ABAP ************************************************************************** * static default factory action createTravel @@ -365,57 +371,59 @@ In this exercise, you will implement the different actions defined for the _Trav ENDIF. ENDMETHOD. - ``` - - 3. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - - 4. Now, specify the static factory action **`createTravel`** as **default** in the behavior definition of the _travel_ entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`**. - - Add the keyword **`default`** after the keyword **`static`** as shown on the screenshot below. - - Travel BDEF - - 5. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - + ``` + +3. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + +4. Now, specify the static factory action **`createTravel`** as **default** in the behavior definition of the _travel_ entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`**. + + Add the keyword **`default`** after the keyword **`static`** as shown on the screenshot below. + + Travel BDEF + +5. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + Now, the static default factory action **`createTravel`** will be automatically called by the SAP Fiori elements UI instead of the standard **`create`** operation. - +
## Exercise 7.4: Preview and Test the Enhanced _Travel_ App + [^Top of page](#) -You can test the enhanced SAP Fiori elements app can be tested. +You can test the enhanced SAP Fiori elements app can be tested.
🔵 Click to expand! - 1. You can either refresh your application in the browser using **F5** if the browser is still open - or go to your service binding **`ZRAP110_UI_TRAVEL_O4_###`** and start the Fiori elements App preview for the **`Travel`** entity set. +1. You can either refresh your application in the browser using **F5** if the browser is still open - or go to your service binding **`ZRAP110_UI_TRAVEL_O4_###`** and start the Fiori elements App preview for the **`Travel`** entity set. + +2. Play around. For example,... - 2. Play around. For example,... - Press the buttons _**Accept Travel**_ and _**Reject Travel**_ to change the overall status of _travel_ instances. - - - Press the button _**Create**_. The logic of the **`createTravel`** should be called now - + + - Press the button _**Create**_. The logic of the **`createTravel`** should be called now + - Create or Edit an existing entry to check the calculation of the total price. > ⚠ Please not that the execution of the internal action **`reCalcTotalPrice`** is not yet triggered. Therefore, the total price of a _travel_ instance will not be calculated for now. You will tackle this in the next exercise by implementing the determination **`calculateTotalPrice`**. - - After clicking **Create** you will get following pop-up. Here you can select all enties at once. This is pop-up appears due to the key word default. - - Preview - -
- + After clicking **Create** you will get following pop-up. Here you can select all entries at once. This is pop-up appears due to the key word default. + + Preview + + + ## Summary + [^Top of page](#) -Now that you've implemented and tested... -- instance actions, +Now that you've implemented and tested... + +- instance actions, - internal instance actions, and -- static default factory instance actions, - +- static default factory instance actions, + you can continue with the next exercise – **[Exercise 8: Implement the Base BO Behavior - Determinations](../ex08/README.md)** --- - diff --git a/exercises/ex08/README.md b/exercises/ex08/README.md index 2834b72..d8fc44e 100644 --- a/exercises/ex08/README.md +++ b/exercises/ex08/README.md @@ -3,36 +3,40 @@ # Exercise 8: Implement the Base BO Behavior - Determinations ## Introduction + In the previous exercise, you've defined and implemented various actions (see [Exercise 7](../ex07/README.md)). -In this exercise, you will implement the determinations defined for the _travel_ BO entity and the _booking_ BO entity in [Exercise 3](../ex03/README.md): +In this exercise, you will implement the determinations defined for the _travel_ BO entity and the _booking_ BO entity in [Exercise 3](../ex03/README.md): + - **`setInitialTravelValues`** and **`setInitialBookingValues`** to set the default values of _travel_ and _booking_ entities respectively. - **`calculateTotalPrice`** to trigger the recalculation of the total price of a _travel_ instance when needed. ### Exercises: + - [8.1: Implement the Determinations of the _Travel_ BO entity](#exercise-81-implement-the-determinations-of-the-travel-bo-entity) - [8.2: Implement the Determinations of the _Booking_ BO entity](#exercise-82-implement-the-determinations-of-the-booking-bo-entity) - [8.3: Preview and Test the Enhanced _Travel_ App](#exercise-83-preview-and-test-the-enhanced-travel-app) - [Summary](#summary) -> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned assigned suffix in the exercise steps below. +> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned assigned suffix in the exercise steps below. ### About determinations
- Click to expand! + Click to expand! #### About determinations > 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. - > + > > **Further reading**: [Determinations](https://help.sap.com/viewer/923180ddb98240829d935862025004d6/Cloud/en-US/6edb0438d3e14d18b3c403c406fbe209.html).
- + ## Exercise 8.1: Implement the Determinations of the _Travel_ BO entity + [^Top of page](#) -> Implement the determinations **`setInitialTravelValues`** and **`calculateTotalPrice`** for the _travel_ BO entity defined in [Exercise 3.5](../ex03/README.md). +> Implement the determinations **`setInitialTravelValues`** and **`calculateTotalPrice`** for the _travel_ BO entity defined in [Exercise 3.5](../ex03/README.md).
🔵 Click to expand! @@ -40,14 +44,14 @@ In this exercise, you will implement the determinations defined for the _travel_ ### Exercise 8.1.1: Implement the Determination `setInitialTravelValues` of the _Travel_ BO entity > Implement the determination behavior in the local handler method `setInitialTravelValues` of the behavior pool of the _travel_ entity. - +
🟣 Click to expand! - 1. Go to the method **`setInitialTravelValues`** of the local handler class **`lhc_travel`** in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provide below. - + 1. Go to the method **`setInitialTravelValues`** of the local handler class **`lhc_travel`** in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provided below. + Replace all occurences of the placeholder `###` with your assigned suffix. - + ```ABAP ************************************************************************** * determination setInitialTravelValues: BeginDate, EndDate @@ -92,22 +96,22 @@ In this exercise, you will implement the determinations defined for the _travel_ ENDMETHOD. ``` - - 2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - -
+ +2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + +
### Exercise 8.1.2: Implement the Determination `calculateTotalPrice` of the _Travel_ BO entity > Implement the determination behavior in the local handler method **`calculateTotalPrice`** of the behavior pool of the _travel_ entity. It is used to enable the call of the internal action `reCalcTotalPrice` of the _Travel_ BO entity at specific trigger points. - +
🟣 Click to expand! - 1. Go to the method **`calculateTotalPrice`** of the local handler class **`lhc_travel`** in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provide below. - + 1. Go to the method **`calculateTotalPrice`** of the local handler class **`lhc_travel`** in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** and replace the empty method implementation with the code provided below. + Replace all occurences of the placeholder `###` with your assigned suffix. - + ```ABAP ************************************************************************** * determination calculateTotalPrice @@ -118,20 +122,20 @@ In this exercise, you will implement the determinations defined for the _travel_ EXECUTE reCalcTotalPrice FROM CORRESPONDING #( keys ). - ENDMETHOD. + ENDMETHOD. ``` - - 2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - -
+ +2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + + ## Exercise 8.2: Implement the Determinations of the _Booking_ BO entity + [^Top of page](#introduction) -> Implement the determinations **`setInitialBookingValues`** and **`calculateTotalPrice`** for the _booking_ BO entity defined in [Exercise 3.5](../ex03/README.md). -> +> Implement the determinations **`setInitialBookingValues`** and **`calculateTotalPrice`** for the _booking_ BO entity defined in [Exercise 3.5](../ex03/README.md).
🔵 Click to expand! @@ -139,14 +143,14 @@ In this exercise, you will implement the determinations defined for the _travel_ ### Exercise 8.1.2: Implement the Determination `setInitialBookingValues` of the _Booking_ BO entity > Implement the determination behavior in the local handler method `setInitialBookingValues` of the behavior pool of the _booking_ entity. - +
🟣 Click to expand! - 1. Go to the method **`setInitialBookingValues`** of the local handler class **`lhc_booking`** in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_BOOKINGTP_###`** and replace the empty method implementation with the code provide below. - + 1. Go to the method **`setInitialBookingValues`** of the local handler class **`lhc_booking`** in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_BOOKINGTP_###`** and replace the empty method implementation with the code provided below. + Replace all occurences of the placeholder `###` with your assigned suffix. - + ```ABAP ************************************************************************** * Determination setInitialBookingValues: @@ -196,26 +200,24 @@ In this exercise, you will implement the determinations defined for the _travel_ UPDATE FROM update. ENDIF. - ENDMETHOD. + ENDMETHOD. ``` - - 2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - -
- - - + +2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + +
+ ### Exercise 8.2.2: Implement the Determination `calculateTotalPrice` of the _Booking_ BO entity -> Implement the determination behavior in the local handler method `calculateTotalPrice` of the behavior pool of the _booking_ entity. It is used to enable the call of the internal action `reCalcTotalPrice` of the _Travel_ parent BO entity at specific trigger points. - +> Implement the determination behavior in the local handler method `calculateTotalPrice` of the behavior pool of the _booking_ entity. It is used to enable the call of the internal action `reCalcTotalPrice` of the _Travel_ parent BO entity at specific trigger points. +
🟣 Click to expand! - 1. Go to the method **`calculateTotalPrice`** of the local handler class **`lhc_booking`** in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_BOOKINGTP_###`** and replace the empty method implementation with the code provide below. - + 1. Go to the method **`calculateTotalPrice`** of the local handler class **`lhc_booking`** in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_BOOKINGTP_###`** and replace the empty method implementation with the code provided below. + Replace all occurences of the placeholder `###` with your assigned suffix. - + ```ABAP ************************************************************************** * Determination calculateTotalPrice @@ -235,42 +237,43 @@ In this exercise, you will implement the determinations defined for the _travel_ FROM CORRESPONDING #( travels ). ENDMETHOD. ``` - - 2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - -
- + +2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + + + - ## Exercise 8.3: Preview and Test the Enhanced _Travel_ App + [^Top of page](#) -You can test the enhanced SAP Fiori elements app can be tested. +You can test the enhanced SAP Fiori elements app can be tested.
🔵 Click to expand! - 1. You can either refresh your application in the browser using **F5** if the browser is still open - or go to your service binding **`ZRAP110_UI_TRAVEL_O4_###`** and start the Fiori elements App preview for the **`Travel`** entity set. +1. You can either refresh your application in the browser using **F5** if the browser is still open - or go to your service binding **`ZRAP110_UI_TRAVEL_O4_###`** and start the Fiori elements App preview for the **`Travel`** entity set. + +2. Play around with the app. For example,... - 2. Play around with the app. For example,... - Create or Edit an existing entry to check the calculation of the total price. - Create a new _booking_ instance. - Preview - + Preview + +
- - ## Summary + [^Top of page](#introduction) -Now that you've... +Now that you've... + - Implemented the various determinations, - called an internal action from a determination, and - previewed your enhanced _travel_ App - + you can continue with the next exercise – **[Exercise 9: Enhance the BO Behavior with Side Effects](../ex09/README.md)** --- - diff --git a/exercises/ex09/README.md b/exercises/ex09/README.md index dd228c2..fb7a5d3 100644 --- a/exercises/ex09/README.md +++ b/exercises/ex09/README.md @@ -2,174 +2,172 @@ # Exercise 9: Enhance the BO Behavior with Side Effects -## Introduction +## Introduction In the previous exercise, you've implemented determinations in the base BO Behavior (see [Exercise 8](../ex08/README.md)). -In the present exercise, you will define side effects for the _travel_ BO root entity to trigger a reload of the Fiori elements based _Travel_ app. +In the present exercise, you will define side effects for the _travel_ BO root entity to trigger a reload of the Fiori elements based _Travel_ app. ### Exercises - + - [9.1 - Define Side Effects in the base _Travel_ BO Behavior](#exercise-91-define-side-effects-in-the-base-travel-bo-behavior) - [9.2 - Expose Side Effects in the _Travel_ BO Behavior Projection](#exercise-92-expose-side-effects-in-the-travel-bo-projection) -- [9.3 - Define Side Effects in the _Travel_BO Behavior Projection](#exercise-93-define-side-effects-in-the-travel-bo-behavior-projection) +- [9.3 - Define Side Effects in the \_Travel_BO Behavior Projection](#exercise-93-define-side-effects-in-the-travel-bo-behavior-projection) - [9.4 - Preview and Test the Enhanced Travel App](#exercise-94-preview-and-test-the-enhanced-travel-app) -- [Summary](#summary) +- [Summary](#summary) -> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned assigned suffix in the exercise steps below. +> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned assigned suffix in the exercise steps below. -### About Side Effects +### About Side Effects > Side effects are used to trigger data, permission, or message changes based on data changes in UI scenarios with draft-enabled BOs. -> +> > They are useful in UI scenarios based on draft-enabled BOs to notify a Fiori Elements UI that data changes of defined fields require the recalculation of other data values, permissions or messages. -> +> > **Further reading**: [Side Effects](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/side-effects) - ## Exercise 9.1: Define Side Effects in the base _Travel_ BO Behavior + [^Top of page](#) > Define Side effects to trigger the recalculation of the total price (`TotalPrice`) each time the fields the booking fee (`BookingFee`), the currency code (`CurrencyCode`), and the flight price (`FlightPrice`) of the _travel_ or the _booking_ entities change on the UI. -> +> > Also define Side effects so that begin date (`BeginDate`) and the end date (`EndDate`) of the travel entity are validated each time they are changed. ->
🔵 Click to expand! -### Exercise 9.1.1: Define the Side Effects for the base _Travel_ BO Entity +### Exercise 9.1.1: Define the Side Effects for the base _Travel_ BO Entity + +> Define side effects for the fields **`TotalPrice`**, **`BeginDate`**, and **`EndDate`** of the _travel_ entity. - > Define side effects for the fields **`TotalPrice`**, **`BeginDate`**, and **`EndDate`** of the _travel_ entity. -
🟣 Click to expand! - - 1. Open the behavior definition of the _travel_ BO entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`**. - 2. Define the side effects for the recalculation of the total price. - +1. Open the behavior definition of the _travel_ BO entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`**. + +2. Define the side effects for the recalculation of the total price. + Field triggers are the elements **`BookingFee`** and **`CurrencyCode`**, and the field target (or affected field) is the element **`TotalPrice`**. - - Insert the code snippet provided below after the determinations as shown on the screenshot. + + Insert the code snippet provided below after the determinations as shown on the screenshot. ```ABAP //side effects - side effects + side effects { field BookingFee affects field TotalPrice; field CurrencyCode affects field TotalPrice; } ``` - - package - - - 2. Define the side effects to trigger the validation of **`BeginDate`** and **`EndDate`**. - + + package + +3. Define the side effects to trigger the validation of **`BeginDate`** and **`EndDate`**. + For that the defined **`determine action checkDates`** defined in [Exercise 3.4](../ex03/README.md#exercise-34-define-the-actions) will be called each time `BeginDate` and `EndDate` are changed. The respective messages should be reloaded whenever available. - + > ℹ A `determine action` allows you to specify trigger points for when validations and determinations should be invoked. - + Add following code snippet to the **`side effects`** definition as shown on the screenshot: - + ```ABAP - determine action checkDates executed on field BeginDate, field EndDate affects messages; + determine action checkDates executed on field BeginDate, field EndDate affects messages; ``` - - package - + + package +
- -### Exercise 9.1.2: Define the Side Effects for the base _Booking_ BO Entity - > Define side effects for the fields **`TotalPrice`** of the parent _travel_ entity. - +### Exercise 9.1.2: Define the Side Effects for the base _Booking_ BO Entity + +> Define side effects for the fields **`TotalPrice`** of the parent _travel_ entity. +
🟣 Click to expand! - - 1. Open the behavior definition of the _booking_ BO entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`**. - - 2. Define the side effects for the recalculation of the total price of the target _travel_ entity each time the flight price or the currency code of the _booking_ entity changes. - + +1. Open the behavior definition of the _booking_ BO entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`**. + +2. Define the side effects for the recalculation of the total price of the target _travel_ entity each time the flight price or the currency code of the _booking_ entity changes. + Field triggers are the elements **`FlightPrice`** and **`CurrencyCode`**, and the field target (aka affected field) is the element **`_Travel-TotalPrice`** of the target parent _Travel_ entity. - - (**`_Travel.TotalPrice`**) - - Insert the code snippet provided below after the determinations as shown on the screenshot. + + (**`_Travel.TotalPrice`**) + + Insert the code snippet provided below after the determinations as shown on the screenshot. ```ABAP - //side effects for a target entity + //side effects for a target entity side effects { field FlightPrice affects field _Travel . TotalPrice; field CurrencyCode affects field _Travel . TotalPrice; } - ``` - - package - - 3. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + ``` + + package + +3. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes.
- ## Exercise 9.2: Expose Side Effects in the _Travel_ BO Projection + [^Top of page](#) > Now, you have to expose the side effects in the BO behavior projection to enable it on the Fiori elements _Travel_ app.
🔵 Click to expand! - - 1. Open the behavior projection of the _Travel_ BO ![bdef](../images/adt_bdef.png)**`ZRAP110_C_TravelTP_###`**. - - 1. Insert the code snippet provided below just after the `use draft;` statement as shown on the screenshot. - + +1. Open the behavior projection of the _Travel_ BO ![bdef](../images/adt_bdef.png)**`ZRAP110_C_TravelTP_###`**. + +1. Insert the code snippet provided below just after the `use draft;` statement as shown on the screenshot. + ```ABAP - use side effects; - ``` - - package - - 2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - + use side effects; + ``` + + package + +1. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. +
- + 9.3 - Define Side Effects in the _Travel_ BO Projection +## Exercise 9.3: Define Side Effects in the _Travel_ BO Behavior Projection -## Exercise 9.3: Define Side Effects in the _Travel_ BO Behavior Projection [^Top of page](#) -> Now, you will define side effects in the BO behavior projection for the virtual elements defined in the BO projection view: **`DaysToFlightIndicator`**, +> Now, you will define side effects in the BO behavior projection for the virtual elements defined in the BO projection view: **`DaysToFlightIndicator`**, > **`InitialDaysToFlight`**, and **`RemainingDaysToFlight`**. -> +> > Side effects for elements defined the BO projection layer have to be defined on the same layer. They cannot be defined on the base BO layer.
🔵 Click to expand! - - 1. Go to the behavior projection of the _Travel_ BO ![bdef](../images/adt_bdef.png)**`ZRAP110_C_TravelTP_###`**. - - 2. Insert the code snippet provided below in the behavior projection of the _booking_ BO entity **`ZRAP110_C_BookingTP_###`** just after the `use delete;` statement as shown on the screenshot. - - ```ABAP + +1. Go to the behavior projection of the _Travel_ BO ![bdef](../images/adt_bdef.png)**`ZRAP110_C_TravelTP_###`**. + +2. Insert the code snippet provided below in the behavior projection of the _booking_ BO entity **`ZRAP110_C_BookingTP_###`** just after the `use delete;` statement as shown on the screenshot. + + ```ABAP side effects { field BookingDate affects field DaysToFlightIndicator, field InitialDaysToFlight, field RemainingDaysToFlight; field FlightDate affects field DaysToFlightIndicator, field InitialDaysToFlight, field RemainingDaysToFlight; field ConnectionID affects field DaysToFlightIndicator, field InitialDaysToFlight, field RemainingDaysToFlight; - field CarrierID affects field DaysToFlightIndicator, field InitialDaysToFlight, field RemainingDaysToFlight; } - ``` - - BDEF Projection - - 2. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - + field CarrierID affects field DaysToFlightIndicator, field InitialDaysToFlight, field RemainingDaysToFlight; } + ``` + + BDEF Projection + +3. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. +
- -## Exercise 9.4: Preview and Test the Enhanced Travel App +## Exercise 9.4: Preview and Test the Enhanced Travel App + [^Top of page](#) > You can now preview and test the changes by creating a new _travel_ instance with _booking_ instances in the _Travel_ app. @@ -177,21 +175,22 @@ In the present exercise, you will define side effects for the _travel_ BO root e
🔵 Click to expand! -1. Refresh your application in the browser using **F5** if the browser is still open - +1. Refresh your application in the browser using **F5** if the browser is still open - or go to your service binding ![srvb icon](../images/adt_srvb.png)**`ZRAP110_UI_TRAVEL_O4_###`** and start the Fiori elements App preview for the **`Travel`** entity set. -2. For example, go to an existing _Travel_ instance or edit an existing one, and change either the booking fee or a booking flight price. - +2. For example, go to an existing _Travel_ instance or edit an existing one, and change either the booking fee or a booking flight price. + The total price should be re-calculated directly. - package + package
## Summary [^Top of page](#) -Now that you've... +Now that you've... + - defined side effects in the base BO, - exposed them in the BO projection, and - tested the enhanced _Travel_ app, @@ -199,4 +198,3 @@ Now that you've... you can continue with the next exercise – **[Exercise 10: Implement the Base BO Behavior - Functions](../ex10/README.md)** --- - diff --git a/exercises/ex10/README.md b/exercises/ex10/README.md index 8bdcea9..2d731c5 100644 --- a/exercises/ex10/README.md +++ b/exercises/ex10/README.md @@ -2,34 +2,36 @@ # Exercise 10: Implement the Base BO Behavior - Functions -## Introduction +## Introduction In the previous exercise, you've defined side effects for the _Travel_ BO (see [Exercise 9](../ex09/README.md)). In this exercise, you will implement the function **`getDaysToFlight`** that you've defined in [Exercise 3](../ex03/README.md). This function will be used to determine all the day to flight related virtual elements defined in the _booking_ BO projection view (see [Exercise 4](../ex04/README.md)). -### Exercises: +### Exercises: + - [10.1 - Implement the Functions of the _Booking_ BO Entity](#exercise-101-implement-the-functions-of-the-booking-bo-entity) - [10.2 - Test Function using EML](#exercise-102-test-function-using-eml) -- [Summary](#summary) +- [Summary](#summary) + +> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned suffix in the exercise steps below. -> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your choosen or assigned assigned suffix in the exercise steps below. +### About Functions -### About Functions
Click to expand! - + > A function in RAP is a custom read-operation that is part of the business logic. -> -> Functions perform calculations or reads on business objects without causing any side effects. +> +> Functions perform calculations or reads on business objects without causing any side effects. > Functions don't issue any locks on database tables and you can't modify or persist any data computed in a function implementation. -> +> > **Further reading**: [Functions](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/functions) - -
+ ## Exercise 10.1: Implement the Functions of the _Booking_ BO Entity + [^Top of page](#) > Implement the only one function that was defined in [Exercise 3.6](../ex06/README.md): `getDaysToFlight`. @@ -40,65 +42,66 @@ In this exercise, you will implement the function **`getDaysToFlight`** that you ### Exercise 10.1.1: Implement the Function `getDaysToFlight` of the _Booking_ BO Entity > Implement the the Function `getDaysToFlight` for the _booking_ entity in the behavior implementation class ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_BookingTP_###`**. This function can be used to determine the values of the virtual elements of the _Booking_ BO projection view: **`BookingStatusIndicator`**, **`InitialDaysToFlight`**, **`RemainingDaysToFlight`**, and **`DaysToFlightIndicator`**. -> +> > This function can, for example, be used at runtime to calculate the virtual elements via direct EML calls. ->
🟣 Click to expand! - 1. Open the behavior implementation class of the _Travel_ entity ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_BOOKINGTP_###`** and navigate to the method **`getDaysToFlight`** of the local handler class **`lhc_booking`** - - 2. Implement the function method **`getDaysToFlight`**. - - For that, replace the empty method implementation of **`getDaysToFlight`** with the source code provided below and -replace all occurences of the placeholder `###` with your assigned suffix using **Ctrl+F**. - - ```ABAP - ************************************************************************** - * Instance-bound function for calculating virtual elements via EML calls - ************************************************************************** - METHOD getDaysToFlight. - DATA: - c_booking_entity TYPE ZRAP110_C_BookingTP_###, - bookings_result TYPE TABLE FOR FUNCTION RESULT zrap110_r_traveltp_###\\booking~getdaystoflight, - booking_result LIKE LINE OF bookings_result. - - "read relevant data - READ ENTITIES OF ZRAP110_R_TravelTP_### IN LOCAL MODE - ENTITY booking - FIELDS ( TravelID BookingStatus BookingID FlightDate BookingDate ) - * ALL FIELDS - WITH CORRESPONDING #( keys ) - RESULT DATA(bookings). - - LOOP AT bookings ASSIGNING FIELD-SYMBOL(). - c_booking_entity = CORRESPONDING #( ). - "set relevant transfered data - booking_result = CORRESPONDING #( ). - "calculate virtual elements - booking_result-%param - = CORRESPONDING #( zrap110_calc_book_elem_###=>calculate_days_to_flight( c_booking_entity ) - MAPPING booking_status_indicator = BookingStatusIndicator - days_to_flight_indicator = DaysToFlightIndicator - initial_days_to_flight = InitialDaysToFlight - remaining_days_to_flight = RemainingDaysToFlight ). - "append - APPEND booking_result TO bookings_result. - ENDLOOP. - - result = bookings_result. - - ENDMETHOD. - ``` - - 4. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. +1. Open the behavior implementation class of the _Travel_ entity ![ABAP class](../images/adt_class.png)**`ZRAP110_BP_BOOKINGTP_###`** and navigate to the method **`getDaysToFlight`** of the local handler class **`lhc_booking`** + +2. Implement the function method **`getDaysToFlight`**. + + For that, replace the empty method implementation of **`getDaysToFlight`** with the source code provided below and + + replace all occurences of the placeholder `###` with your assigned suffix using **Ctrl+F**. + + ```ABAP + ************************************************************************** + * Instance-bound function for calculating virtual elements via EML calls + ************************************************************************** + METHOD getDaysToFlight. + DATA: + c_booking_entity TYPE ZRAP110_C_BookingTP_###, + bookings_result TYPE TABLE FOR FUNCTION RESULT zrap110_r_traveltp_###\\booking~getdaystoflight, + booking_result LIKE LINE OF bookings_result. + + "read relevant data + READ ENTITIES OF ZRAP110_R_TravelTP_### IN LOCAL MODE + ENTITY booking + FIELDS ( TravelID BookingStatus BookingID FlightDate BookingDate ) + * ALL FIELDS + WITH CORRESPONDING #( keys ) + RESULT DATA(bookings). + + LOOP AT bookings ASSIGNING FIELD-SYMBOL(). + c_booking_entity = CORRESPONDING #( ). + "set relevant transfered data + booking_result = CORRESPONDING #( ). + "calculate virtual elements + booking_result-%param + = CORRESPONDING #( zrap110_calc_book_elem_###=>calculate_days_to_flight( c_booking_entity ) + MAPPING booking_status_indicator = BookingStatusIndicator + days_to_flight_indicator = DaysToFlightIndicator + initial_days_to_flight = InitialDaysToFlight + remaining_days_to_flight = RemainingDaysToFlight ). + "append + APPEND booking_result TO bookings_result. + ENDLOOP. + + result = bookings_result. + + ENDMETHOD. + ``` + +3. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes.
## Exercise 10.2: Test Function using EML + [^Top of page](#) > Implement a READ FUNCTION in an ABAP class to test the implemented function. @@ -106,8 +109,8 @@ replace all occurences of the placeholder `###` with your assigned suffix using
🔵 Click to expand! - 1. Open the class **`ZRAP110_EML_PLAYGROUND_###`** and uncomment following coding: - +1. Open the class **`ZRAP110_EML_PLAYGROUND_###`** and uncomment following coding: + ```ABAP "execute function getDaysToFlight READ ENTITIES OF ZRAP110_R_TravelTP_### @@ -125,27 +128,27 @@ replace all occurences of the placeholder `###` with your assigned suffix using out->write( | --------------- | ). ENDLOOP. ``` - - BO Behavior Definition - - 2. Start your **_Travel_** App and copy a **Travel ID** from a former created entry of your choice. - - BO Behavior Definition - - 3. Go back to your class **`ZRAP110_EML_PLAYGROUND_###`** and **paste** your **Travel ID** on the corresponding space. - - BO Behavior Definition - - 4. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. - - 5. Right-click your class, select **Run As** > **ABAP Application (Console)** (or press **F9**). - - BO Behavior Definition - - 6. Check your result. - - BO Behavior Definition - + + BO Behavior Definition + +2. Start your **_Travel_** App and copy a **Travel ID** from a former created entry of your choice. + + BO Behavior Definition + +3. Go back to your class **`ZRAP110_EML_PLAYGROUND_###`** and **paste** your **Travel ID** on the corresponding space. + + BO Behavior Definition + +4. Save ![save icon](../images/adt_save.png) and activate ![activate icon](../images/adt_activate.png) the changes. + +5. Right-click your class, select **Run As** > **ABAP Application (Console)** (or press **F9**). + + BO Behavior Definition + +6. Check your result. + + BO Behavior Definition +
@@ -153,11 +156,11 @@ replace all occurences of the placeholder `###` with your assigned suffix using ## Summary [^Top of page](#) -Now that you've... +Now that you've... + - implemented a function with a return structure as output parameter, and - determined the values of virtual elements via an EML call using a function, you can continue with the next exercise – **[Exercise 11: Enhance the BO Behavior with Business Events](../ex11/README.md)** --- - diff --git a/exercises/ex11/README.md b/exercises/ex11/README.md index b6be08c..faa6f05 100644 --- a/exercises/ex11/README.md +++ b/exercises/ex11/README.md @@ -4,73 +4,74 @@ ## Introduction -In the previous exercise, you've implemented a function for the _booking_ BO entity (see [Exercise 10](../ex10/README.md)). +In the previous exercise, you've implemented a function for the _booking_ BO entity (see [Exercise 10](../ex10/README.md)). -In this exercise, you will enhance the behavior defintion of the _Travel_ BO entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`** with business events. Your RAP BO will act as an event provider. The events will be used to send a message when the overall status of the _Travel_ BO node is changed to _accepted_ or _rejected_ to inform possible consumers about the change. +In this exercise, you will enhance the behavior defintion of the _Travel_ BO entity ![bdef](../images/adt_bdef.png)**`ZRAP110_R_TRAVELTP_###`** with business events. Your RAP BO will act as an event provider. The events will be used to send a message when the overall status of the _Travel_ BO node is changed to _accepted_ or _rejected_ to inform possible consumers about the change. In this exercise your RAP BO acts as an event provider. For the local event consumption, you will implement a local event handler that acts as an event consumer, listening to and processing events raised by your _Travel_ RAP BO in the same system. - ### Exercises: -- [11.1 - Define the Business Event Parameter](#exercise-111-define-the-business-event-parameter ) + +- [11.1 - Define the Business Event Parameter](#exercise-111-define-the-business-event-parameter) - [11.2 - Define the Business Event in the _Travel_ BO](#exercise-112-define-the-business-event-in-the-travel-bo) - [11.3 - Raise the Event in the _Travel_ BOl](#exercise-113-raise-the-event-in-the-travel-bo) - [11.4 - Create a Local Event Handler](#exercise-114-create-a-local-event-handler) - [11.5 - Test the Enhanced _Travel_ App](#exercise-115-test-the-enhanced-travel-app) - [Summary](#summary) -> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your assigned suffix in the exercise steps below. - +> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your assigned suffix in the exercise steps below. ### About Business Events in RAP
Click to expand the details! -> Developers can now define and raise business events in a RAP BO or in a RAP BO behavior extension. -> -> RAP supports event-driven architecture natively on SAP BTP ABAP environment and SAP S/4HANA in the cloud and on-prem as of release 2022. Event-driven architecture enables asynchronous communication between an event provider and an event consumer in use cases where no direct response from the event consumer is required. -> +> Developers can now define and raise business events in a RAP BO or in a RAP BO behavior extension. +> +> RAP supports event-driven architecture natively on SAP BTP ABAP environment and SAP S/4HANA in the cloud and on-prem as of release 2022. Event-driven architecture enables asynchronous communication between an event provider and an event consumer in use cases where no direct response from the event consumer is required. +> > Business events provide the opportunity of light-weight, decoupled process integration based on standardized and stable APIs and they are now a native part of the SAP - ABAP RESTful Application Programming Model. With the RAP Business Event Bindings Editor, you can create RAP Event Bindings which are needed to provide a mapping between the definition of RAP Events via behavior definition (BDEF) and the external representation of Business Events. -> +> > A RAP BO can act as event consumer or event provider. -> +> > RAP Business events can be consumed in other systems (_remote consumption_), or in the same system as they are raised (_local consumption_).
-> ℹ **Further reading**: [About RAP Business Events](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/business-events) | [Develop RAP Business Events](https://help.sap.com/docs/abap-cloud/abap-rap/develop-business-events) | [Business Event Consumption](https://help.sap.com/docs/abap-cloud/abap-rap/business-event-consumption) | +> ℹ **Further reading**: [About RAP Business Events](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/business-events) | [Develop RAP Business Events](https://help.sap.com/docs/abap-cloud/abap-rap/develop-business-events) | [Business Event Consumption](https://help.sap.com/docs/abap-cloud/abap-rap/business-event-consumption) | +## Exercise 11.1: Define the Business Event Parameter -## Exercise 11.1: Define the Business Event Parameter [^Top of page](#) -> A RAP Business event can be defined with or without an output parameter. An output parameter is used to transfer values that are not inherently part of the BO data model. -> +> A RAP Business event can be defined with or without an output parameter. An output parameter is used to transfer values that are not inherently part of the BO data model. +> > Parameters in RAP are modelled using CDS abtract entity. -> +> > In this exercise, you will use the CDS abstract entity ![ddls](../images/adt_ddls.png)**`ZRAP110_A_TRAVEL_###`** available in your exercise package **`ZRAP110_###`**, where **`###`** is your assigned suffix.
🔵 Click to expand! - 1. Go to the **Project Explorer**, open the CDS abtract view ![ddls](../images/adt_ddls.png)**`ZRAP110_A_TRAVEL_###`** in your package and have a look at its data definition. - - CDS Abstract Entity - + 1. Go to the **Project Explorer**, open the CDS abtract view ![ddls](../images/adt_ddls.png)**`ZRAP110_A_TRAVEL_###`** in your package and have a look at its data definition. + + CDS Abstract Entity +
- Source code - + Source code + ```ABAP @EndUserText.label: 'Abtract Entity for Travel' define abstract entity ZRAP110_A_TRAVEL_### @@ -86,23 +87,23 @@ In this exercise your RAP BO acts as an event provider. For the local event cons begin_date : /dmo/begin_date; end_date : /dmo/end_date; email_address : /dmo/email_address; - } + } ``` -
+
+ + Beside attributes - such as **`travel_id`**, **`customer_id`**, and **`total_price`** - that can be retrieved from the _Travel_ BO entity, the variable **`email_address`** can contains the e-mail address of an Agency which needs to be informed. The variable **`travel_id`** contains the information about the _travel_ that triggered the event. - Beside attributes - such as **`travel_id`**, **`customer_id`**, and **`total_price`** - that can be retrieved from the _Travel_ BO entity, the variable **`email_address`** can contains the e-mail address of an Agency which needs to be informed. The variable **`travel_id`** contains the information about the _travel_ that triggered the event. - - 2. Close the abstract entity and go ahead with the next step. +2. Close the abstract entity and go ahead with the next step.
-## Exercise 11.2: Define the Business Event in the _Travel_ BO +## Exercise 11.2: Define the Business Event in the _Travel_ BO + [^Top of page](#) > Define the events **`travel_accepted`** (with output parameter) and **`travel_rejected`** (without output parameter). > -> The event **`travel_accepted`** will be defined with the abstract entity ![ddls](../images/adt_ddls.png)**`ZRAP110_A_TRAVEL_###`** as output parameter. -> +> The event **`travel_accepted`** will be defined with the abstract entity ![ddls](../images/adt_ddls.png)**`ZRAP110_A_TRAVEL_###`** as output parameter.
🔵 Click to expand! @@ -111,40 +112,41 @@ In this exercise your RAP BO acts as an event provider. For the local event cons 2. Define the event **`travel_accepted`** using the keyword **`event`** in the behavior definition of the **_Travel_ BO node**, just after the _Side Effects_ as shown on the screenshot below. Replace the placeholder `###` with your assigned suffix. - Insert the code snippet provided below for the purpose after the _side effects_ definition. + Insert the code snippet provided below for the purpose after the _side effects_ definition. ```ABAP //business events - event travel_accepted parameter ZRAP110_A_Travel_###; - event travel_rejected; + event travel_accepted parameter ZRAP110_A_Travel_###; + event travel_rejected; ``` - Travel BO node bdef - - 3. Business events must be raised in the save sequence, therefore, we have to enable the _additional save_ for our managed BO by specifying the statement **`with additional save`**. - - We will add the keywords **`with full data`** to always have access to all the data of the _travel_ entity instances without having to read them. - + Travel BO node bdef + +3. Business events must be raised in the save sequence, therefore, we have to enable the _additional save_ for our managed BO by specifying the statement **`with additional save`** + + We will add the keywords **`with full data`** to always have access to all the data of the _travel_ entity instances without having to read them. + For that, insert the code snippet provided below after the `late numbering` statement, ```ABAP with additional save with full data - ``` - - Travel BO node bdef - - 4. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. - + ``` + + Travel BO node bdef + +4. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. + A warning ⚠ will be displayed about the need for a redefinition of the local saver method `save_modified`. You will tackle this in the next step. - +
## Exercise 11.3: Raise the Event in the _Travel_ BO + [^Top of page](#) -> The business events **`travel_accepted`** and **`travel_rejected`** must be respectively raised each time a _travel_ BO entity is accepted or rejected. This can be used, for example, to trigger an email 📤 to be sent out to whomever it may concern. -> -> Business events are raised in the additional save of the BO entity for which you want to raise the event, i.e. in the local saver class method **`save_modified`** of the behavior pool ![class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** of _Travel_ BO entity in the present scenario. +> The business events **`travel_accepted`** and **`travel_rejected`** must be respectively raised each time a _travel_ BO entity is accepted or rejected. This can be used, for example, to trigger an email 📤 to be sent out to whomever it may concern. +> +> Business events are raised in the additional save of the BO entity for which you want to raise the event, i.e. in the local saver class method **`save_modified`** of the behavior pool ![class](../images/adt_class.png)**`ZRAP110_BP_TRAVELTP_###`** of _Travel_ BO entity in the present scenario.
🔵 Click to expand! @@ -153,7 +155,7 @@ In this exercise your RAP BO acts as an event provider. For the local event cons 2. Define the constant **`travel_status`** for the different overall travel status and redefine the method **`save_modified`** in the local saver class definition. - Insert the code snippet provided below in the `PROTECTED SECTION` for the purpose. + Insert the code snippet provided below in the `PROTECTED SECTION` for the purpose. ```ABAP CONSTANTS: @@ -168,205 +170,209 @@ In this exercise your RAP BO acts as an event provider. For the local event cons Travel BO node bdef - 3. Add the method implementation using the ADT Quick Fix (**Ctrl+1**). + 3. Add the method implementation using the ADT Quick Fix (**Ctrl+1**). Select the appropriate entry for the method implementation to be added to the class implementation. - - Travel BO node bdef - - 4. Now go to the class implementation section and raise the event with the appropriate information. The appropriate events should be raised only when the overall status of a _travel_ instance is set to _accepted_ or _rejected_. - - For that, replace the empty method implementation of **`save_modified`** with the source code provided below and replace all occurences of the placeholder **`###`** with your assigned suffix using **Ctrl+F**. - - ```ABAP - METHOD save_modified. - "send notification for all accepted and rejected travel instances - IF update IS NOT INITIAL. - - "raise event - RAISE ENTITY EVENT ZRAP110_R_TravelTP_###~travel_accepted - FROM VALUE #( - FOR travel IN update-travel - WHERE ( %control-OverallStatus EQ if_abap_behv=>mk-on AND - OverallStatus EQ travel_status-accepted ) - "transferred information - ( %key = travel-%key - travel_id = travel-TravelID - agency_id = travel-AgencyID - customer_id = travel-CustomerID - overall_status = travel-OverallStatus - description = travel-Description - total_price = travel-TotalPrice - currency_code = travel-CurrencyCode - begin_date = travel-BeginDate - end_date = travel-EndDate - ) - ). - - "raise event - RAISE ENTITY EVENT ZRAP110_R_TravelTP_###~travel_rejected - FROM VALUE #( - FOR travel IN update-travel - WHERE ( %control-OverallStatus EQ if_abap_behv=>mk-on AND - OverallStatus EQ travel_status-rejected ) - "transferred information - ( %key = travel-%key ) - ). - - ENDIF. - ENDMETHOD. - ``` - - 4. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. - + Travel BO node bdef + +4. Now go to the class implementation section and raise the event with the appropriate information. The appropriate events should be raised only when the overall status of a _travel_ instance is set to _accepted_ or _rejected_. + + For that, replace the empty method implementation of **`save_modified`** with the source code provided below and replace all occurences of the placeholder **`###`** with your assigned suffix using **Ctrl+F**. + + ```ABAP + METHOD save_modified. + "send notification for all accepted and rejected travel instances + IF update IS NOT INITIAL. + + "raise event + RAISE ENTITY EVENT ZRAP110_R_TravelTP_###~travel_accepted + FROM VALUE #( + FOR travel IN update-travel + WHERE ( %control-OverallStatus EQ if_abap_behv=>mk-on AND + OverallStatus EQ travel_status-accepted ) + "transferred information + ( %key = travel-%key + travel_id = travel-TravelID + agency_id = travel-AgencyID + customer_id = travel-CustomerID + overall_status = travel-OverallStatus + description = travel-Description + total_price = travel-TotalPrice + currency_code = travel-CurrencyCode + begin_date = travel-BeginDate + end_date = travel-EndDate + ) + ). + + "raise event + RAISE ENTITY EVENT ZRAP110_R_TravelTP_###~travel_rejected + FROM VALUE #( + FOR travel IN update-travel + WHERE ( %control-OverallStatus EQ if_abap_behv=>mk-on AND + OverallStatus EQ travel_status-rejected ) + "transferred information + ( %key = travel-%key ) + ). + + ENDIF. + + ENDMETHOD. + ``` + +5. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. +
## Exercise 11.4: Create a Local Event Handler + [^Top of page](#) -> As mentioned in the introduction, RAP business events can be consumed locally in the same system where they are raised (local consumption) or remotely in a separate system using SAP Event Mesh (remote consumption) for the a cross-system communication. The events will be **consumed locally** in this exercise. -> -> For that, you will create an event handler class to locally consume the RAP business events raised by your application, ie. by your RAP BO: ![ABAP class](../images/adt_class.png)**`ZRAP110_TRAVEL_EVENT_HANDL_###`**, where `###` is your assigned suffix. In this exercise, the event handling will simply consist of persisting the received information to a database table. -> +> As mentioned in the introduction, RAP business events can be consumed locally in the same system where they are raised (local consumption) or remotely in a separate system using SAP Event Mesh (remote consumption) for the a cross-system communication. The events will be **consumed locally** in this exercise. +> +> For that, you will create an event handler class to locally consume the RAP business events raised by your application, ie. by your RAP BO: ![ABAP class](../images/adt_class.png)**`ZRAP110_TRAVEL_EVENT_HANDL_###`**, where `###` is your assigned suffix. In this exercise, the event handling will simply consist of persisting the received information to a database table.
🔵 Click to expand! - 1. First create a database table with a UUID-based primary key to store the received event information. - - For that, right-click the folder **Database Tables** and select **New Database Table** from the context menu to launch the creation wizard. - - Travel BO node bdef - - Maintain the required information and click **Next >**. - - Name: **`ZRAP110_ETRAV###`**, where `###` is your assigned suffix - - Description: `Travel event data` - - Travel BO node bdef - - Select a transport request, and click **Finish** to create the database table. - - Travel BO node bdef +1. First create a database table with a UUID-based primary key to store the received event information. - 2. Replace the default code with the code snippet provided below and replace all occurences of the placeholder `###` with your assigned suffix. - -
-        @EndUserText.label : 'Travel data'
-        @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
-        @AbapCatalog.tableCategory : #TRANSPARENT
-        @AbapCatalog.deliveryClass : #A
-        @AbapCatalog.dataMaintenance : #RESTRICTED
-        define table zrap110_etrav### {
-
-          key client     : abap.clnt not null;
-          key uuid       : sysuuid_x16 not null;
-          travel_id      : /dmo/travel_id not null;
-          agency_id      : /dmo/agency_id;
-          customer_id    : /dmo/customer_id;
-          event_name     : /dmo/description;
-          overall_status : /dmo/overall_status;
-          created_at     : abap.utclong;
-        }
-      
- - Travel BO node bdef + For that, right-click the folder **Database Tables** and select **New Database Table** from the context menu to launch the creation wizard. - 3. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. - - 4. Now go ahead, create, and implement the event handler class for the local event consumption. - - For that, go to the **Project Explorer**, right-click the folder **Classes** in your package, and select **New ABAP Classes** from the context menu to launch the creation wizard. - - Travel BO node bdef - - Maintain the required information and press **Finish**. - - Name: **`ZRAP110_TRAVEL_EVENT_HANDL_###`**, where `###` is your assigned suffix - - Description: _Travel event handler for local consumption_ + Travel BO node bdef - Travel BO node bdef - - Select a transport request, and click **Finish** to create the ABAP class. - - Travel BO node bdef - - 5. Specify the class as event handler class pool for your RAP BO by adding the statement **`FOR EVENTS OF entity_name`** of the class definition section, directly after the keyword **`FINAL`** as shown on the screenshot. Do not forget to replace all occurence of **`###`** with your assigned suffix. - -
-          FOR EVENTS OF ZRAP110_R_TRAVELTP_###
-     
+ Maintain the required information and click **Next >**. + + - Name: **`ZRAP110_ETRAV###`**, where `###` is your assigned suffix + - Description: `Travel event data` + + Travel BO node bdef + + Select a transport request, and click **Finish** to create the database table. + + Travel BO node bdef + +2. Replace the default code with the code snippet provided below and replace all occurences of the placeholder `###` with your assigned suffix. + +
+     @EndUserText.label : 'Travel data'
+     @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
+     @AbapCatalog.tableCategory : #TRANSPARENT
+     @AbapCatalog.deliveryClass : #A
+     @AbapCatalog.dataMaintenance : #RESTRICTED
+     define table zrap110_etrav### {
    
-     Travel BO node bdef  
-  
-     You can now go ahead with the event handler implementation.
- 
-  6. Now go to the **Local Types** tab to define and implement the local handler class **`lhe_travel`** for the _travel_ BO entity. 
-  
-     For that, simply replace the skeleton code with the source code provided in the document below. You can access the ABAP Kexword documentation (**F1**) for more details on the classes `cl_abap_behavior_event_handler` and `cl_abap_tx` used in the implementation.
-  
-     Do not forget to replace all occurences of the placeholder **`###`** with your assigned suffix. 
-       
-     ▶📄 **Source code document:** ![class](../images/adt_class.png)[Local Types of ABAP Class ZRAP110_TRAVEL_EVENT_HANDLER_###](sources/EX11_CLASS_ZRAP110_TRAVEL_EVENT_HANDLER_LocalTypes.txt)
-  
-     **Brief explanation of the local RAP event handler class `lhe_travel`**
-       
- Click to expand! - - 1. A local event handler class must inherit from the superclass **`cl_abap_behavior_event_handler`**. - - 2. Our current local event handler contains a RAP event handler method for each event we whant to handle: - - i.e. **`on_travel_accept()`** and **`on_travel_reject()`** for the events `travel_accepted` and `travel_rejected` respectively, in this exercise. - - In the method signature, the importing parameter, the entity, as well as the event to be consumed are specified. - - > **Note**: An event can only be handled by one method within an event handler class. However, method handling across multiple handler classes is possible. - - 3. In this exercise, the method **`get_uuid()`** is used for convenience to centrally generate UUIDs for the new database records to be persisted. - - 4. About the implementation of the RAP event handler methods: **`on_travel_accept()`** and **`on_travel_reject()`** - - Because we are doing an insert on a database, we must first close the active modify phase of the RAP LUW by calling the method `cl_abap_tx=>save()`. - - Loop over the transfered event instances and do the needful 🙂 - -
- - 7. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. - -
+ key client : abap.clnt not null; + key uuid : sysuuid_x16 not null; + travel_id : /dmo/travel_id not null; + agency_id : /dmo/agency_id; + customer_id : /dmo/customer_id; + event_name : /dmo/description; + overall_status : /dmo/overall_status; + created_at : abap.utclong; + } + + + Travel BO node bdef + +3. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. + +4. Now go ahead, create, and implement the event handler class for the local event consumption. + + For that, go to the **Project Explorer**, right-click the folder **Classes** in your package, and select **New ABAP Classes** from the context menu to launch the creation wizard. + + Travel BO node bdef + + Maintain the required information and press **Finish**. + + - Name: **`ZRAP110_TRAVEL_EVENT_HANDL_###`**, where `###` is your assigned suffix + - Description: _Travel event handler for local consumption_ + + Travel BO node bdef + + Select a transport request, and click **Finish** to create the ABAP class. + + Travel BO node bdef + +5. Specify the class as event handler class pool for your RAP BO by adding the statement **`FOR EVENTS OF entity_name`** of the class definition section, directly after the keyword **`FINAL`** as shown on the screenshot. Do not forget to replace all occurences of **`###`** with your assigned suffix. + +
+        FOR EVENTS OF ZRAP110_R_TRAVELTP_###
+   
+ + Travel BO node bdef + + You can now go ahead with the event handler implementation. + +6. Now go to the **Local Types** tab to define and implement the local handler class **`lhe_travel`** for the _travel_ BO entity. + + For that, simply replace the skeleton code with the source code provided in the document below. You can access the ABAP Keyword documentation (**F1**) for more details on the classes `cl_abap_behavior_event_handler` and `cl_abap_tx` used in the implementation. + + Do not forget to replace all occurences of the placeholder **`###`** with your assigned suffix. + + ▶📄 **Source code document:** ![class](../images/adt_class.png)[Local Types of ABAP Class ZRAP110*TRAVEL_EVENT_HANDLER*###](sources/EX11_CLASS_ZRAP110_TRAVEL_EVENT_HANDLER_LocalTypes.txt) + **Brief explanation of the local RAP event handler class `lhe_travel`** +
+ Click to expand! + + 1. A local event handler class must inherit from the superclass **`cl_abap_behavior_event_handler`**. + + 2. Our current local event handler contains a RAP event handler method for each event we whant to handle: + + - i.e. **`on_travel_accept()`** and **`on_travel_reject()`** for the events `travel_accepted` and `travel_rejected` respectively, in this exercise. + - In the method signature, the importing parameter, the entity, as well as the event to be consumed are specified. + + > **Note**: An event can only be handled by one method within an event handler class. However, method handling across multiple handler classes is possible. + + 3. In this exercise, the method **`get_uuid()`** is used for convenience to centrally generate UUIDs for the new database records to be persisted. + + 4. About the implementation of the RAP event handler methods: **`on_travel_accept()`** and **`on_travel_reject()`** + - Because we are doing an insert on a database, we must first close the active modify phase of the RAP LUW by calling the method `cl_abap_tx=>save()`. + - Loop over the transfered event instances and do the needful 🙂 + +
+ +7. Save ![save icon](../images/adt_save.png) (**Ctrl+S**) and activate ![activate icon](../images/adt_activate.png) (**Ctrl+F3**) the changes. + +
+ +## Exercise 11.5: Test the Enhanced _Travel_ App - ## Exercise 11.5: Test the Enhanced _Travel_ App [^Top of page](#) > Now play aroud with your _Travel_ app and check out whether the raised events were process by the event handler class and the respective information persisted in the database table **`ZRAP110_ETRAV###`**. ->
🔵 Click to expand! - - 1. First, start the Data Preview (F8) of the new database table `ZRAP110_ETRAV_###`. No data should be shown as it is empty. - - ??? - - 2. Now, go to your _Travel_ app, and, for example, set a Travel record to _accepted_ and another one to _rejected_. - - ??? - - ??? - - ??? - - 3. Go back to the ABAP Development Tools and refresh the Data Preview of the database table `ZRAP110_ETRAV_###`. - - Entires of the raised events should now appear on the screen. - ??? - - 4. You can repeat the test: Play around in the _Travel_ app and check the new entries in the database table `ZRAP110_ETRAV_###`. - +1. First, start the Data Preview (F8) of the new database table `ZRAP110_ETRAV_###`. No data should be shown as it is empty. + + ??? + +2. Now, go to your _Travel_ app, and, for example, set a Travel record to _accepted_ and another one to _rejected_. + + ??? + + ??? + + ??? + +3. Go back to the ABAP Development Tools and refresh the Data Preview of the database table `ZRAP110_ETRAV_###`. + + Entries of the raised events should now appear on the screen. + + ??? + +4. You can repeat the test: Play around in the _Travel_ app and check the new entries in the database table `ZRAP110_ETRAV_###`. +
## Summary + [^Top of page](#) -Now that you've... +Now that you've... + - Defined and raised an event in your BO behavior definition, - Created and implemented an event handler class for the local event consumption, and - Test the enhanced _Travel_ App, diff --git a/exercises/ex11b/README.md b/exercises/ex11b/README.md index 5c3e089..ca12355 100644 --- a/exercises/ex11b/README.md +++ b/exercises/ex11b/README.md @@ -2,12 +2,10 @@ Hallo [Home - RAP110](../../README.md) > ⚠**SAP TechEd 2023**: ⚠ -> +> > Please note that this exercise (Exercise **11b**) is NOT part of the hands-on exercises and therefore, must NOT be performed. > > This is because an SAP Event Mesh instance must be configured in the **SAP BTP Cockpit** and an outbound communication arrangement must be set up for the connection between the hands-on ABAP environment and SAP Event Mesh. -> -> # Exercise 11b: Exposure of RAP Business Events via SAP Event Mesh @@ -15,121 +13,124 @@ Hallo In the previous exercise, you've defined and raised a business event in the Travel BO entity in your Travel App ([see Exercise 11](../ex11/README.md)). -Inthe present scenario your RAP BO acts as event provider, so an event bising and an outbound communication arrangement is required to set up the connection between your system and the SAP Event Mesh. +In the present scenario your RAP BO acts as event provider, so an event biding and an outbound communication arrangement is required to set up the connection between your system and the SAP Event Mesh. In this exercise, you will create an event binding. - ### Exercises: + - [11b.1 - Create the Event Binding](#exercise-11b1-create-the-event-binding) - [11b.2 - Configure the Event Bindings in SAP Event Mesh](#exercise-11b2-configure-the-event-bindings-in-sap-event-mesh) - [11b.3 - Test the Enhanced _Travel_ App](#exercise-11b3-test-the-enhanced-travel-app) - [Summary](#summary) -- [Appendix](#appendix) +- [Appendix](#appendix) -> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your group ID in the exercise steps below. +> **Reminder**: Do not forget to replace the suffix placeholder **`###`** with your group ID in the exercise steps below. @@ -139,37 +140,37 @@ REMOVED AFTER TECHED 2023 🔵 Click to expand! 1. For that, launch the SAP Fiori Launchpad. For that, right-click your **_ABAP Cloud Project_** (or **Alt+Enter**) and select **Properties** in the context menu. - - Event Binding - + + Event Binding + 2. Then click on **ABAP Development** in the left window pane and click the System URL to open the SAP Fiori Launchpad. - - Event Binding - 3. Start the app _**Enterprise Event Enablement - Configure Channel Binding**_ in the SAP Fiori launchpad. - + Event Binding + + 3. Start the app _**Enterprise Event Enablement - Configure Channel Binding**_ in the SAP Fiori launchpad. + For that, you can search for **Configure Channel Binding** and select the entry. > Please search for _**`Kanalbindung`**_ if you’re logged in german (DE). - - Event Binding + + Event Binding 5. Select the event channel **`ZRAP110_TRAVEL_EVENTS`**, and add a new **Outbound Topic** in the **Outboung Topic Bindings** tab. - > An outbound Topic corresponds to a event binding _**Type**_ which can be found in the **Event Binding** editor - + > An outbound Topic corresponds to a event binding _**Type**_ which can be found in the **Event Binding** editor - > e.g. **`zrap110.a###.Travel.Accepted.v*`**, where `###` is your group ID/suffix, in the present exercise - - For that, select **Create**. + + For that, select **Create**. Event Binding - 8. Now search for your event with **`*axxx*`**. - + 8. Now search for your event with **`*axxx*`**. + Event Binding - +
-REMOVE AFTER TECHED 2023 +REMOVE AFTER TECHED 2023 --> +--> ## Summary + [^Top of page](#)