diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/130_create_a_new_abap_project.png b/130_create_a_new_abap_project.png new file mode 100644 index 0000000..18b256c Binary files /dev/null and b/130_create_a_new_abap_project.png differ diff --git a/140_create_a_new_abap_project.png b/140_create_a_new_abap_project.png new file mode 100644 index 0000000..5185bd7 Binary files /dev/null and b/140_create_a_new_abap_project.png differ diff --git a/99_100_add_zlocal_to_favorites.png b/99_100_add_zlocal_to_favorites.png new file mode 100644 index 0000000..db2ec71 Binary files /dev/null and b/99_100_add_zlocal_to_favorites.png differ diff --git a/README.md b/README.md index 30e7328..9d40a67 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,39 @@ -[![REUSE status](https://api.reuse.software/badge/github.com/SAP-samples/low-code-applications)](https://api.reuse.software/info/github.com/SAP-samples/low-code-applications) - -# Hands On Projects For Low Code Application Development +# Create SAP S/4HANA Extensions Using ABAP Cloud and SAP Build ## Description -This repository contains descriptions for hands on projects on low code development using SAP tools. +This repository contains the material for the workshop "Create SAP S/4HANA Extensions Using ABAP Cloud and SAP Build". +We will create a new service using the ABAP RESTful Application Programming Model (RAP) in an on premise SAP S/4HANA system and then create a process using SAP Build on the SAP Business Technology Platform (BTP). + +## Overview + +This session covers the basic app development steps using the ABAP Development Tools (ADT) to create a new OData service based on the ABAP RESTful Application Programming Model (RAP) in an on premise SAP S/4HANA system. This service will then be used in a new process that will be created using SAP Build that runs on the SAP Business Technology Platfrom (BTP). You will see how professional developers code this service in ABAP and then a citizen developer can create the process in a visual way without any coding skills in SAP Build. + +## The use case + + ## Requirements -The prerequisites if not otherwise noted are normally just a browser ( preferably Chrome ) with Internet access +To carry out the exercises of this repository, you need to +- install the ABAP Development Tools (ADT) for the ABAP development parts +- have a browser ready, preferably Google Chrome, to access the SAP Build + +The users for the development environment during the course are email addresses which are provided to you by the hosts. -## Contents +Go to [Getting Started - Preparation](exercises/ex0/README.md) to find out the installation details, URLs, then start with the first exercise. -- [Accelerate Application Development with Low-Code in the SAP Business Application Studio](https://github.com/SAP-samples/low-code-applications/tree/bas_capex_2204) based on the release 2204 +## Exercises -## How to obtain support -[Create an issue](https://github.com/SAP-samples/low-code-applications/issues) in this repository if you find a bug or have questions about the content. +- [Getting Started - Preparation](exercises/ex0/README.md) +- [Part 1 - ABAP ](exercises/rap/README.md) +- [Part 2 - SAP Build ](exercises/build/exercises/ex1/README.md) + +Start the exercises [here](exercises/rap/exercises/ex1/README.md). -For additional support, [ask a question in SAP Community](https://answers.sap.com/questions/ask.html). +## How to obtain support! -## Contributing -If you wish to contribute code, offer fixes or improvements, please send a pull request. Due to legal reasons, contributors will be asked to accept a DCO when they create the first pull request to this project. This happens in an automated fashion during the submission process. SAP uses [the standard DCO text of the Linux Foundation](https://developercertificate.org/). +Support for the content in this repository is available during the actual time of the session by the hosts. ## Contributing If you want to contribute, please check the [CONTRIBUTING.md](CONTRIBUTING.md) documentation for contribution guidelines. @@ -30,4 +43,4 @@ If you want to contribute, please check the [CONTRIBUTING.md](CONTRIBUTING.md) d SAP adopts the Contributor's Covenant 2.0 across our open source projects to ensure a welcoming and open culture for everyone involved ([Code of Conduct](CODE_OF_CONDUCT.md)). ## License -Copyright (c) 2022 SAP SE or an SAP affiliate company. All rights reserved. This project is licensed under the Apache Software License, version 2.0 except as noted otherwise in the [LICENSE](LICENSE) file. +Copyright (c) 2023 SAP SE or an SAP affiliate company. All rights reserved. This project is licensed under the Apache Software License, version 2.0 except as noted otherwise in the [LICENSE](LICENSES/Apache-2.0.txt) file. diff --git a/exercises/build/exercises/ex1/README.md b/exercises/build/exercises/ex1/README.md new file mode 100644 index 0000000..8d548df --- /dev/null +++ b/exercises/build/exercises/ex1/README.md @@ -0,0 +1,153 @@ +# Exercise 1: Create Actions in SAP Build to access the Onlineshop API + +From this exercise on, we will switch to SAP's Business Technology Platform (BTP) on which SAP's solution for citizen developers, SAP Build run. + +In this exercise we will create Actions in SAP Build that access the Onlineshop API on S/4HANA from the previous chapter. There will be 2 actions, one to read all the onlineshop entries and another one that creates a new onlineshop entry. + +To create such Actions we need to prepare 2 things first: +- create a destination in BTP to create the secure connectivity from a BTP subaccount to the Onlineshop API on S/4HANA from the previous chapters +- download the OData metadata document of the Onlineshop API from the previous chapter + +## Exercise 1.1: Create a Destination in a BTP subaccount to access the Onlineshop API + +We will now create the destination in a BTP subaccount to our Onlineshop API in the S/4HANA system from the previous chapter. The destination will ensure secure connectivity. + +1. In your ABAP Development Tools under **Business Services** -> **Service Bindings** -> **Z_ONLINESHOP_###** copy the **Service URL**, it should be `/sap/opu/odata4/sap/z_onlineshop_###/srvd_a2x/sap/z_onlineshop_###/0001/` (Make sure you don't use the service binding for the UI but the Web API!) + +![serviceurl](images/105.png) + +2. In a browser open the [destinations view in the BTP Cockpit](https://emea.cockpit.btp.cloud.sap/cockpit/#/globalaccount/47ae62c5-c35b-48a4-99b1-eee46b5b62bf/subaccount/f65e327c-d9e9-44cd-8d7b-e4e7ea8db474/destinations) + +3. Press the `New Destination` button. + +4. Fill in the following: + + | Porperty | Value | + | :------------- | :------------- | + | Name | Onlineshop_### | + | Type | HTTP | + | Description | Onlineshop_### on S4H | + | URL | http://s4h:443 + the copied Onlineshop URL (e.g. /sap/opu/odata4/sap/z_onlineshop_###/srvd_a2x/sap/z_onlineshop_###/0001/) | + | Proxy Type | OnPremise | + | Authentication | BasicAuthentication | + | Location ID | CALCC | + | User | lowcode### | + | Password | ABAP credentials as provided by your instructor | + +5. Then press the `New Property` button and add +`sap.applicationdevelopment.actions.enabled` with value `true` + +6. Press the `New Property` button again and add +`sap.processautomation.enabled` with value `true` + +![destination](images/100.png) + +7. Press `Save` + +8. Press `Check Connection`: You should get a pop up that says `Connection to "Onlineshop_###" successful` + +## Exercise 1.2: Download the OData metadata document of the Onlineshop API + +In this exercise we will download the OData metadata document to a file to later use it for a definiton of an Action for SAP Build. + +1. In your ABAP Development Tools you should still have the service binding ( under **Business Services** -> **Service Bindings** -> **Z_ONLINESHOP_###** ) open , this time, click on **Service URL**: + +![serviceurl](images/110.png) + +2. A browser window opens. The URL will look like this: + + https://YY.YYY.YYY.YY:44301/sap/opu/odata4/sap/z_onlineshop_###/srvd_a2x/sap/z_onlineshop_###/0001/?sap-client=100 + + Delete the `?sap-client=100` at the end and instead add `$metadata`, so the URL looks like this: + + https://YY.YYY.YYY.YY:44301/sap/opu/odata4/sap/z_onlineshop_###/srvd_a2x/sap/z_onlineshop_###/0001/$metadata + + Press `return` to load the metadata document + +4. Right Mouse Click on the browser window and select `View Page Source` and press `Ctrl + A` + `Ctrl + C` (`Command + A` + `Command + C` on Mac) + +5. Open a text editor on your computer, paste the copied content using `Ctrl + V` (`Command + V` on Mac) and save the file as `Onlineshop_###_metadata.xml` to a location of your liking on your computer + +## Exercise 1.3: Create Actions from the Onlineshop API + +1. Open the [lobby](https://lcapteched.eu10.build.cloud.sap/lobby) in the browser with + + User: lowcodeuser+0###@gmail.com + + PW: XXXXXXX + + that is provided by the instructors by the workshop (note this is not the same user as for the ABAP development tools, it is a BTP user) + +2. Press `Create` + +![lobby](images/150.png) + +3. Select `Build an Automated Process` + +![lobby](images/155.png) + +4. Select `Actions` + +![lobby](images/160.png) + +5. As Project Name choose `Onlineshop###Action`. Use the `Browse` button to locate the metadata file that you have saved in the previous step on your computer. Press `Create` + +![lobby](images/165.png) + +6. Expand the entry `onlineshop` and select both, the `POST /onlineshop Add new entry to onlineshop` and the `Get /onlineshop Get entities from onlineshop`. Press `Add` + +![lobby](images/170.png) + +7. The 2 actions are now visible, select the `POST` one. In the right upper corner press the `Settings` button that looks like a gear wheel. + +![lobby](images/180.png) + +## Exercise 1.4: Test Actions from the Onlineshop API + +1. Switch `Enable CSRF` to `yes` and press `Save` + +![lobby](images/185.png) + +2. To test the action, select the destination that you have created before `Onlineshop_###`. In the input fields below, write `AS02` for the `product` and a number into the `quantity` field. Press `Test`. + +![lobby](images/190.png) + +3. The result should look like this: + +![lobby](images/195.png) + +## Exercise 1.5: Release the Action and Publish to Library + +In order to use the action inside SAP Build products like Process Automation, it has to be released first. Releasing means that the current state of the action is stored in an imutable way. Once the project is released, it can be published to library, which means that it is available inside SAP Build products like Process Automation, it can be discovered and used there. + +1. In the upper right corner of your action press `Release` + +![lobby](images/200.png) + +2. Optionally add some release notes and press `Release` on the dialog + +![lobby](images/205.png) + +3. After you released the action, in the same upper right corner the button has changed to `release to library`, press it + +![lobby](images/210.png) + +4. Confirm that you want to publish, pressing the button + +![lobby](images/215.png) + +## Excercise 1.6: Add the Destination to the SAP Build Settings + +You have set up a destination in the BTP Cockpit to test our new actions and in the last step made the actions available for usage in SAP Build Process Automation. You now also need to register the destination with SAP Build to be used in a real environment of a process, not just for tests of actions. + +1. In the SAP Build choose `Settings` and then `Destinations` in the left pane. + +2. Press `New Destination` and search for your destination `Onlineshop_###` where of course `###` is your group ID. Select the destination and press `Add`. + +![lobby](images/90.png) + +## Summary + +You have created 2 actions based on the Onlineshop Service, you built on ABAP Cloud in the previous exercises. You have created a BTP destination to connect to the Online Service and you have tested the actions. You have released the action and published it to a library, so you can use it in the following chapter in a new SAP Build Process Automation. You have also registered the destination for usage in SAP Build. + +You can continue with the next exercise - **[Exercise 2: Create a Process in SAP Build Process Automation based on the Onlineshop Service](../ex2/README.md)** diff --git a/exercises/build/exercises/ex1/images/100.png b/exercises/build/exercises/ex1/images/100.png new file mode 100644 index 0000000..95b5d7f Binary files /dev/null and b/exercises/build/exercises/ex1/images/100.png differ diff --git a/exercises/build/exercises/ex1/images/105.png b/exercises/build/exercises/ex1/images/105.png new file mode 100644 index 0000000..95a45bc Binary files /dev/null and b/exercises/build/exercises/ex1/images/105.png differ diff --git a/exercises/build/exercises/ex1/images/110.png b/exercises/build/exercises/ex1/images/110.png new file mode 100644 index 0000000..788e8d9 Binary files /dev/null and b/exercises/build/exercises/ex1/images/110.png differ diff --git a/exercises/build/exercises/ex1/images/150.png b/exercises/build/exercises/ex1/images/150.png new file mode 100644 index 0000000..09405af Binary files /dev/null and b/exercises/build/exercises/ex1/images/150.png differ diff --git a/exercises/build/exercises/ex1/images/155.png b/exercises/build/exercises/ex1/images/155.png new file mode 100644 index 0000000..5fcd097 Binary files /dev/null and b/exercises/build/exercises/ex1/images/155.png differ diff --git a/exercises/build/exercises/ex1/images/160.png b/exercises/build/exercises/ex1/images/160.png new file mode 100644 index 0000000..523912c Binary files /dev/null and b/exercises/build/exercises/ex1/images/160.png differ diff --git a/exercises/build/exercises/ex1/images/165.png b/exercises/build/exercises/ex1/images/165.png new file mode 100644 index 0000000..bf83f61 Binary files /dev/null and b/exercises/build/exercises/ex1/images/165.png differ diff --git a/exercises/build/exercises/ex1/images/170.png b/exercises/build/exercises/ex1/images/170.png new file mode 100644 index 0000000..d862ae6 Binary files /dev/null and b/exercises/build/exercises/ex1/images/170.png differ diff --git a/exercises/build/exercises/ex1/images/175.png b/exercises/build/exercises/ex1/images/175.png new file mode 100644 index 0000000..e4bf378 Binary files /dev/null and b/exercises/build/exercises/ex1/images/175.png differ diff --git a/exercises/build/exercises/ex1/images/180.png b/exercises/build/exercises/ex1/images/180.png new file mode 100644 index 0000000..c6b9dfb Binary files /dev/null and b/exercises/build/exercises/ex1/images/180.png differ diff --git a/exercises/build/exercises/ex1/images/185.png b/exercises/build/exercises/ex1/images/185.png new file mode 100644 index 0000000..e877a6b Binary files /dev/null and b/exercises/build/exercises/ex1/images/185.png differ diff --git a/exercises/build/exercises/ex1/images/190.png b/exercises/build/exercises/ex1/images/190.png new file mode 100644 index 0000000..e7dd187 Binary files /dev/null and b/exercises/build/exercises/ex1/images/190.png differ diff --git a/exercises/build/exercises/ex1/images/195.png b/exercises/build/exercises/ex1/images/195.png new file mode 100644 index 0000000..d338e12 Binary files /dev/null and b/exercises/build/exercises/ex1/images/195.png differ diff --git a/exercises/build/exercises/ex1/images/200.png b/exercises/build/exercises/ex1/images/200.png new file mode 100644 index 0000000..279ade8 Binary files /dev/null and b/exercises/build/exercises/ex1/images/200.png differ diff --git a/exercises/build/exercises/ex1/images/205.png b/exercises/build/exercises/ex1/images/205.png new file mode 100644 index 0000000..33bce84 Binary files /dev/null and b/exercises/build/exercises/ex1/images/205.png differ diff --git a/exercises/build/exercises/ex1/images/210.png b/exercises/build/exercises/ex1/images/210.png new file mode 100644 index 0000000..883d50d Binary files /dev/null and b/exercises/build/exercises/ex1/images/210.png differ diff --git a/exercises/build/exercises/ex1/images/215.png b/exercises/build/exercises/ex1/images/215.png new file mode 100644 index 0000000..f6ce716 Binary files /dev/null and b/exercises/build/exercises/ex1/images/215.png differ diff --git a/exercises/build/exercises/ex1/images/90.png b/exercises/build/exercises/ex1/images/90.png new file mode 100644 index 0000000..07e3512 Binary files /dev/null and b/exercises/build/exercises/ex1/images/90.png differ diff --git a/exercises/build/exercises/ex2/README.md b/exercises/build/exercises/ex2/README.md new file mode 100644 index 0000000..c60d47a --- /dev/null +++ b/exercises/build/exercises/ex2/README.md @@ -0,0 +1,216 @@ +# Exercise 2: Create a Process in SAP Build Process Automation based on the Onlineshop Service + +In this chapter you will build a whole process in SAP Build Process Automation. It will contain a UI with a form with which users can create requests for products in our onlineshop. Depending on the quantity there will then be an approval step where a manager will have to approve or reject the onlineshop request. If the quantity is low, the request will automatically be approved. In case of an approval an action to create a new onlineshop entry based on the onlineshop service you have built in the S/4HANA system using ABAP Cloud. The result can then be seen in the Fiori elements preview application based on the onlineshop service. + +Remember that wherever in this exercise you see `###` to replace it with your **group ID** that was given to you by the instructors. + +## Exercise 2.1: Create a new Process in SAP BUild Process Automation + +You will create the project for a process. + +1. Choose `Lobby`in SAP Build. Press `Create`. Select `Build and Automated Process` and then `Business Process`. + +![lobby](images/100.png) + +![lobby](images/110.png) + +2. Choose `Onlineshop###Process` as your Project Name and press `Create`. + +![lobby](images/120.png) + +3. The process project is being created and your are prompted to create a process within this project. Choose `Onlineshop####` as a name, leave the identifier as suggested by the system. + +![lobby](images/130.png) + +## Exercise 2.2: Add a Form to the Process + +You will create a UI form for the process, where users can request the order of a product with a quantitiy in the onlineshop. + +1. On the canvas of the process, press `+` on the trigger step that the system has already generated for you. Choose `Formss` and `New Form`. + +![lobby](images/140.png) + +2. Choose `Onlineshop###Form` as a name and press `Create`. + +![lobby](images/145.png) + +The new form is now embedded into the trigger of the process. + +3. On the form choose `Open Editor`. + +![lobby](images/150.png) + +You can now see a new canvas on which you can place a number of UI elements that make up your form. This is what users will see when they want to request a product in the onlineshop. + +4. From the left side pane, choose `Headline 1` and drag it to the Canvas and drop it there. Write `Enter the product and the quantity that you want to order` into the headline. Now choose `Text` and drag and drop it to the canvas. Change the fields label to `Product`. Now choose `Number` and drag and drop it to the canvas. Change the fields label to `Quantity`. Finally, press `Save`. + +![lobby](images/155.png) + +## Exercise 2.3: Add an Approval step to the Process + +You will create a an approval step for the onlineshop request. This is a UI that will pop up in an approver's (e.g. manager) `My Inbox` application, where the approver will see the product and the quantity that was ordered and can approve or reject the request. + +1. On the process canvas, press on the `+` after the process trigger, then choose `Approvals` and `New Approval Form`. + +![lobby](images/160.png) + +2. Choose `Onlineshop###Approval` as a name. Mark the `Based on a Form` checkbox and select the form that you have created in the previous step. Press `Create` + +![lobby](images/165.png) + +If you hadn't chosen to base the approval on the form, you would get an empty canvas and you could design the approval UI from scratch. However, since approvals usually contain a lot of information that was entered in the original form, it is a good idea to copy the forms UI elements over into the approval and then adjust where needed. + +3. Click on the new approval step on the canvas. On the right side pane choose the `General` tab. Place the cursor into the the `Subject` field and write `Approve order of`, then select the `Product` field that is suggested to you from your form. Under `Users` enter the email address of the user that was given to you by the instructor. + +![lobby](images/170.png) + +This step determines who gets the approval request in their `My Inbox` application. In a real scenario the reveiver might be determined dynamically and of course the requestor would not be the approver. For yor tests however, you want to see the approval in your inbox, make sure you use the right email address. + +4. Switch to the `Inputs` tab. Assign the `Product` and `Quantity` fields from your form to the corresponding fields of the approval. Press `Save` + +![lobby](images/175.png) + +This is a general pattern in Process Automation: There are outputs from a previous step, in this case the form that triggers the process and there are inputs for the follow up step like our approvals. Inputs and outputs need to be mapped. + +5. On the approval on the canvas press `Open Editor` + +![lobby](images/180.png) + +6. On the approval UI that now pops up and that contains the fields from your form, change the headline to be `Approval for order`, leave the rest of the fields as they are. `Save` your work + +![lobby](images/185.png) + +## Exercise 2.4: Add an Action step to the Process + +You will now add an action step that uses the action to add a new entry to the onlineshop that you have created in the exercise before. This action is invoked when the request from the form has been successfully approved. + +1. Press the `+` of `Approve` to the right of the approval step and choose `Actions` and `Browser Library`. + +![lobby](images/190.png) + +2. On the dialog search for the action `Onlineshop###Action`that you created before. Choose the `Add new entity to onlineshop` one and close the dialog. + +![lobby](images/220.png) + +3. On the right hand pane, choose to `Create Destination Variable`. On the following dialog, choose `MyDestination` as an identifier. Press `Create` + +![lobby](images/225.png) + +![lobby](images/230.png) + +This variable will later contain the name of the destination that you have created in an earler exercise. + +4. On the right hand pane choose the `Inputs` tab. Map the `product` field to the `Product` of the form and do the same for the `quantity` field from the `Quantity` in the form. `Save` your work. + +![lobby](images/235.png) + +5. On the canvas, press the `+` on the `Reject` end of the approval and drag and drop it to the `End` step of your process. + +![lobby](images/260.png) + +This makes sure that if the request is rejected by an approver, the action is not invoked and therefore no new onlineshop entry is created in the S/4HANA backend + +## Exercise 2.5: Add an Condition step to the Process + +In this exercise you will add a condition step to the process. It will check whether the ordered quantity from the form is equal or less to 1 and if so, bypass the approval step. + +1. On the process canvas, press the `+` on the right of your process trigger and choose `Controls` and `Condition`. + +![lobby](images/240.png) + +2. On the right side pane for the condition, press on the `Open Condition Editor` + +![lobby](images/245.png) + +3. On the dialog, choose the `Quantity` field from you form in the field on the very left. As a condition in the middler, choose `is greate than` from the list. As a value in the field on the very right, choose `1`. Press `Apply`. + +![lobby](images/250.png) + +4. On the canvas, choose the `+` on the `Default` branch of the condition and drag and drop it to your action step. + +![lobby](images/255.png) + +With this the approval step is bypassed when the condition is not met, i.e. when the quantity is 1. + +With this, you have finished building the process. + + +## Exercise 2.6: Release and Deploy your process + +In this part, you will release the project and deploy it to the BTP, so it can be tested and used for onlineshop requests. + +1. On your process canvas, first make sure that you `Save` all your work. Once the `Save` button is inactive, press on the `Release` button above + +![lobby](images/270.png) + +2. Optionally add some comment for the released version. Press `Release`. + +![lobby](images/275.png) + +Like for the actions before, this freezes the current state of your process. You can of course change the process afterwards, but you can always go back to this frozen, released state. + +3. Where the `Release` button was, there is now a `Deploy` button. Press it. + +![lobby](images/280.png) + +4. On the dialog that now appears, press `Next` for the first step. + +![lobby](images/285.png) + +This step shows all the artefacts that are part of the deployed process + +5. On the `Runtime Variables` step, choose your destination `Onlineshop_###` with the `Set new value` radiobutton selected. Press `Next` + +![lobby](images/290.png) + +This makes sure that your process action is bound to the destination when it is carried out. The destination is available here because you have registerd it under `Settings` in an earlier step. + +6. Press `Deploy` on the `Triggers` step. + +![lobby](images/295.png) + +## Exercise 2.7: Test your Process + +With the process now deployed, you can finally test the whole scenario! + +1. On the canvas, click on your form in the trigger step. On the right hand pane, under tab `General` copy the link in the field `From link` + +![lobby](images/300.png) + +2. Open a new browser window and past the link into it. You should see a form like below. Enter a product name of your liking and a quantiy that is greater than 1, e.g. 2. Press `Submit` + +![lobby](images/310.png) + +This is how a user will request a product, starting the process. + +Next up, let's check whether there is an approval step for this now. + +3. On the SAP Build window that contains the Lobby, click on the button on the right for `MyInbox` + +![lobby](images/315.png) + +4. The `MyInbox` application comes up and it should show an entry that corresponds with the request from the form that you just submitted. Select the entry and look at the approval text, it should contain the ordered product and quantity, that you just submitted. Press `Approve`. + +![lobby](images/320.png) + +5. Check whether there is a new entry in your Onlineshop Preview Fiori elements app, you might still have the corresponding browser window open. If you need to open it again, go back to your ABAP Development tools and open it again (See [here](../../..//rap/exercises/ex2#exercise-23-preview-the-onlineshop-app-using-fiori-elements) again, how to do that). + +![lobby](images/325.png) + +6. Now try bring up a new form of the process. This time however, enter a `quantity` of only `1` in your from and submit it. + +![lobby](images/330.png) + +As the quantity is only 1 and you had added a condition in the process to bypass the approval step and directly carry out the action in your process if this condition is met, you should now see a new entry for the onlineshop in the Fiori elements preview. + +7. Check whether there is a new entry in the Onlineshop Preview app, press `Go`. + +![lobby](images/335.png) + +You should see your new entry! + +## Summary + +This concludes the workshop! + +You have successfully built a new Onlineshop API on an S/4HANA system using ABAP Cloud capabilities. You have then create a new process using SAP Build Process Automation that makes use of this new API. The process contains the entry of an onlineshop request, an approval step as well as calling the API to create a new Onlineshop entry. \ No newline at end of file diff --git a/exercises/build/exercises/ex2/images/100.png b/exercises/build/exercises/ex2/images/100.png new file mode 100644 index 0000000..059d640 Binary files /dev/null and b/exercises/build/exercises/ex2/images/100.png differ diff --git a/exercises/build/exercises/ex2/images/110.png b/exercises/build/exercises/ex2/images/110.png new file mode 100644 index 0000000..3e4d250 Binary files /dev/null and b/exercises/build/exercises/ex2/images/110.png differ diff --git a/exercises/build/exercises/ex2/images/120.png b/exercises/build/exercises/ex2/images/120.png new file mode 100644 index 0000000..60dd4fc Binary files /dev/null and b/exercises/build/exercises/ex2/images/120.png differ diff --git a/exercises/build/exercises/ex2/images/130.png b/exercises/build/exercises/ex2/images/130.png new file mode 100644 index 0000000..e278079 Binary files /dev/null and b/exercises/build/exercises/ex2/images/130.png differ diff --git a/exercises/build/exercises/ex2/images/140.png b/exercises/build/exercises/ex2/images/140.png new file mode 100644 index 0000000..2790de1 Binary files /dev/null and b/exercises/build/exercises/ex2/images/140.png differ diff --git a/exercises/build/exercises/ex2/images/145.png b/exercises/build/exercises/ex2/images/145.png new file mode 100644 index 0000000..21f20c7 Binary files /dev/null and b/exercises/build/exercises/ex2/images/145.png differ diff --git a/exercises/build/exercises/ex2/images/150.png b/exercises/build/exercises/ex2/images/150.png new file mode 100644 index 0000000..469217a Binary files /dev/null and b/exercises/build/exercises/ex2/images/150.png differ diff --git a/exercises/build/exercises/ex2/images/155.png b/exercises/build/exercises/ex2/images/155.png new file mode 100644 index 0000000..b3e3362 Binary files /dev/null and b/exercises/build/exercises/ex2/images/155.png differ diff --git a/exercises/build/exercises/ex2/images/160.png b/exercises/build/exercises/ex2/images/160.png new file mode 100644 index 0000000..3d97b36 Binary files /dev/null and b/exercises/build/exercises/ex2/images/160.png differ diff --git a/exercises/build/exercises/ex2/images/165.png b/exercises/build/exercises/ex2/images/165.png new file mode 100644 index 0000000..e1cbdc6 Binary files /dev/null and b/exercises/build/exercises/ex2/images/165.png differ diff --git a/exercises/build/exercises/ex2/images/170.png b/exercises/build/exercises/ex2/images/170.png new file mode 100644 index 0000000..6bd1473 Binary files /dev/null and b/exercises/build/exercises/ex2/images/170.png differ diff --git a/exercises/build/exercises/ex2/images/175.png b/exercises/build/exercises/ex2/images/175.png new file mode 100644 index 0000000..f8f4ffb Binary files /dev/null and b/exercises/build/exercises/ex2/images/175.png differ diff --git a/exercises/build/exercises/ex2/images/180.png b/exercises/build/exercises/ex2/images/180.png new file mode 100644 index 0000000..d6a6273 Binary files /dev/null and b/exercises/build/exercises/ex2/images/180.png differ diff --git a/exercises/build/exercises/ex2/images/185.png b/exercises/build/exercises/ex2/images/185.png new file mode 100644 index 0000000..6637dae Binary files /dev/null and b/exercises/build/exercises/ex2/images/185.png differ diff --git a/exercises/build/exercises/ex2/images/190.png b/exercises/build/exercises/ex2/images/190.png new file mode 100644 index 0000000..1b38577 Binary files /dev/null and b/exercises/build/exercises/ex2/images/190.png differ diff --git a/exercises/build/exercises/ex2/images/220.png b/exercises/build/exercises/ex2/images/220.png new file mode 100644 index 0000000..a2e07f1 Binary files /dev/null and b/exercises/build/exercises/ex2/images/220.png differ diff --git a/exercises/build/exercises/ex2/images/225.png b/exercises/build/exercises/ex2/images/225.png new file mode 100644 index 0000000..a081f2f Binary files /dev/null and b/exercises/build/exercises/ex2/images/225.png differ diff --git a/exercises/build/exercises/ex2/images/230.png b/exercises/build/exercises/ex2/images/230.png new file mode 100644 index 0000000..c12d66c Binary files /dev/null and b/exercises/build/exercises/ex2/images/230.png differ diff --git a/exercises/build/exercises/ex2/images/235.png b/exercises/build/exercises/ex2/images/235.png new file mode 100644 index 0000000..4dd2724 Binary files /dev/null and b/exercises/build/exercises/ex2/images/235.png differ diff --git a/exercises/build/exercises/ex2/images/240.png b/exercises/build/exercises/ex2/images/240.png new file mode 100644 index 0000000..239f994 Binary files /dev/null and b/exercises/build/exercises/ex2/images/240.png differ diff --git a/exercises/build/exercises/ex2/images/245.png b/exercises/build/exercises/ex2/images/245.png new file mode 100644 index 0000000..e2fd80b Binary files /dev/null and b/exercises/build/exercises/ex2/images/245.png differ diff --git a/exercises/build/exercises/ex2/images/250.png b/exercises/build/exercises/ex2/images/250.png new file mode 100644 index 0000000..2e5fa32 Binary files /dev/null and b/exercises/build/exercises/ex2/images/250.png differ diff --git a/exercises/build/exercises/ex2/images/255.png b/exercises/build/exercises/ex2/images/255.png new file mode 100644 index 0000000..d8a05f9 Binary files /dev/null and b/exercises/build/exercises/ex2/images/255.png differ diff --git a/exercises/build/exercises/ex2/images/260.png b/exercises/build/exercises/ex2/images/260.png new file mode 100644 index 0000000..c79935a Binary files /dev/null and b/exercises/build/exercises/ex2/images/260.png differ diff --git a/exercises/build/exercises/ex2/images/270.png b/exercises/build/exercises/ex2/images/270.png new file mode 100644 index 0000000..e7ebea1 Binary files /dev/null and b/exercises/build/exercises/ex2/images/270.png differ diff --git a/exercises/build/exercises/ex2/images/275.png b/exercises/build/exercises/ex2/images/275.png new file mode 100644 index 0000000..0faedad Binary files /dev/null and b/exercises/build/exercises/ex2/images/275.png differ diff --git a/exercises/build/exercises/ex2/images/280.png b/exercises/build/exercises/ex2/images/280.png new file mode 100644 index 0000000..19c03b5 Binary files /dev/null and b/exercises/build/exercises/ex2/images/280.png differ diff --git a/exercises/build/exercises/ex2/images/285.png b/exercises/build/exercises/ex2/images/285.png new file mode 100644 index 0000000..f7a8a01 Binary files /dev/null and b/exercises/build/exercises/ex2/images/285.png differ diff --git a/exercises/build/exercises/ex2/images/290.png b/exercises/build/exercises/ex2/images/290.png new file mode 100644 index 0000000..27321ee Binary files /dev/null and b/exercises/build/exercises/ex2/images/290.png differ diff --git a/exercises/build/exercises/ex2/images/295.png b/exercises/build/exercises/ex2/images/295.png new file mode 100644 index 0000000..858a112 Binary files /dev/null and b/exercises/build/exercises/ex2/images/295.png differ diff --git a/exercises/build/exercises/ex2/images/300.png b/exercises/build/exercises/ex2/images/300.png new file mode 100644 index 0000000..85e3db9 Binary files /dev/null and b/exercises/build/exercises/ex2/images/300.png differ diff --git a/exercises/build/exercises/ex2/images/310.png b/exercises/build/exercises/ex2/images/310.png new file mode 100644 index 0000000..2a78603 Binary files /dev/null and b/exercises/build/exercises/ex2/images/310.png differ diff --git a/exercises/build/exercises/ex2/images/315.png b/exercises/build/exercises/ex2/images/315.png new file mode 100644 index 0000000..8e16b8e Binary files /dev/null and b/exercises/build/exercises/ex2/images/315.png differ diff --git a/exercises/build/exercises/ex2/images/320.png b/exercises/build/exercises/ex2/images/320.png new file mode 100644 index 0000000..35e3b01 Binary files /dev/null and b/exercises/build/exercises/ex2/images/320.png differ diff --git a/exercises/build/exercises/ex2/images/325.png b/exercises/build/exercises/ex2/images/325.png new file mode 100644 index 0000000..9c36934 Binary files /dev/null and b/exercises/build/exercises/ex2/images/325.png differ diff --git a/exercises/build/exercises/ex2/images/330.png b/exercises/build/exercises/ex2/images/330.png new file mode 100644 index 0000000..6d83813 Binary files /dev/null and b/exercises/build/exercises/ex2/images/330.png differ diff --git a/exercises/build/exercises/ex2/images/335.png b/exercises/build/exercises/ex2/images/335.png new file mode 100644 index 0000000..7d19027 Binary files /dev/null and b/exercises/build/exercises/ex2/images/335.png differ diff --git a/exercises/build/images/004.png b/exercises/build/images/004.png new file mode 100644 index 0000000..70208a3 Binary files /dev/null and b/exercises/build/images/004.png differ diff --git a/exercises/build/images/005.png b/exercises/build/images/005.png new file mode 100644 index 0000000..1b7ee28 Binary files /dev/null and b/exercises/build/images/005.png differ diff --git a/exercises/build/images/10.png b/exercises/build/images/10.png new file mode 100644 index 0000000..292e88e Binary files /dev/null and b/exercises/build/images/10.png differ diff --git a/exercises/build/images/11.1.png b/exercises/build/images/11.1.png new file mode 100644 index 0000000..f46aec3 Binary files /dev/null and b/exercises/build/images/11.1.png differ diff --git a/exercises/build/images/11.10.png b/exercises/build/images/11.10.png new file mode 100644 index 0000000..ba4bd3c Binary files /dev/null and b/exercises/build/images/11.10.png differ diff --git a/exercises/build/images/11.2.png b/exercises/build/images/11.2.png new file mode 100644 index 0000000..e7b1ab6 Binary files /dev/null and b/exercises/build/images/11.2.png differ diff --git a/exercises/build/images/11.7.png b/exercises/build/images/11.7.png new file mode 100644 index 0000000..3be7d1b Binary files /dev/null and b/exercises/build/images/11.7.png differ diff --git a/exercises/build/images/11.8.png b/exercises/build/images/11.8.png new file mode 100644 index 0000000..3f8e792 Binary files /dev/null and b/exercises/build/images/11.8.png differ diff --git a/exercises/build/images/11.png b/exercises/build/images/11.png new file mode 100644 index 0000000..d366e53 Binary files /dev/null and b/exercises/build/images/11.png differ diff --git a/exercises/build/images/6.1.png b/exercises/build/images/6.1.png new file mode 100644 index 0000000..e9dd761 Binary files /dev/null and b/exercises/build/images/6.1.png differ diff --git a/exercises/build/images/6.2.png b/exercises/build/images/6.2.png new file mode 100644 index 0000000..50af056 Binary files /dev/null and b/exercises/build/images/6.2.png differ diff --git a/exercises/build/images/6.3.png b/exercises/build/images/6.3.png new file mode 100644 index 0000000..805cada Binary files /dev/null and b/exercises/build/images/6.3.png differ diff --git a/exercises/build/images/7.1.png b/exercises/build/images/7.1.png new file mode 100644 index 0000000..5358e28 Binary files /dev/null and b/exercises/build/images/7.1.png differ diff --git a/exercises/build/images/7.2.png b/exercises/build/images/7.2.png new file mode 100644 index 0000000..4387817 Binary files /dev/null and b/exercises/build/images/7.2.png differ diff --git a/exercises/build/images/7.3.png b/exercises/build/images/7.3.png new file mode 100644 index 0000000..33b51fe Binary files /dev/null and b/exercises/build/images/7.3.png differ diff --git a/exercises/build/images/7.png b/exercises/build/images/7.png new file mode 100644 index 0000000..889874e Binary files /dev/null and b/exercises/build/images/7.png differ diff --git a/exercises/build/images/8.4.png b/exercises/build/images/8.4.png new file mode 100644 index 0000000..ad2d8d3 Binary files /dev/null and b/exercises/build/images/8.4.png differ diff --git a/exercises/build/images/8.5.png b/exercises/build/images/8.5.png new file mode 100644 index 0000000..9631feb Binary files /dev/null and b/exercises/build/images/8.5.png differ diff --git a/exercises/build/images/8.6.png b/exercises/build/images/8.6.png new file mode 100644 index 0000000..5c83d45 Binary files /dev/null and b/exercises/build/images/8.6.png differ diff --git a/exercises/build/images/8.png b/exercises/build/images/8.png new file mode 100644 index 0000000..c40c9da Binary files /dev/null and b/exercises/build/images/8.png differ diff --git a/exercises/build/images/9.1.png b/exercises/build/images/9.1.png new file mode 100644 index 0000000..989f5d9 Binary files /dev/null and b/exercises/build/images/9.1.png differ diff --git a/exercises/build/images/9.2.png b/exercises/build/images/9.2.png new file mode 100644 index 0000000..7bed44c Binary files /dev/null and b/exercises/build/images/9.2.png differ diff --git a/exercises/build/images/9.3.png b/exercises/build/images/9.3.png new file mode 100644 index 0000000..a03e6e4 Binary files /dev/null and b/exercises/build/images/9.3.png differ diff --git a/exercises/build/images/9.4.png b/exercises/build/images/9.4.png new file mode 100644 index 0000000..56065c3 Binary files /dev/null and b/exercises/build/images/9.4.png differ diff --git a/exercises/build/images/9.5.png b/exercises/build/images/9.5.png new file mode 100644 index 0000000..70ddb62 Binary files /dev/null and b/exercises/build/images/9.5.png differ diff --git a/exercises/build/images/9.png b/exercises/build/images/9.png new file mode 100644 index 0000000..9afd918 Binary files /dev/null and b/exercises/build/images/9.png differ diff --git a/exercises/build/images/FinalProcess.png b/exercises/build/images/FinalProcess.png new file mode 100644 index 0000000..e2d3856 Binary files /dev/null and b/exercises/build/images/FinalProcess.png differ diff --git a/exercises/build/images/Mail_1.png b/exercises/build/images/Mail_1.png new file mode 100644 index 0000000..40b1131 Binary files /dev/null and b/exercises/build/images/Mail_1.png differ diff --git a/exercises/build/images/autoapproval_2.png b/exercises/build/images/autoapproval_2.png new file mode 100644 index 0000000..55d7b7a Binary files /dev/null and b/exercises/build/images/autoapproval_2.png differ diff --git a/exercises/build/images/autoapproval_3.png b/exercises/build/images/autoapproval_3.png new file mode 100644 index 0000000..9ac28bf Binary files /dev/null and b/exercises/build/images/autoapproval_3.png differ diff --git a/exercises/build/images/mail_2.png b/exercises/build/images/mail_2.png new file mode 100644 index 0000000..28ca007 Binary files /dev/null and b/exercises/build/images/mail_2.png differ diff --git a/exercises/build/images/mail_3.png b/exercises/build/images/mail_3.png new file mode 100644 index 0000000..71ab3e4 Binary files /dev/null and b/exercises/build/images/mail_3.png differ diff --git a/exercises/build/images/mail_4.png b/exercises/build/images/mail_4.png new file mode 100644 index 0000000..c724c95 Binary files /dev/null and b/exercises/build/images/mail_4.png differ diff --git a/exercises/ex0/README.md b/exercises/ex0/README.md new file mode 100644 index 0000000..d30a999 --- /dev/null +++ b/exercises/ex0/README.md @@ -0,0 +1,15 @@ +# Preparation + +Let's start the excercise and see whether everything is ready to go. +Please make sure you have all the necessary prerequsistes listed below. If not, please raise your voice during the meeting so that we can assist you early in the session. + +## Prerequisites + +1. Installation of the ABAP Development Tools (ADT): Go to [this tutorial](https://developers.sap.com/tutorials/abap-install-adt.html) and carry out the steps of "Install ABAP Development Tools (ADT)", you don't need to do the "Install abapGit plugin" part. +1. Logon to the SAP Build Lobby https://lcapteched.eu10.build.cloud.sap/lobby using a browser, preferably Google Chrome +1. Your user is provided to you by the hosts of this session +1. Your password is also provided by the host of this session +1. **In almost every chapter of this tutorial there is a reference to a number ###, so a 3 digit number. Make sure that this number was assigend to you by the moderators / speakers of this course and remember it well.** It is important as we will use these numbers, where every user has a different one, in order to create different names for applications and other artefact. As we will deploy all the the artefacts to the same Business Technology Platform account, it is important that they all differ in the names and identifiers, so there are no clashes +1. **If you don't have access to the lobby with your user and password or if you don't know your number, please let the speakers know.** + +Continue to - [the ABAP part](../rap/README.md) diff --git a/exercises/rap/README.md b/exercises/rap/README.md new file mode 100644 index 0000000..81efadc --- /dev/null +++ b/exercises/rap/README.md @@ -0,0 +1,100 @@ + # Use ABAP Cloud for SAP S/4HANA (Cloud) extensions + + + + + + + +## Overview + + +**ABAP Cloud** +… is the ABAP development model to build cloud-ready business apps, services and extensions +… comes with SAP BTP and SAP S/4HANA +… works with public or private cloud, and even on-premise + +This hands-on workshop will guide you to build developer extensions using *ABAP Cloud* in an SAP S/4HANA system using RAP facades. + +A RAP facade is a *released* business object interface built with the ABAP RESTful Application Programming Model (RAP). + +You will create your own transactional Fiori elements app with the ABAP RESTful Application Programming Model (RAP) and use released RAP facades to enhance the existing functionality. + +### Business Scenario + + The scenario we will implement will be an online shop for employees which will allow for the creation of *Purchase Requisitions* by using a released RAP facade from Procurements. + + - An existing customer/partner wants to create a new business application that will allow employees of a company to order certain articles such as laptops for quick delivery using this shopping app. This can be realized with the ABAP RESTful Application Programming Model (RAP). + + - You’ll build the application starting from a database table using an ADT wizard that generates a starter project wich contains all the needed development RAP artefacts that have to be implemented. The generated business service will be transactional, draft-enabled, and enriched with UI semantics for the generation of the Fiori elements app. + + + + + +### Architecture Overview + + +The figure below illustrates the high-level architecture components of the cloud extensibility model used in SAP S/4HANA public Cloud, SAP S/4HANA private cloud and SAP S/4HANA on premise systems. + + ![architecture](images/100_SAP_S4_HANA_Extensibility_Patterns.png) + + +## Exercises + + + +| Exercises | +| ------------- | +| [How to connect with ADT to your SAP S/4HANA system](exercises/ex99/README.md) | +| [Exercise 1: Create an ABAP Package](exercises/ex1/README.md) | +| [Exercise 2: Create the OnlineShop Application](exercises/ex2/README.md) | +| [Exercise 3: Adapt the data model](exercises/ex3/README.md) | +| [Exercise 4: Create a Web API for the Onlineshop](exercises/ex4/README.md) | + +Continue to - [How to connect with ADT to your SAP S/4HANA system](exercises/ex99/README.md) + +## How to obtain support + +Support for the content in this repository is available during the actual time of the on-site workshop or online session for which this content has been designed. Otherwise, you may request support via the [Issues](../../../../issues) tab. + + +## Further Information + +- [Getting Started with the ABAP RESTful Application Programming Model (RAP)](https://blogs.sap.com/2019/10/25/getting-started-with-the-abap-restful-programming-model/) +- [ABAP @SAP Community](https://community.sap.com/topics/abap) + +## License +Copyright (c) 2022 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, version 2.0 except as noted otherwise in the [LICENSE](LICENSES/Apache-2.0.txt) file. diff --git a/exercises/rap/READMEOLD.md b/exercises/rap/READMEOLD.md new file mode 100644 index 0000000..2aa8a47 --- /dev/null +++ b/exercises/rap/READMEOLD.md @@ -0,0 +1,101 @@ + # Use ABAP Cloud for SAP S/4HANA (Cloud) extensions + + + +This repository contains the material for the hands-on session **Use ABAP Cloud for SAP S/4HANA (Cloud) extensions**. + + + + + +## Overview + + +**ABAP Cloud** +… is the ABAP development model to build cloud-ready business apps, services and extensions +… comes with SAP BTP and SAP S/4HANA +… works with public or private cloud, and even on-premise + +This hands-on workshop will guide you to build developer extensions using *ABAP Cloud* in an SAP S/4HANA system using RAP facades. + +A RAP facade is a *released* business object interface built with the ABAP RESTful Application Programming Model (RAP). + +You will create your own transactional Fiori elements app with the ABAP RESTful Application Programming Model (RAP) and use released RAP facades to enhance the existing functionality. + +### Business Scenario + + The scenario we will implement will be an online shop for employees which will allow for the creation of *Purchase Requisitions* by using a released RAP facade from Procurements. + + - An existing customer/partner wants to create a new business application that will allow employees of a company to order certain articles such as laptops for quick delivery using this shopping app. This can be realized with the ABAP RESTful Application Programming Model(RAP). + + - You’ll build the application starting from a database table using an ADT wizard that generates a starter project wich contains all the needed development RAP artefacts that have to be implemented. The generated business service will be transactional, draft-enabled, and enriched with UI semantics for the generation of the Fiori elements app. + + - Now, the customer/partner wishes to enhance the existing online shop application. After an order for a laptop is placed, it should be possible to initiate a purchase requisition for this order in the SAP S/4HANA system. Using the developer extensibility custom code can be added to the existing business logic of the online shop BO to fulfill this requirementand by calling the released RAP facade **I_PurchaseRequisitionTP** locally. + +Your application will finally look like this: + + ![List Report Page](images/Online_Shop_List_Report_Page.png) + + ![Object Page](images/Online_Shop_OBject_Page.png) + + +### Architecture Overview + + +The figure below illustrates the high-level architecture components of the cloud extensibility model used in SAP S/4HANA public Cloud, SAP S/4HANA private cloud and SAP S/4HANA on premise systems. + + ![architecture](images/100_SAP_S4_HANA_Extensibility_Patterns.png) + + +## Exercises + + + +| Exercises | +| ------------- | +| [How to connect with ADT to your SAP S/4HANA system](exercises/ex99/README.md) | +| [Exercise 1: Create an ABAP class with a released RAP Busindess Object](exercises/ex1/README.md) | +| [Exercise 2: Create the OnlineShop Application](exercises/ex2/README.md) | +| [Exercise 3: Adapt the data model](exercises/ex3/README.md) | +| [Exercise 4: Developer extensibility](exercises/ex4/README.md) | + +Continue to - [How to connect with ADT to your SAP S/4HANA system](exercises/ex99/README.md) + +## How to obtain support + +Support for the content in this repository is available during the actual time of the on-site workshop or online session for which this content has been designed. Otherwise, you may request support via the [Issues](../../../../issues) tab. + + +## Further Information + + +You can find further information on the different topics here: +- [SAP S/4HANA Cloud ABAP Environment](https://www.sap.com/about/events/teched-news-guide/composable-enterprise-solutions.html) +- [New ABAP Platform Extensibility Options for SAP S/4HANA](https://blogs.sap.com/2021/11/19/new-abap-platform-extensibility-options-in-2021/) +- [Getting Started with the ABAP RESTful Application Programming Model (RAP)](https://blogs.sap.com/2019/10/25/getting-started-with-the-abap-restful-programming-model/) +- [ABAP Extensibility Topic Page @SAP Community](https://community.sap.com/topics/abap-extensibility) + +## License +Copyright (c) 2022 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, version 2.0 except as noted otherwise in the [LICENSE](LICENSES/Apache-2.0.txt) file. diff --git a/exercises/rap/exercises/ex1/README.md b/exercises/rap/exercises/ex1/README.md new file mode 100644 index 0000000..07c9ca3 --- /dev/null +++ b/exercises/rap/exercises/ex1/README.md @@ -0,0 +1,187 @@ +[Home ](../../README.md) + +# Exercise 1: Create an ABAP Package + +## Introduction + +In this exercise, you will create your exercise package and add an appropriate *ABAP repository tree* to the *Project Explorer* in your ADT. + + +> **Reminder:** +> Don't forget to replace all occurences of the placeholder **`###`** with your group ID in the exercise steps below. +> You can use the ADT function **Replace All** (**Ctrl+F**) for the purpose. +> If you don't have a group ID yet, please check with your instructor. + +## Exercise 1.1: Create Package with language version ABAP for Cloud Development + +> Create your exercise package ![package](../../images/adt_package.png). +> This ABAP package will contain all the artefacts you will be creating in the different exercises of this hands-on session. + + + + + + + + 1. In ADT, again the **Project Explorer** right-click on the package **`ZLOCAL`**, and select **New** > **ABAP Package** from the context menu. + + ![package](images/220_create_package.png) + + + 2. Maintain the required information (`###` is your group ID): + - Name: **`Z_ONLINESHOP_###`** + - Description: _**`Online Shop ###`**_ + - Select the box **Add to favorites package** + + Click **Next >**. + + ![package](images/230_create_package.png). + + 3. Do not enter an Application Component and press **Next** + + ![package](images/240_create_package.png). + + 4. Create a new transport request, maintain a description (e.g. _**Online Shop Package ###**_), and click **Finish**. + + ![package](images/250_create_package.png). + + 5. You should now see your new package in your **Project Explorer**. + + ![package](images/270_create_package.png) + + 6. Check the language version of your package + + As you can see your package has the superpackage `ZLOCAL`. This is a structure package that is part of the software component `ZLOCAL` which is configured for the use of **ABAP for Cloud Development** and the **Local Objects**. + + ![package](images/280_create_package.png). + + + + + + + +You have now created an ABAP package that has ABAP language version *ABAP for Cloud Development*. + +Continue with the next exercise - **[Exercise 2: Create the OnlineShop Application](../ex2/#readme)** diff --git a/exercises/rap/exercises/ex1/images/200_create_package.png b/exercises/rap/exercises/ex1/images/200_create_package.png new file mode 100644 index 0000000..b46c2c7 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/200_create_package.png differ diff --git a/exercises/rap/exercises/ex1/images/210_create_package.png b/exercises/rap/exercises/ex1/images/210_create_package.png new file mode 100644 index 0000000..8acaa29 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/210_create_package.png differ diff --git a/exercises/rap/exercises/ex1/images/220_create_package.png b/exercises/rap/exercises/ex1/images/220_create_package.png new file mode 100644 index 0000000..5ae1903 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/220_create_package.png differ diff --git a/exercises/rap/exercises/ex1/images/230_create_package.png b/exercises/rap/exercises/ex1/images/230_create_package.png new file mode 100644 index 0000000..60ab777 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/230_create_package.png differ diff --git a/exercises/rap/exercises/ex1/images/240_create_package.png b/exercises/rap/exercises/ex1/images/240_create_package.png new file mode 100644 index 0000000..7eaea0c Binary files /dev/null and b/exercises/rap/exercises/ex1/images/240_create_package.png differ diff --git a/exercises/rap/exercises/ex1/images/250_create_package.png b/exercises/rap/exercises/ex1/images/250_create_package.png new file mode 100644 index 0000000..2f8fc75 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/250_create_package.png differ diff --git a/exercises/rap/exercises/ex1/images/260_create_package.png b/exercises/rap/exercises/ex1/images/260_create_package.png new file mode 100644 index 0000000..761423d Binary files /dev/null and b/exercises/rap/exercises/ex1/images/260_create_package.png differ diff --git a/exercises/rap/exercises/ex1/images/270_create_package.png b/exercises/rap/exercises/ex1/images/270_create_package.png new file mode 100644 index 0000000..517ebe0 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/270_create_package.png differ diff --git a/exercises/rap/exercises/ex1/images/280_create_package.png b/exercises/rap/exercises/ex1/images/280_create_package.png new file mode 100644 index 0000000..f8723f4 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/280_create_package.png differ diff --git a/exercises/rap/exercises/ex1/images/300_new_class.png b/exercises/rap/exercises/ex1/images/300_new_class.png new file mode 100644 index 0000000..dfe959e Binary files /dev/null and b/exercises/rap/exercises/ex1/images/300_new_class.png differ diff --git a/exercises/rap/exercises/ex1/images/310_new_class.png b/exercises/rap/exercises/ex1/images/310_new_class.png new file mode 100644 index 0000000..62b8b50 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/310_new_class.png differ diff --git a/exercises/rap/exercises/ex1/images/320_new_class.png b/exercises/rap/exercises/ex1/images/320_new_class.png new file mode 100644 index 0000000..0079bd7 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/320_new_class.png differ diff --git a/exercises/rap/exercises/ex1/images/330_new_class.png b/exercises/rap/exercises/ex1/images/330_new_class.png new file mode 100644 index 0000000..d8d7529 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/330_new_class.png differ diff --git a/exercises/rap/exercises/ex1/images/330_new_class_a.png b/exercises/rap/exercises/ex1/images/330_new_class_a.png new file mode 100644 index 0000000..9df9d94 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/330_new_class_a.png differ diff --git a/exercises/rap/exercises/ex1/images/340_new_class.png b/exercises/rap/exercises/ex1/images/340_new_class.png new file mode 100644 index 0000000..03b5f17 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/340_new_class.png differ diff --git a/exercises/rap/exercises/ex1/images/340_new_class_a.png b/exercises/rap/exercises/ex1/images/340_new_class_a.png new file mode 100644 index 0000000..d15362f Binary files /dev/null and b/exercises/rap/exercises/ex1/images/340_new_class_a.png differ diff --git a/exercises/rap/exercises/ex1/images/400_abap_repository_tree.png b/exercises/rap/exercises/ex1/images/400_abap_repository_tree.png new file mode 100644 index 0000000..3530301 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/400_abap_repository_tree.png differ diff --git a/exercises/rap/exercises/ex1/images/410_abap_repository_tree.png b/exercises/rap/exercises/ex1/images/410_abap_repository_tree.png new file mode 100644 index 0000000..6d8f56d Binary files /dev/null and b/exercises/rap/exercises/ex1/images/410_abap_repository_tree.png differ diff --git a/exercises/rap/exercises/ex1/images/420_abap_repository_tree.gif b/exercises/rap/exercises/ex1/images/420_abap_repository_tree.gif new file mode 100644 index 0000000..176eb08 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/420_abap_repository_tree.gif differ diff --git a/exercises/rap/exercises/ex1/images/420_abap_repository_tree.png b/exercises/rap/exercises/ex1/images/420_abap_repository_tree.png new file mode 100644 index 0000000..ce9b182 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/420_abap_repository_tree.png differ diff --git a/exercises/rap/exercises/ex1/images/430_abap_repository_tree.png b/exercises/rap/exercises/ex1/images/430_abap_repository_tree.png new file mode 100644 index 0000000..6bcb7a3 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/430_abap_repository_tree.png differ diff --git a/exercises/rap/exercises/ex1/images/440_abap_repository_tree.png b/exercises/rap/exercises/ex1/images/440_abap_repository_tree.png new file mode 100644 index 0000000..694f3f3 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/440_abap_repository_tree.png differ diff --git a/exercises/rap/exercises/ex1/images/450_abap_repository_tree.png b/exercises/rap/exercises/ex1/images/450_abap_repository_tree.png new file mode 100644 index 0000000..3f591e7 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/450_abap_repository_tree.png differ diff --git a/exercises/rap/exercises/ex1/images/460_abap_repository_tree.png b/exercises/rap/exercises/ex1/images/460_abap_repository_tree.png new file mode 100644 index 0000000..5b139b9 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/460_abap_repository_tree.png differ diff --git a/exercises/rap/exercises/ex1/images/470_abap_repository_tree.png b/exercises/rap/exercises/ex1/images/470_abap_repository_tree.png new file mode 100644 index 0000000..232f5fc Binary files /dev/null and b/exercises/rap/exercises/ex1/images/470_abap_repository_tree.png differ diff --git a/exercises/rap/exercises/ex1/images/480_abap_repository_tree.png b/exercises/rap/exercises/ex1/images/480_abap_repository_tree.png new file mode 100644 index 0000000..e7dada5 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/480_abap_repository_tree.png differ diff --git a/exercises/rap/exercises/ex1/images/490_abap_repository_tree.png b/exercises/rap/exercises/ex1/images/490_abap_repository_tree.png new file mode 100644 index 0000000..905dcad Binary files /dev/null and b/exercises/rap/exercises/ex1/images/490_abap_repository_tree.png differ diff --git a/exercises/rap/exercises/ex1/images/495_abap_repository_tree.png b/exercises/rap/exercises/ex1/images/495_abap_repository_tree.png new file mode 100644 index 0000000..42d0887 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/495_abap_repository_tree.png differ diff --git a/exercises/rap/exercises/ex1/images/500_check_documentation.png b/exercises/rap/exercises/ex1/images/500_check_documentation.png new file mode 100644 index 0000000..0101619 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/500_check_documentation.png differ diff --git a/exercises/rap/exercises/ex1/images/510_check_documentation.png b/exercises/rap/exercises/ex1/images/510_check_documentation.png new file mode 100644 index 0000000..9c0f285 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/510_check_documentation.png differ diff --git a/exercises/rap/exercises/ex1/images/520_check_documentation.gif b/exercises/rap/exercises/ex1/images/520_check_documentation.gif new file mode 100644 index 0000000..5ce281b Binary files /dev/null and b/exercises/rap/exercises/ex1/images/520_check_documentation.gif differ diff --git a/exercises/rap/exercises/ex1/images/530_check_documentation.png b/exercises/rap/exercises/ex1/images/530_check_documentation.png new file mode 100644 index 0000000..9178cf4 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/530_check_documentation.png differ diff --git a/exercises/rap/exercises/ex1/images/600_develop_test_class.png b/exercises/rap/exercises/ex1/images/600_develop_test_class.png new file mode 100644 index 0000000..476357a Binary files /dev/null and b/exercises/rap/exercises/ex1/images/600_develop_test_class.png differ diff --git a/exercises/rap/exercises/ex1/images/605_develop_test_class.png b/exercises/rap/exercises/ex1/images/605_develop_test_class.png new file mode 100644 index 0000000..52795a7 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/605_develop_test_class.png differ diff --git a/exercises/rap/exercises/ex1/images/610_develop_test_class.png b/exercises/rap/exercises/ex1/images/610_develop_test_class.png new file mode 100644 index 0000000..0aeebe8 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/610_develop_test_class.png differ diff --git a/exercises/rap/exercises/ex1/images/800_use_sap_note_and_github.png b/exercises/rap/exercises/ex1/images/800_use_sap_note_and_github.png new file mode 100644 index 0000000..89a7aaf Binary files /dev/null and b/exercises/rap/exercises/ex1/images/800_use_sap_note_and_github.png differ diff --git a/exercises/rap/exercises/ex1/images/810_use_sap_note_and_github.png b/exercises/rap/exercises/ex1/images/810_use_sap_note_and_github.png new file mode 100644 index 0000000..f32c3f5 Binary files /dev/null and b/exercises/rap/exercises/ex1/images/810_use_sap_note_and_github.png differ diff --git a/exercises/rap/exercises/ex1/sources/main_test_class.txt b/exercises/rap/exercises/ex1/sources/main_test_class.txt new file mode 100644 index 0000000..b7624d5 --- /dev/null +++ b/exercises/rap/exercises/ex1/sources/main_test_class.txt @@ -0,0 +1,168 @@ +METHOD if_oo_adt_classrun~main. + + + DATA: purchase_requisitions TYPE TABLE FOR CREATE I_PurchaserequisitionTP, + purchase_requisition TYPE STRUCTURE FOR CREATE I_PurchaserequisitionTP, + purchase_requisition_items TYPE TABLE FOR CREATE i_purchaserequisitionTP\_PurchaseRequisitionItem, + purchase_requisition_item TYPE STRUCTURE FOR CREATE i_purchaserequisitiontp\\purchaserequisition\_purchaserequisitionitem, + purchase_reqn_acct_assgmts TYPE TABLE FOR CREATE I_PurchaseReqnItemTP\_PurchaseReqnAcctAssgmt, + purchase_reqn_acct_assgmt TYPE STRUCTURE FOR CREATE I_PurchaseReqnItemTP\_PurchaseReqnAcctAssgmt, + purchase_reqn_item_texts TYPE TABLE FOR CREATE I_PurchaseReqnItemTP\_PurchaseReqnItemText, + purchase_reqn_item_text TYPE STRUCTURE FOR CREATE I_PurchaseReqnItemTP\_PurchaseReqnItemText, + delivery_date TYPE I_PurchaseReqnItemTP-DeliveryDate. + + delivery_date = cl_abap_context_info=>get_system_date( ) + 14. + + DATA n TYPE i. + + n += 1. + "purchase requisition + purchase_requisition = VALUE #( %cid = |My%CID_{ n }| + purchaserequisitiontype = 'NB' + PurReqnDescription = CONV string( cl_abap_context_info=>get_system_time( ) ) ) . + APPEND purchase_requisition TO purchase_requisitions. + + "purchase requisition item + purchase_requisition_item = VALUE #( + %cid_ref = |My%CID_{ n }| + %target = VALUE #( ( + + +**"Printer Professional +* %cid = 'My%ItemCID_1' +* plant = '1010' +* purchaserequisitionitemtext = 'Test Released APIs' +* accountassignmentcategory = 'U' +* requestedquantity = n +** baseunit = 'EA' +* purchaserequisitionprice = '10.00' +* purreqnitemcurrency = 'EUR' +* materialgroup = 'L001' +* purchasinggroup = '001' +* purchasingorganization = '1010' +* DeliveryDate = Delivery_Date +* Material = 'ZPRINTER01' + +**"Printer Platinum + +* %cid = 'My%ItemCID_1' +* plant = '1010' +* purchaserequisitionitemtext = 'Test Released APIs' +* accountassignmentcategory = 'U' +* requestedquantity = n +** baseunit = 'EA' +* purchaserequisitionprice = '10.00' +* purreqnitemcurrency = 'EUR' +* materialgroup = 'L001' +* purchasinggroup = '001' +* purchasingorganization = '1010' +* DeliveryDate = Delivery_Date +* Material = 'ZPRINTER02' + + +** Mobile Phone + + %cid = 'My%ItemCID_1' + plant = '1010' + purchaserequisitionitemtext = 'Test Released APIs' + accountassignmentcategory = 'U' + requestedquantity = n +* baseunit = 'EA' + purchaserequisitionprice = '178.00' + purreqnitemcurrency = 'EUR' + materialgroup = 'A001' + purchasinggroup = '001' + purchasingorganization = '1010' + DeliveryDate = Delivery_Date + Material = 'D001' + + + ) ) ). + APPEND purchase_requisition_item TO purchase_requisition_items. + + "purchase requisition account assignment + purchase_reqn_acct_assgmt = VALUE #( + %cid_ref = |My%ItemCID_{ n }| + %target = VALUE #( ( + %cid = |My%AccntCID_{ n }| + CostCenter = 'JMW-COST' + GLAccount = '0000400000' ) ) ) . + APPEND purchase_reqn_acct_assgmt TO purchase_reqn_acct_assgmts . + + "purchase requisition item text + purchase_reqn_item_text = VALUE #( + %cid_ref = |My%ItemCID_{ n }| + %target = VALUE #( ( + %cid = |My%TextCID_{ n }| + textobjecttype = 'B01' + language = 'E' + plainlongtext = 'Commandline test via F9' + ) ) ) . + APPEND purchase_reqn_item_text TO purchase_reqn_item_texts. + + + "EML deep create statement + + "purchase reqn + MODIFY ENTITIES OF i_purchaserequisitiontp ENTITY purchaserequisition + CREATE FIELDS ( purchaserequisitiontype PurReqnDescription ) + WITH purchase_requisitions + "purchase reqn item + CREATE BY \_purchaserequisitionitem + FIELDS ( plant +* purchaserequisitionitemtext "product description of the selected material will be used + accountassignmentcategory + requestedquantity + baseunit + purchaserequisitionprice + purreqnitemcurrency + Material + materialgroup + purchasinggroup + purchasingorganization + DeliveryDate + ) + WITH purchase_requisition_items + "purchase reqn account assignment + ENTITY purchaserequisitionitem + + CREATE BY \_purchasereqnacctassgmt + FIELDS ( CostCenter + GLAccount + Quantity +* BaseUnit + ) + WITH purchase_reqn_acct_assgmts + "purchase reqn item text + CREATE BY \_purchasereqnitemtext + FIELDS ( plainlongtext ) + WITH purchase_reqn_item_texts + + REPORTED DATA(reported) + MAPPED DATA(mapped) + FAILED DATA(failed). + + LOOP AT mapped-purchaserequisition INTO DATA(mapped_pr). + out->write( |{ mapped_pr-%pid }| ). + ENDLOOP. + + COMMIT ENTITIES + BEGIN RESPONSE OF i_purchaserequisitiontp + FAILED DATA(failed_late) + REPORTED DATA(reported_late). + + LOOP AT mapped-purchaserequisition ASSIGNING FIELD-SYMBOL(). + CONVERT KEY OF i_purchaserequisitiontp FROM -%pid TO DATA(ls_ctr). + -PurchaseRequisition = ls_ctr-PurchaseRequisition. + ENDLOOP. + + IF sy-subrc = 0. + out->write( | PurchaseRequisition: { ls_ctr-PurchaseRequisition } | ). + ELSE. + out->write( | Error PurchaseRequisition sy-subrc: { sy-subrc } | ). + ENDIF. + + COMMIT ENTITIES END. + + + ENDMETHOD. diff --git a/exercises/rap/exercises/ex1/sources/zcl_test_i_purchase_req_###.txt b/exercises/rap/exercises/ex1/sources/zcl_test_i_purchase_req_###.txt new file mode 100644 index 0000000..05ce6d3 --- /dev/null +++ b/exercises/rap/exercises/ex1/sources/zcl_test_i_purchase_req_###.txt @@ -0,0 +1,186 @@ +CLASS zcl_test_i_purchase_req_### DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + + INTERFACES if_oo_adt_classrun . + PROTECTED SECTION. + PRIVATE SECTION. +ENDCLASS. + + + +CLASS zcl_test_i_purchase_req_### IMPLEMENTATION. + +METHOD if_oo_adt_classrun~main. + + + DATA: purchase_requisitions TYPE TABLE FOR CREATE I_PurchaserequisitionTP, + purchase_requisition TYPE STRUCTURE FOR CREATE I_PurchaserequisitionTP, + purchase_requisition_items TYPE TABLE FOR CREATE i_purchaserequisitionTP\_PurchaseRequisitionItem, + purchase_requisition_item TYPE STRUCTURE FOR CREATE i_purchaserequisitiontp\\purchaserequisition\_purchaserequisitionitem, + purchase_reqn_acct_assgmts TYPE TABLE FOR CREATE I_PurchaseReqnItemTP\_PurchaseReqnAcctAssgmt, + purchase_reqn_acct_assgmt TYPE STRUCTURE FOR CREATE I_PurchaseReqnItemTP\_PurchaseReqnAcctAssgmt, + purchase_reqn_item_texts TYPE TABLE FOR CREATE I_PurchaseReqnItemTP\_PurchaseReqnItemText, + purchase_reqn_item_text TYPE STRUCTURE FOR CREATE I_PurchaseReqnItemTP\_PurchaseReqnItemText, + delivery_date TYPE I_PurchaseReqnItemTP-DeliveryDate. + + delivery_date = cl_abap_context_info=>get_system_date( ) + 14. + + DATA n TYPE i. + + n += 1. + "purchase requisition + purchase_requisition = VALUE #( %cid = |My%CID_{ n }| + purchaserequisitiontype = 'NB' + PurReqnDescription = CONV string( cl_abap_context_info=>get_system_time( ) ) ) . + APPEND purchase_requisition TO purchase_requisitions. + + "purchase requisition item + purchase_requisition_item = VALUE #( + %cid_ref = |My%CID_{ n }| + %target = VALUE #( ( + + +**"Printer Professional +* %cid = 'My%ItemCID_1' +* plant = '1010' +* purchaserequisitionitemtext = 'Test Released APIs' +* accountassignmentcategory = 'U' +* requestedquantity = n +** baseunit = 'EA' +* purchaserequisitionprice = '10.00' +* purreqnitemcurrency = 'EUR' +* materialgroup = 'L001' +* purchasinggroup = '001' +* purchasingorganization = '1010' +* DeliveryDate = Delivery_Date +* Material = 'ZPRINTER01' + +**"Printer Platinum + +* %cid = 'My%ItemCID_1' +* plant = '1010' +* purchaserequisitionitemtext = 'Test Released APIs' +* accountassignmentcategory = 'U' +* requestedquantity = n +** baseunit = 'EA' +* purchaserequisitionprice = '10.00' +* purreqnitemcurrency = 'EUR' +* materialgroup = 'L001' +* purchasinggroup = '001' +* purchasingorganization = '1010' +* DeliveryDate = Delivery_Date +* Material = 'ZPRINTER02' + + +** Mobile Phone + + %cid = 'My%ItemCID_1' + plant = '1010' + purchaserequisitionitemtext = 'Test Released APIs' + accountassignmentcategory = 'U' + requestedquantity = n +* baseunit = 'EA' + purchaserequisitionprice = '178.00' + purreqnitemcurrency = 'EUR' + materialgroup = 'A001' + purchasinggroup = '001' + purchasingorganization = '1010' + DeliveryDate = Delivery_Date + Material = 'D001' + + + ) ) ). + APPEND purchase_requisition_item TO purchase_requisition_items. + + "purchase requisition account assignment + purchase_reqn_acct_assgmt = VALUE #( + %cid_ref = |My%ItemCID_{ n }| + %target = VALUE #( ( + %cid = |My%AccntCID_{ n }| + CostCenter = 'JMW-COST' + GLAccount = '0000400000' ) ) ) . + APPEND purchase_reqn_acct_assgmt TO purchase_reqn_acct_assgmts . + + "purchase requisition item text + purchase_reqn_item_text = VALUE #( + %cid_ref = |My%ItemCID_{ n }| + %target = VALUE #( ( + %cid = |My%TextCID_{ n }| + textobjecttype = 'B01' + language = 'E' + plainlongtext = 'Commandline test via F9' + ) ) ) . + APPEND purchase_reqn_item_text TO purchase_reqn_item_texts. + + + "EML deep create statement + + "purchase reqn + MODIFY ENTITIES OF i_purchaserequisitiontp ENTITY purchaserequisition + CREATE FIELDS ( purchaserequisitiontype PurReqnDescription ) + WITH purchase_requisitions + "purchase reqn item + CREATE BY \_purchaserequisitionitem + FIELDS ( plant +* purchaserequisitionitemtext "product description of the selected material will be used + accountassignmentcategory + requestedquantity + baseunit + purchaserequisitionprice + purreqnitemcurrency + Material + materialgroup + purchasinggroup + purchasingorganization + DeliveryDate + ) + WITH purchase_requisition_items + "purchase reqn account assignment + ENTITY purchaserequisitionitem + + CREATE BY \_purchasereqnacctassgmt + FIELDS ( CostCenter + GLAccount + Quantity +* BaseUnit + ) + WITH purchase_reqn_acct_assgmts + "purchase reqn item text + CREATE BY \_purchasereqnitemtext + FIELDS ( plainlongtext ) + WITH purchase_reqn_item_texts + + REPORTED DATA(reported) + MAPPED DATA(mapped) + FAILED DATA(failed). + + LOOP AT mapped-purchaserequisition INTO DATA(mapped_pr). + out->write( |{ mapped_pr-%pid }| ). + ENDLOOP. + + COMMIT ENTITIES + BEGIN RESPONSE OF i_purchaserequisitiontp + FAILED DATA(failed_late) + REPORTED DATA(reported_late). + + LOOP AT mapped-purchaserequisition ASSIGNING FIELD-SYMBOL(). + CONVERT KEY OF i_purchaserequisitiontp FROM -%pid TO DATA(ls_ctr). + -PurchaseRequisition = ls_ctr-PurchaseRequisition. + ENDLOOP. + + IF sy-subrc = 0. + out->write( | PurchaseRequisition: { ls_ctr-PurchaseRequisition } | ). + ELSE. + out->write( | Error PurchaseRequisition sy-subrc: { sy-subrc } | ). + ENDIF. + COMMIT ENTITIES END. + + + ENDMETHOD. + + +ENDCLASS. diff --git a/exercises/rap/exercises/ex2/README.md b/exercises/rap/exercises/ex2/README.md new file mode 100644 index 0000000..3ebddb8 --- /dev/null +++ b/exercises/rap/exercises/ex2/README.md @@ -0,0 +1,214 @@ +[Home ](../../README.md) + +# Exercise 2: Create the OnlineShop Application + +## Introduction + +In this exercise, you will use the package `Z_ONLINESHOP_###`that you have created earlier. +Here you will create a database table where you will define all important fields for the OnlineShop application. + +This RAP business object (BO) represents an online shop, where you can order laptops or other articles you need as an employee. + +We will start our implementation by building a simple managed RAP business object and we will add the business logic to call the released RAP API in SAP S/4HANA afterwards. + +You will use an ADT wizard to generate all the needed development RAP artefacts of your UI service. This includes the data model, projection view, service definition and service binding. Afterwards you will check your _OnlineShop_ application with the SAP Fiori elements preview. + +> **Reminder:** +> Don't forget to replace all occurences of the placeholder **`###`** with your group ID in the exercise steps below. +> You can use the ADT function **Replace All** (**Ctrl+F**) for the purpose. + + +## Exercise 2.1: Create database table + +Create a database table![table](../../images/adt_tabl.png) to store the _OnlineShop_ data. +A OnlineShop entity defines general data, such as the product name or the quantity that is ordered. Once the order is checked out the number of the purchase requisition that will be created by using our released API will be stored as well. + +> Hint: +> The tasks are also desribed in the following tutorial (step 2). Just replace the names with those that are mentioned in this how to guide. +> https://developers.sap.com/tutorials/abap-environment-rap100-generate-ui-service.html + + 1. Right-click on your ABAP package **`Z_ONLINESHOP_###`** and select **New** > **Other ABAP Repository Object** from the context menu. + + 2. Search for **database table**, select it, and click **Next >**. + + 3. Maintain the required information (`###` is your group ID) and click **Next >**. + - Name: **`ZONLINESHOP_###`** + - Description: _**`Persistence for online shop`**_ + + 4. Select your transport request, and click **Finish** to create the database table. + + 5. Replace the default code with the code snippet provided below and replace all occurences of the placeholder **`###`** with your group ID using the **Replace All** function (**Ctrl+F**). + + > **Hint**: Hover the code snippet and choose the _Copy raw contents_ icon table appearing in the upper-right corner to copy it. + +
+@EndUserText.label : 'Persistence for online shop'
+@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
+@AbapCatalog.tableCategory : #TRANSPARENT
+@AbapCatalog.deliveryClass : #A
+@AbapCatalog.dataMaintenance : #RESTRICTED
+define table zonlineshop_XXX {
+  key client            : abap.clnt not null;
+  key order_uuid        : sysuuid_x16 not null;
+  order_id              : abap.char(10) not null;
+  product               : abap.char(40) not null;
+  quantity              : abap.int4;
+  purchase_requisition  : abap.char(10);
+  overall_status        : abap.char(40);
+  created_by            : abp_creation_user;
+  created_at            : abp_creation_tstmpl;
+  last_changed_by       : abp_lastchange_user;
+  last_changed_at       : abp_lastchange_tstmpl;
+  local_last_changed_at : abp_locinst_lastchange_tstmpl;
+
+}
+
+ + 6. Save ![save icon](../../images/adt_save.png) and activate ![activate icon](../../images/adt_activate.png) the changes. + +## Exercise 2.2: Generate the transactional UI service + +Create your OData V4 based UI service with the built-in RAP generator. +The generated business service will be transactional, draft-enabled, and enriched with UI semantics for the generation of the Fiori elements app. + +> Hint: +> The tasks are also desribed in the following tutorial (step 2). Just replace the names with those that are mentioned in this how to guide. +> https://developers.sap.com/tutorials/abap-environment-rap100-generate-ui-service.html + + + 1. In the **Project Explorer** (**Dictionary**) right-click your database table ![table](../../images/adt_tabl.png)**`ZONLINESHOP_###`** and select **Generate ABAP Repository Objects** from the context menu. + + 2. Maintain the required information (`###` is your group ID) and click **Next >**: + - Generator: **`ABAP RESTful Application Programming Model: UI Service`** + + 3. Maintain the required information on the **Configure Generator** dialog to provide the name of your data model and generate them. + + For that, navigate through the wizard tree (_Business Objects_, _Data Model_, etc...), maintain the artefact names provided in the table below, + and press **Next >**. + + Verify the maintained entries and press **Next >** to confirm. + + > ℹ **Info about Naming Conventions** + > The main aspects of the naming conventions of SAP S/4HANA's Virtual Data Model (VDM) are used in this exercise. + > More information on VDM can be found on the SAP Help portal: **[Here](https://help.sap.com/docs/SAP_S4HANA_CLOUD/0f69f8fb28ac4bf48d2b57b9637e81fa/8a8cee943ef944fe8936f4cc60ba9bc1.html)**. + + + + | **RAP Layer** | **Artefacts** | **Artefact Names** | + |:---------------------- |:------------------------ |:-------------------------------------------------------- | + | **Business Object** | | | + | | **Data Model** | Data Definition Name: **`ZR_ONLINESHOP_###`** | + | | | Alias Name: **`onlineshop`** | + | | **Behavior** | Implementation Class: **`ZBP_R_ONLINESHOP_###`** | + | | | Draft Table Name: **`ZDONLINESHOP_###`** | + | **Service Projection** (BO Projection) | | Name: **`ZC_ONLINESHOP_###`** | + | **Business Services** | | | + | | **Service Definition** | Name: **`ZUI_ONLINESHOP_###`** | + | | **Service Binding** | Name: **`ZUI_ONLINESHOP_O4_###`** | + | | | Binding Type: **`OData V4 - UI`** | + + + 4. Select a transport request, and click **Finish**. The needed artefacts will be generated. + + 5. Go to the **Project Explorer**, select your package ![package](../../images/adt_package.png)**`Z_ONLINESHOP_###`**, refresh it by pressing **F5**, and check all generated ABAP repository objects + + + +## Exercise 2.3: Preview the OnlineShop App using Fiori elements + + +In this exercise you will publish the local service endpoint of your service binding ![service binding](../../images/adt_srvb.png) and start the _Fiori elements App Preview_. + + 1. Open your service binding ![service binding](../../images/adt_srvb.png)**`ZUI_ONLINESHOP_O4_###`** and click **Publish**. + + ![Publish](images/105_publish_service_binding_on_prem.png) + + 2. Double-click on the entity **`onlineshop`** in the **Entity Set and Association** section to open the _Fiori elements App Preview_. + + ![Preview](images/107_publish_service_binding_on_prem.png) + + 3. If prompted, sign in with the user and password provided by the instructors. You should see a Fiori elements application like this + + ![Fiori elements app](images/109_publish_service_binding_on_prem.png) + + + + + +## Summary + + +Now that you've... +- created an ABAP package, +- created a database table, +- created a transactional UI service, +- published a local service point, and started the _Fiori elements App Preview_ in ADT. + +You can continue with the next exercise - **[Exercise 3: Adapt the data model](../ex3/README.md)**. + + +--- + diff --git a/exercises/rap/exercises/ex2/images/100_error_publish_service_binding.png b/exercises/rap/exercises/ex2/images/100_error_publish_service_binding.png new file mode 100644 index 0000000..3fe52cf Binary files /dev/null and b/exercises/rap/exercises/ex2/images/100_error_publish_service_binding.png differ diff --git a/exercises/rap/exercises/ex2/images/100_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/100_publish_service_binding_on_prem.png new file mode 100644 index 0000000..5b8327a Binary files /dev/null and b/exercises/rap/exercises/ex2/images/100_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/105_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/105_publish_service_binding_on_prem.png new file mode 100644 index 0000000..a4df0ef Binary files /dev/null and b/exercises/rap/exercises/ex2/images/105_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/107_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/107_publish_service_binding_on_prem.png new file mode 100644 index 0000000..7aa753b Binary files /dev/null and b/exercises/rap/exercises/ex2/images/107_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/109_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/109_publish_service_binding_on_prem.png new file mode 100644 index 0000000..7141cd6 Binary files /dev/null and b/exercises/rap/exercises/ex2/images/109_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/110_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/110_publish_service_binding_on_prem.png new file mode 100644 index 0000000..20df3a8 Binary files /dev/null and b/exercises/rap/exercises/ex2/images/110_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/120_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/120_publish_service_binding_on_prem.png new file mode 100644 index 0000000..c55bb19 Binary files /dev/null and b/exercises/rap/exercises/ex2/images/120_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/130_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/130_publish_service_binding_on_prem.png new file mode 100644 index 0000000..729f393 Binary files /dev/null and b/exercises/rap/exercises/ex2/images/130_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/140_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/140_publish_service_binding_on_prem.png new file mode 100644 index 0000000..7e1f3c0 Binary files /dev/null and b/exercises/rap/exercises/ex2/images/140_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/150_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/150_publish_service_binding_on_prem.png new file mode 100644 index 0000000..8bb23f0 Binary files /dev/null and b/exercises/rap/exercises/ex2/images/150_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/160_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/160_publish_service_binding_on_prem.png new file mode 100644 index 0000000..33566c6 Binary files /dev/null and b/exercises/rap/exercises/ex2/images/160_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/170_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/170_publish_service_binding_on_prem.png new file mode 100644 index 0000000..3af68d6 Binary files /dev/null and b/exercises/rap/exercises/ex2/images/170_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/180_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/180_publish_service_binding_on_prem.png new file mode 100644 index 0000000..478a211 Binary files /dev/null and b/exercises/rap/exercises/ex2/images/180_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/190_publish_service_binding_on_prem.png b/exercises/rap/exercises/ex2/images/190_publish_service_binding_on_prem.png new file mode 100644 index 0000000..ca60f68 Binary files /dev/null and b/exercises/rap/exercises/ex2/images/190_publish_service_binding_on_prem.png differ diff --git a/exercises/rap/exercises/ex2/images/2023-05-07_20-03-05.png b/exercises/rap/exercises/ex2/images/2023-05-07_20-03-05.png new file mode 100644 index 0000000..6bd2b16 Binary files /dev/null and b/exercises/rap/exercises/ex2/images/2023-05-07_20-03-05.png differ diff --git a/exercises/rap/exercises/ex2/sources/ZI_PRODUCT_VH_REUSE.txt b/exercises/rap/exercises/ex2/sources/ZI_PRODUCT_VH_REUSE.txt new file mode 100644 index 0000000..d525151 --- /dev/null +++ b/exercises/rap/exercises/ex2/sources/ZI_PRODUCT_VH_REUSE.txt @@ -0,0 +1,57 @@ +@AbapCatalog.viewEnhancementCategory: [#NONE] +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Value Help for I_PRODUCT' +@Metadata.ignorePropagatedAnnotations: true +@ObjectModel.usageType:{ + serviceQuality: #X, + sizeCategory: #S, + dataClass: #MIXED +} +define view entity ZI_PRODUCT_VH_REUSE + as select from I_Product +{ + // @UI.lineItem: [{ position: 10, label: 'Product', importance: #HIGH }] + key Product as Product, + + // @UI.lineItem: [{ position: 20, label: 'Product Description', importance: #HIGH }] + _Text[1: Language=$session.system_language].ProductName as ProductText, + + // @UI.lineItem: [{ position: 30, label: 'Price', importance: #HIGH }] + @Semantics.amount.currencyCode: 'Currency' + case + when Product = 'ZPRINTER01' then cast ( 500.00 as abap.dec( 16, 2 ) ) + when Product = 'ZPRINTER02' then cast ( 300.00 as abap.dec( 16, 2 ) ) + when Product = 'D001' then cast ( 550.00 as abap.dec(16,2) ) //Mobile Phone + when Product = 'D002' then cast ( 499.00 as abap.dec(16,2) ) //Tablet PC +// when Product = 'D003' then cast ( 599.00 as abap.dec(16,2) ) //Apfel Pad + when Product = 'D004' then cast ( 49.00 as abap.dec(16,2) ) //Dingens + when Product = 'D005' then cast ( 150.00 as abap.dec(16,2) ) //Office Table +// when Product = 'D006' then cast ( 259.00 as abap.dec(16,2) ) //Office Chair + else cast ( 100000.00 as abap.dec(16,2) ) // :-) + end as Price, + + // @UI.lineItem: [{ position: 40, label: 'Product Group'}] + @UI.hidden: true + cast ( 'EUR' as abap.cuky( 5 ) ) as Currency, + + // @UI.lineItem: [{ position: 50, label: 'Product Group'] + @UI.hidden: true + ProductGroup as ProductGroup, + + // @UI.lineItem: [{ position: 60, label: 'Base Unit'}] + @UI.hidden: true + BaseUnit as BaseUnit + +} +where + Product = 'D001' + or Product = 'D002' +// or Product = 'D003' + or Product = 'D004' + or Product = 'D005' +// or Product = 'D006' + or Product = 'ZPRINTER01' + or Product = 'ZPRINTER02' + + + diff --git a/exercises/rap/exercises/ex2/sources/ZONLINESHOP_###.txt b/exercises/rap/exercises/ex2/sources/ZONLINESHOP_###.txt new file mode 100644 index 0000000..41e52ab --- /dev/null +++ b/exercises/rap/exercises/ex2/sources/ZONLINESHOP_###.txt @@ -0,0 +1,29 @@ +@EndUserText.label : 'Persistence for online shop' +@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE +@AbapCatalog.tableCategory : #TRANSPARENT +@AbapCatalog.deliveryClass : #A +@AbapCatalog.dataMaintenance : #RESTRICTED +define table zaonlineshop_### { + key client : abap.clnt not null; + key order_uuid : sysuuid_x16 not null; + order_id : abap.char(10) not null; + order_item_id : abap.char(40) not null; + @Semantics.amount.currencyCode : 'zaonlineshop_###.currency' + order_item_price : abap.curr(11,2); + order_item_quantity : abap.numc(4); + @Semantics.amount.currencyCode : 'zaonlineshop_###.currency' + total_price : abap.curr(11,2); + currency : abap.cuky; + overall_status : abap.char(30); + overall_status_indicator : abap.int1; + delivery_date : abap.dats; + notes : abap.string(256); + purchase_requisition : abap.char(20); + purch_rqn_creation_date : abap.dats; + created_by : abp_creation_user; + created_at : abp_creation_tstmpl; + last_changed_by : abp_lastchange_user; + last_changed_at : abp_lastchange_tstmpl; + local_last_changed_at : abp_locinst_lastchange_tstmpl; + +} diff --git a/exercises/rap/exercises/ex3/README.md b/exercises/rap/exercises/ex3/README.md new file mode 100644 index 0000000..4401fbf --- /dev/null +++ b/exercises/rap/exercises/ex3/README.md @@ -0,0 +1,629 @@ +[Home ](../../README.md) + +# Exercise 3: Adapt the data model + +## Introduction + +In this exercise, you will adapt the data model of the newly generated RAP business object `ZR_ONLINESHOP_###` + + + + + +## Exercise 3.1: Provide Metadata Extension for Fiori elements UI + +1. Replace the complete source code of the Metadata Extension File **ZC_ONLINESHOP_###**. + +![enhance_data_model](images/115_adapt_data_model.png) + + Replace the placeholder `###` with your group ID and save and activate your changes. + + +
+@Metadata.layer: #CORE
+@UI: {
+  headerInfo: {
+    typeName: 'onlineshop',
+    typeNamePlural: 'onlineshops'
+  }
+}
+annotate view ZC_ONLINESHOP_XXX with
+{
+  @UI.facet: [ {
+    id: 'idIdentification',
+    type: #IDENTIFICATION_REFERENCE,
+    label: 'onlineshop',
+    position: 10
+  } ]
+  @UI.hidden: true
+  orderuuid;
+
+  @UI.lineItem: [ {
+    position: 30 ,
+    label: 'Order ID' ,
+    importance: #MEDIUM
+  } ]
+  @UI.identification: [ {
+    label: 'Order ID',
+    position: 30
+  } ]
+  orderid;
+
+  @UI.lineItem: [ {
+    position: 10 ,
+    label: 'Product' ,
+    importance: #MEDIUM
+  } ]
+  @UI.identification: [ {
+    position: 10,
+    label: 'Product'
+  } ]
+  product;
+
+  @UI.lineItem: [ {
+    position: 20 ,
+    label: 'Quantity' ,
+    importance: #MEDIUM
+  } ]
+  @UI.identification: [ {
+    position: 20 ,
+    label: 'Quantity'
+  } ]
+  quantity;
+  
+  @UI.lineItem: [ {
+    position: 40 , 
+    label: 'PurchaseRequisition',
+    importance: #MEDIUM
+  } ]
+  @UI.identification: [ {
+    label: 'PurchaseRequisition',
+    position: 40 
+  } ]
+  purchaserequisition;
+  
+  @UI.lineItem: [ {
+    position: 50 , 
+    label: 'Overall Status',
+    importance: #MEDIUM
+  } ]
+  @UI.identification: [ {
+    label: 'Overall Status',
+    position: 50 
+  } ]
+  overallstatus;
+  
+  @UI.hidden: true
+  locallastchangedat;
+}
+
+ + This metadata extension file includes the annotations that tell the Fiori elements UI which columns should go into the result list and which fields group a form on the object page. While most of the code was already generated automatically, we now add a couple of labels to the column headers and for the form and change the order of fields a bit to make the form nicer (order is changed via the 'importance' annotation). + +2. Save ![save icon](../../images/adt_save.png) and activate ![activate icon](../../images/adt_activate.png) the changes. + + + +## Exercise 3.2: Adapt the behavior definition + + + +In the behavior definition we will also set several fields as read-only. + +For fields that are read-only and that are not read from the value help we have to create determinations. + + 1. Open the behavior definition `ZR_ONLINESHOP_###`. + + ![adapt_bdef](images/195_adapt_bdef.png) + + 2. Add the following list of fields to mark them as read-only +
+   OrderID,
+   PurchaseRequisition,
+   OverallStatus,
+  
+ + behind + +
+{
+  field ( readonly )
+   OrderUUID,
+  
+ + in order to make the Order ID a read-only field. + + ![adapt_bdef](images/220_adapt_bdef.png) + + 3. Save ![save icon](../../images/adt_save.png) and activate ![activate icon](../../images/adt_activate.png) the changes. + + 4. In the **Project Explorer** under `Business Services`->`Service Bindings`->`ZUI_ONLINESHOP_O4_###` check the UI using the Fiori Elements preview. + + On the list, press **Create** and you should see a form like this, where **Order ID**, **Purchase Requisition** and **Overall Status** are text not input fields: + + ![adapt_bdef](images/230_adapt_bdef.png) + + + +## Exercise 3.3: Define determinations + + + We now will create a determination which is called when a new online store entry is created. The determination will calculate a new Order ID. While the OrderUUID is generated automatically by the system upon save, the Order ID we have to generate ourselves. The corresponding code looks up the currently highest number for orders and then adds 1 for a new ID. + + 1. Add the following determination to your behavior definition **ZR_ONLINESHOP_###** (in the **Project Explorer** under **Core Data Services** -> **Behavior Definitions**) + +
+  determination CalculateOrderID on save { create; }
+  
+ + + ![define_determinations](images/300_define_determinations_1.png) + + 2. Save ![save icon](../../images/adt_save.png) and activate ![activate icon](../../images/adt_activate.png) the changes. + + 3. Use the quick fix **Ctrl+1** (**Command+1** on Mac) to generate the appropriate methods in the behavior definition class. + + ![define_determinations](images/310_define_determinations_1.png) + + 4. Then a new tab is openend with the generated handler that looks like this: + + ![define_determinations](images/312_define_determinations_1.png) + + 5. Add the code snippet to implement the method `CalculateOrderID` for the determination `createOrderID`. Replace +
+      METHOD CalculateOrderID.
+      ENDMETHOD.
+  
+ + with: + +
+  
+ METHOD CalculateOrderID.
+
+    "read transfered instances
+    READ ENTITIES OF ZR_OnlineShop_### IN LOCAL MODE
+      ENTITY OnlineShop
+        ALL FIELDS
+        WITH CORRESPONDING #( keys )
+      RESULT DATA(OnlineOrders).
+
+    "ignore  entries with assigned order ID
+    DELETE OnlineOrders WHERE OrderID IS NOT INITIAL.
+    IF OnlineOrders IS NOT INITIAL.
+      "get max order ID from the relevant active and draft table entries
+      SELECT FROM ZOnlineShop_### FIELDS MAX( order_id ) INTO @DATA(max_order_id). "active table
+      SELECT FROM ZdOnlineShop_### FIELDS MAX( orderid ) INTO @DATA(max_order_id_draft). "draft table
+
+      IF max_order_id_draft > max_order_id.
+        max_order_id = max_order_id_draft.
+      ENDIF.
+
+      DATA(OverallStatus) = |{ sy-uname } - is placing order request|.
+      MODIFY ENTITIES OF ZR_OnlineShop_### IN LOCAL MODE
+        ENTITY OnlineShop
+          UPDATE FIELDS ( OrderID OverallStatus )
+          WITH VALUE #( FOR order IN OnlineOrders INDEX INTO i (
+                           %tky          = order-%tky
+                           OrderID       = max_order_id + i
+                           OverallStatus = overallstatus
+                      ) )
+        FAILED DATA(failed).
+
+      MODIFY ENTITIES OF zr_onlineshop_### IN LOCAL MODE
+        ENTITY OnlineShop EXECUTE CreatePurchaseRequisition FROM CORRESPONDING #( keys ).
+    ENDIF.
+
+  ENDMETHOD.
+ 
+  
+ + 6. Replace the placeholder `###` with your group ID. + + The code reads all entries including the one that was just created. It looks at all the orders whether they already have an `OrderID`, it finds the order with the highest `OrderID`, assuming this is the newest. It adds 1 to the highest `OrderID` and assigns this new number to our new onlineshop record and modifies the database using EML ([Entity Manipulation Language](https://help.sap.com/docs/btp/sap-abap-restful-application-programming-model/entity-manipulation-language-eml)) + + 7. Save ![save icon](../../images/adt_save.png) the changes. The implementation of the internal action `CreatePurchaseRequisition` will be added in the next section. + + +## Exercise 3.4: Add an additonal internal action to create a Purchase Requisition + + +1. Add the following line to your behavior implementation `ZBP_R_ONLINESHOP_###` (in the project explorer under **Source Code Library** -> **Classes**, make sure to switch to the `Global Class` tab in the ADT editor) + +
+CLASS-DATA mapped_purchase_requisition TYPE RESPONSE FOR MAPPED i_purchaserequisitiontp.
+
+ +Add it below the `public section.` line, so it looks like this: + +
+  class ZBP_R_ONLINESHOP_### definition
+    public
+    abstract
+    final
+    for behavior of ZR_ONLINESHOP_###.
+
+  public section.
+      CLASS-DATA mapped_purchase_requisition TYPE RESPONSE FOR MAPPED i_purchaserequisitiontp.
+  protected section.
+  private section.
+  ENDCLASS.
+
+ +2. Save ![save icon](../../images/adt_save.png) the changes. + +3. Add the following internal action to your behavior definition **ZR_ONLINESHOP_###** (in the **Project Explorer** under **Core Data Services** -> **Behavior Definitions**) just behind the line for the calculation of the new order id, that you inserted before. + +
+  internal action CreatePurchaseRequisition result [1] $self;
+
+ + ![define_determinations](images/400_define_determinations_1.png) + +4. Save ![save icon](../../images/adt_save.png) the changes. + +5. Click on the icon on the left hand side of the new line and invoke the generation of the new method + + ![define_determinations](images/410_define_determinations_1.png) + +6. Replace + +
+  METHOD CreatePurchaseRequisition.
+  ENDMETHOD.
+
+ +with the following code: + +
+  METHOD CreatePurchaseRequisition.
+
+    DATA purchase_requisitions      TYPE TABLE FOR CREATE I_PurchaserequisitionTP.
+    DATA purchase_requisition_items TYPE TABLE FOR CREATE i_purchaserequisitionTP\_PurchaseRequisitionItem.
+    DATA purchase_reqn_acct_assgmts TYPE TABLE FOR CREATE I_PurchaseReqnItemTP\_PurchaseReqnAcctAssgmt.
+    DATA purchase_reqn_item_texts   TYPE TABLE FOR CREATE I_PurchaseReqnItemTP\_PurchaseReqnItemText.
+    DATA update_lines               TYPE TABLE FOR UPDATE zr_onlineshop_###\\OnlineShop.
+
+    "read transfered order instances
+    READ ENTITIES OF zr_onlineshop_### IN LOCAL MODE
+      ENTITY OnlineShop ALL FIELDS WITH CORRESPONDING #( keys )
+      RESULT DATA(OnlineOrders).
+
+    LOOP AT OnlineOrders INTO DATA(OnlineOrder).
+      DATA(n) = sy-tabix.
+
+      "purchase requisition
+      APPEND VALUE #( %cid                    = OnlineOrder-OrderUUID
+                      purchaserequisitiontype = 'NB' ) TO purchase_requisitions.
+
+      "purchase requisition item
+      APPEND VALUE #( %cid_ref = OnlineOrder-OrderUUID
+                      %target  = VALUE #( (
+                                   %cid                        = |My%ItemCID_{ n }|
+                                   plant                       = '1010'  "Plant 01 (DE)
+                                   accountassignmentcategory   = 'U'  "unknown
+*                                  PurchaseRequisitionItemText =      "retrieved automatically from maintained MaterialInfo
+                                   requestedquantity           = '1'
+                                   purchaserequisitionprice    = '100'
+                                   purreqnitemcurrency         = 'EUR'
+                                   Material                    = 'D001'
+                                   materialgroup               = 'A001'
+                                   purchasinggroup             = '001'
+                                   purchasingorganization      = '1010'
+                                   DeliveryDate                = CONV #( cl_abap_context_info=>get_system_date(  ) + 14 )
+                                 ) ) ) TO purchase_requisition_items.
+
+      "purchase requisition account assignment
+      APPEND VALUE #( %cid_ref = |My%ItemCID_{ n }|
+                      %target  = VALUE #( (
+                                   %cid       = |My%AccntCID_{ n }|
+                                   CostCenter = 'JMW-COST'
+                                   GLAccount  = '0000400000'
+                                 ) ) ) TO purchase_reqn_acct_assgmts.
+
+      "purchase requisition item text
+      APPEND VALUE #( %cid_ref = |My%ItemCID_{ n }|
+                      %target  = VALUE #( (
+                                   %cid           = |My%TextCID_{ n }|
+                                   textobjecttype = 'B01'
+                                   language       = 'E'
+                                   plainlongtext  = OnlineOrder-Product
+                                 ) ) ) TO purchase_reqn_item_texts.
+    ENDLOOP.
+
+    "EML deep create statement
+    IF keys IS NOT INITIAL.
+      MODIFY ENTITIES OF i_purchaserequisitiontp
+        ENTITY purchaserequisition
+          CREATE FIELDS ( purchaserequisitiontype )
+            WITH purchase_requisitions
+          CREATE BY \_purchaserequisitionitem
+            FIELDS ( plant
+                     accountassignmentcategory
+                     requestedquantity
+                     purchaserequisitionprice
+                     purreqnitemcurrency
+                     Material
+                     materialgroup
+                     purchasinggroup
+                     purchasingorganization
+                     DeliveryDate
+                   )
+            WITH purchase_requisition_items
+        ENTITY purchaserequisitionitem
+          CREATE BY \_purchasereqnacctassgmt
+            FIELDS ( CostCenter
+                     GLAccount )
+            WITH purchase_reqn_acct_assgmts
+          CREATE BY \_purchasereqnitemtext
+            FIELDS ( plainlongtext )
+            WITH purchase_reqn_item_texts
+        REPORTED DATA(reported_create_pr)
+        MAPPED DATA(mapped_create_pr)
+        FAILED DATA(failed_create_pr).
+    ENDIF.
+
+    "buffer the generated key information
+    "the correct value for PurchaseRequisition has to be calculated in the save sequence using convert key
+    zbp_r_onlineshop_###=>mapped_purchase_requisition-purchaserequisition = mapped_create_pr-purchaserequisition.
+
+    LOOP AT keys INTO DATA(key_update).
+      APPEND VALUE #( %tky          = key_update-%tky
+                      OverallStatus = 'submitted' ) TO update_lines.
+    ENDLOOP.
+
+    MODIFY ENTITIES OF zr_onlineshop_### IN LOCAL MODE
+         ENTITY OnlineShop
+           UPDATE
+           FIELDS ( OverallStatus )
+           WITH update_lines
+         REPORTED reported
+         FAILED failed
+         MAPPED mapped.
+    IF failed IS INITIAL.
+      "Read the changed data for action result
+      READ ENTITIES OF zr_onlineshop_### IN LOCAL MODE
+        ENTITY OnlineShop
+          ALL FIELDS
+          WITH CORRESPONDING #( keys )
+        RESULT DATA(result_read).
+
+      "return result entities
+      result = VALUE #( FOR order_changed IN result_read ( %tky   = order_changed-%tky
+                                                           %param = order_changed ) ).
+    ENDIF.
+
+  ENDMETHOD.
+
+ +7. Replace the placeholder `###` with your group ID. + +8. Save ![save icon](../../images/adt_save.png) and activate ![activate icon](../../images/adt_activate.png) the changes. + +## Exercise 3.5: Add unmanaged save + +We have to add the use of an unmanaged save to the behavior of our RAP business object since the Purchase Requisition API that we plan to call uses late numbering. + +1. Navigate to the behavior definition ZR_ONLINESHOP_### either in the Project Explorer (**Core Data Services** -> **Behavior Definitions**) or by opening it as a development object using the short cut Ctrl+Shift+A. + +2. Open the behavior definition and add the statement + +
+with unmanaged save 
+
+ +right after the + +
+authorization master ( global ) 
+
+ +statement. + +In addition comment out the statement that specifies the persistent table of our RAP BO `//persistent table zaonlineshop_###` since it is not possible to use both statements in the same behavior definition. + +It should then look like this: + +
+managed implementation in class ZBP_R_ONLINESHOP_### unique;
+strict ( 2 );
+with draft;
+
+define behavior for ZR_ONLINESHOP_### alias onlineshop
+//persistent table zonlineshop_###
+draft table ZDONLINESHOP_###
+etag master LocalLastChangedAt
+lock master total etag LastChangedAt
+authorization master( global )
+with unmanaged save
+
+ +3. Save ![save icon](../../images/adt_save.png) and activate all ![activate icon](../../images/adt_activateAll.png) the changes. + +4. After having activated your changes select the key word `unmanaged` and select Ctrl + 1 (Command +1 on Mac) to start the code assistant. + +![define_determinations](images/420_define_determinations.png) + +This will add a local saver class `lsc_zr_onlineshop_###` to the local classes of your behavior implementation class (in the **Project Explorer** under **Source Code Library** -> **Classes**, in the `Local Types` tab in the ADT Editor). The method `save_modified` is added to the `DEFINITION` and the `IMPLEMENTATION` section of this local class. + +
+CLASS lsc_zr_onlineshop_### DEFINITION INHERITING FROM cl_abap_behavior_saver.
+
+  PROTECTED SECTION.
+
+  METHODS save_modified REDEFINITION.
+  
+ENDCLASS.
+
+ +5. Save ![save icon](../../images/adt_save.png) the changes. + +6. To implement the `save_modified()` method, replace: + +
+  METHOD save_modified.
+  ENDMETHOD.
+
+ +with: + +
+   METHOD save_modified.
+
+    DATA onlineshop_db TYPE STANDARD TABLE OF zonlineshop_###.
+
+    IF create-onlineshop IS NOT INITIAL.
+      onlineshop_db = CORRESPONDING #( create-onlineshop MAPPING FROM ENTITY ).
+
+      "determine the ID of the created purchase requisition and store it as a reference in the created order
+      LOOP AT onlineshop_db ASSIGNING FIELD-SYMBOL(<order>).
+        READ TABLE zbp_r_onlineshop_###=>mapped_purchase_requisition-purchaserequisition ASSIGNING FIELD-SYMBOL(<pr_mapped>)
+                   WITH KEY cid COMPONENTS %cid = <order>-order_uuid.
+        IF sy-subrc = 0.
+          CONVERT KEY OF i_purchaserequisitiontp FROM <pr_mapped>-%pid TO DATA(pr_key).
+          <order>-purchase_requisition = pr_key-purchaserequisition.
+        ENDIF.
+      ENDLOOP.
+
+      INSERT zonlineshop_### FROM TABLE @onlineshop_db.
+    ENDIF.
+
+    LOOP AT delete-onlineshop INTO DATA(onlineshop_delete) WHERE OrderUUID IS NOT INITIAL.
+      DELETE FROM zonlineshop_### WHERE order_uuid = @onlineshop_delete-OrderUUID.
+      DELETE FROM zdonlineshop_### WHERE orderuuid = @onlineshop_delete-OrderUUID.
+    ENDLOOP.
+
+  ENDMETHOD.
+
+ +7. Replace the placeholder `###` with your group ID. + +8. Save ![save icon](../../images/adt_save.png) and activate ![activate icon](../../images/adt_activate.png) the changes. + +## Exercise 3.6: Check your preview application + + 1. Open the service binding `ZUI_ONLINESHOP_O4_###` (**Business Services** -> **Service Bindings**) to test your implementation by using the ADT Fiori preview. Alternatively, if you keep the browser window open with the Fiori preview, you can just refresh the browser and it will automatically reflect the new code. + + 2. On the list, press `Create` and then on the object page enter a new onlineshop entry using for example a product `AS01` and a quantity `1` and then press the `Create` button in lower right corner. + + ![define_determinations](images/313_define_determinations.png) + + + The order id gets calculated and a new purchase requisition gets created in S/4HANA and you should see it in the result: + + ![define_determinations](images/314_define_determinations.png) + + + ## Summary + + You have implemented an adjustment to the Fiori elements UI and a determination to calculate a new order ID and to create a purchase requisiton in S/4HANA. + + You can continue with the next exercise - **[Exercise 4: Create a Web API for the Onlineshop](../ex4/README.md)**. + + diff --git a/exercises/rap/exercises/ex3/images/090_adapt_data_model.png b/exercises/rap/exercises/ex3/images/090_adapt_data_model.png new file mode 100644 index 0000000..d45c113 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/090_adapt_data_model.png differ diff --git a/exercises/rap/exercises/ex3/images/100_adapt_data_model.png b/exercises/rap/exercises/ex3/images/100_adapt_data_model.png new file mode 100644 index 0000000..a8b6474 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/100_adapt_data_model.png differ diff --git a/exercises/rap/exercises/ex3/images/105_adapt_data_model.png b/exercises/rap/exercises/ex3/images/105_adapt_data_model.png new file mode 100644 index 0000000..cf4533f Binary files /dev/null and b/exercises/rap/exercises/ex3/images/105_adapt_data_model.png differ diff --git a/exercises/rap/exercises/ex3/images/110_adapt_data_model.png b/exercises/rap/exercises/ex3/images/110_adapt_data_model.png new file mode 100644 index 0000000..3ae6019 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/110_adapt_data_model.png differ diff --git a/exercises/rap/exercises/ex3/images/115_adapt_data_model.png b/exercises/rap/exercises/ex3/images/115_adapt_data_model.png new file mode 100644 index 0000000..cee9b1e Binary files /dev/null and b/exercises/rap/exercises/ex3/images/115_adapt_data_model.png differ diff --git a/exercises/rap/exercises/ex3/images/195_adapt_bdef.png b/exercises/rap/exercises/ex3/images/195_adapt_bdef.png new file mode 100644 index 0000000..994d977 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/195_adapt_bdef.png differ diff --git a/exercises/rap/exercises/ex3/images/200_adapt_bdef.png b/exercises/rap/exercises/ex3/images/200_adapt_bdef.png new file mode 100644 index 0000000..4a7515d Binary files /dev/null and b/exercises/rap/exercises/ex3/images/200_adapt_bdef.png differ diff --git a/exercises/rap/exercises/ex3/images/210_adapt_bdef.png b/exercises/rap/exercises/ex3/images/210_adapt_bdef.png new file mode 100644 index 0000000..273be4c Binary files /dev/null and b/exercises/rap/exercises/ex3/images/210_adapt_bdef.png differ diff --git a/exercises/rap/exercises/ex3/images/220_adapt_bdef.png b/exercises/rap/exercises/ex3/images/220_adapt_bdef.png new file mode 100644 index 0000000..485b97f Binary files /dev/null and b/exercises/rap/exercises/ex3/images/220_adapt_bdef.png differ diff --git a/exercises/rap/exercises/ex3/images/225_adapt_bdef.png b/exercises/rap/exercises/ex3/images/225_adapt_bdef.png new file mode 100644 index 0000000..49a9a90 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/225_adapt_bdef.png differ diff --git a/exercises/rap/exercises/ex3/images/230_adapt_bdef.png b/exercises/rap/exercises/ex3/images/230_adapt_bdef.png new file mode 100644 index 0000000..eeb8fab Binary files /dev/null and b/exercises/rap/exercises/ex3/images/230_adapt_bdef.png differ diff --git a/exercises/rap/exercises/ex3/images/235_adapt_bdef.png b/exercises/rap/exercises/ex3/images/235_adapt_bdef.png new file mode 100644 index 0000000..f49d031 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/235_adapt_bdef.png differ diff --git a/exercises/rap/exercises/ex3/images/290_adapt_bdef.png b/exercises/rap/exercises/ex3/images/290_adapt_bdef.png new file mode 100644 index 0000000..4980ad4 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/290_adapt_bdef.png differ diff --git a/exercises/rap/exercises/ex3/images/300_define_determinations.png b/exercises/rap/exercises/ex3/images/300_define_determinations.png new file mode 100644 index 0000000..fc94048 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/300_define_determinations.png differ diff --git a/exercises/rap/exercises/ex3/images/300_define_determinations_1.png b/exercises/rap/exercises/ex3/images/300_define_determinations_1.png new file mode 100644 index 0000000..a1e37be Binary files /dev/null and b/exercises/rap/exercises/ex3/images/300_define_determinations_1.png differ diff --git a/exercises/rap/exercises/ex3/images/310_define_determinations.png b/exercises/rap/exercises/ex3/images/310_define_determinations.png new file mode 100644 index 0000000..1a10cdb Binary files /dev/null and b/exercises/rap/exercises/ex3/images/310_define_determinations.png differ diff --git a/exercises/rap/exercises/ex3/images/310_define_determinations_1.png b/exercises/rap/exercises/ex3/images/310_define_determinations_1.png new file mode 100644 index 0000000..408ab36 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/310_define_determinations_1.png differ diff --git a/exercises/rap/exercises/ex3/images/312_define_determinations.png b/exercises/rap/exercises/ex3/images/312_define_determinations.png new file mode 100644 index 0000000..c285f06 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/312_define_determinations.png differ diff --git a/exercises/rap/exercises/ex3/images/312_define_determinations_1.png b/exercises/rap/exercises/ex3/images/312_define_determinations_1.png new file mode 100644 index 0000000..be98b59 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/312_define_determinations_1.png differ diff --git a/exercises/rap/exercises/ex3/images/313_define_determinations.png b/exercises/rap/exercises/ex3/images/313_define_determinations.png new file mode 100644 index 0000000..42562a3 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/313_define_determinations.png differ diff --git a/exercises/rap/exercises/ex3/images/314_define_determinations.png b/exercises/rap/exercises/ex3/images/314_define_determinations.png new file mode 100644 index 0000000..29d5990 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/314_define_determinations.png differ diff --git a/exercises/rap/exercises/ex3/images/320_define_determinations.png b/exercises/rap/exercises/ex3/images/320_define_determinations.png new file mode 100644 index 0000000..3f0fd68 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/320_define_determinations.png differ diff --git a/exercises/rap/exercises/ex3/images/400_define_determinations.png b/exercises/rap/exercises/ex3/images/400_define_determinations.png new file mode 100644 index 0000000..d4f8155 Binary files /dev/null and b/exercises/rap/exercises/ex3/images/400_define_determinations.png differ diff --git a/exercises/rap/exercises/ex3/images/400_define_determinations_1.png b/exercises/rap/exercises/ex3/images/400_define_determinations_1.png new file mode 100644 index 0000000..5c6784c Binary files /dev/null and b/exercises/rap/exercises/ex3/images/400_define_determinations_1.png differ diff --git a/exercises/rap/exercises/ex3/images/400_define_validations.png b/exercises/rap/exercises/ex3/images/400_define_validations.png new file mode 100644 index 0000000..b4ed01b Binary files /dev/null and b/exercises/rap/exercises/ex3/images/400_define_validations.png differ diff --git a/exercises/rap/exercises/ex3/images/410_define_determinations.png b/exercises/rap/exercises/ex3/images/410_define_determinations.png new file mode 100644 index 0000000..7c1db9a Binary files /dev/null and b/exercises/rap/exercises/ex3/images/410_define_determinations.png differ diff --git a/exercises/rap/exercises/ex3/images/410_define_determinations_1.png b/exercises/rap/exercises/ex3/images/410_define_determinations_1.png new file mode 100644 index 0000000..7c1db9a Binary files /dev/null and b/exercises/rap/exercises/ex3/images/410_define_determinations_1.png differ diff --git a/exercises/rap/exercises/ex3/images/420_define_determinations.png b/exercises/rap/exercises/ex3/images/420_define_determinations.png new file mode 100644 index 0000000..aeabcfc Binary files /dev/null and b/exercises/rap/exercises/ex3/images/420_define_determinations.png differ diff --git a/exercises/rap/exercises/ex3/images/500_unmanaged_save.png b/exercises/rap/exercises/ex3/images/500_unmanaged_save.png new file mode 100644 index 0000000..a5843aa Binary files /dev/null and b/exercises/rap/exercises/ex3/images/500_unmanaged_save.png differ diff --git a/exercises/rap/exercises/ex3/sources/ZI_PRODUCT_VH_REUSE.txt b/exercises/rap/exercises/ex3/sources/ZI_PRODUCT_VH_REUSE.txt new file mode 100644 index 0000000..bf0eb73 --- /dev/null +++ b/exercises/rap/exercises/ex3/sources/ZI_PRODUCT_VH_REUSE.txt @@ -0,0 +1,57 @@ +@AbapCatalog.viewEnhancementCategory: [#NONE] +@AccessControl.authorizationCheck: #NOT_REQUIRED +@EndUserText.label: 'Value Help for I_PRODUCT' +@Metadata.ignorePropagatedAnnotations: true +@ObjectModel.usageType:{ + serviceQuality: #X, + sizeCategory: #S, + dataClass: #MIXED +} +define view entity ZI_PRODUCT_VH_REUSE + as select from I_Product +{ + // @UI.lineItem: [{ position: 10, label: 'Product', importance: #HIGH }] + key Product as Product, + + // @UI.lineItem: [{ position: 20, label: 'Product Description', importance: #HIGH }] + _Text[1: Language=$session.system_language].ProductName as ProductText, + + // @UI.lineItem: [{ position: 30, label: 'Price', importance: #HIGH }] + @Semantics.amount.currencyCode: 'Currency' + case +// when Product = 'ZPRINTER01' then cast ( 500.00 as abap.dec( 16, 2 ) ) +// when Product = 'ZPRINTER02' then cast ( 300.00 as abap.dec( 16, 2 ) ) + when Product = 'D001' then cast ( 550.00 as abap.dec(16,2) ) //Mobile Phone + when Product = 'D002' then cast ( 499.00 as abap.dec(16,2) ) //Tablet PC + when Product = 'D003' then cast ( 599.00 as abap.dec(16,2) ) //Apfel Pad + when Product = 'D004' then cast ( 49.00 as abap.dec(16,2) ) //Dingens + when Product = 'D005' then cast ( 150.00 as abap.dec(16,2) ) //Office Table + when Product = 'D006' then cast ( 259.00 as abap.dec(16,2) ) //Office Chair + else cast ( 100000.00 as abap.dec(16,2) ) // :-) + end as Price, + + // @UI.lineItem: [{ position: 40, label: 'Product Group'}] + @UI.hidden: true + cast ( 'EUR' as abap.cuky( 5 ) ) as Currency, + + // @UI.lineItem: [{ position: 50, label: 'Product Group'] + @UI.hidden: true + ProductGroup as ProductGroup, + + // @UI.lineItem: [{ position: 60, label: 'Base Unit'}] + @UI.hidden: true + BaseUnit as BaseUnit + +} +where + Product = 'D001' + or Product = 'D002' + or Product = 'D003' + or Product = 'D004' + or Product = 'D005' + or Product = 'D006' +// or Product = 'ZPRINTER01' +// or Product = 'ZPRINTER02' + + + diff --git a/exercises/rap/exercises/ex3/sources/behavior_implementation_with_determinations.txt b/exercises/rap/exercises/ex3/sources/behavior_implementation_with_determinations.txt new file mode 100644 index 0000000..1c87f0a --- /dev/null +++ b/exercises/rap/exercises/ex3/sources/behavior_implementation_with_determinations.txt @@ -0,0 +1,140 @@ +CLASS lcl_handler DEFINITION INHERITING FROM cl_abap_behavior_handler. + PRIVATE SECTION. + + CONSTANTS: + BEGIN OF is_draft, + false TYPE abp_behv_flag VALUE '00', " active (not draft) + true TYPE abp_behv_flag VALUE '01', " draft + END OF is_draft. + CONSTANTS: + BEGIN OF c_overall_status, + new TYPE string VALUE 'New / Composing', + submitted TYPE string VALUE 'Submitted / Approved', + END OF c_overall_status. + + METHODS: + get_global_authorizations FOR GLOBAL AUTHORIZATION + IMPORTING + REQUEST requested_authorizations FOR OnlineShop + RESULT result, + calculateTotalPrice FOR DETERMINE ON MODIFY + IMPORTING keys FOR OnlineShop~calculateTotalPrice, + setInitialOrderValues FOR DETERMINE ON MODIFY + IMPORTING keys FOR OnlineShop~setInitialOrderValues, + updateProductDetails FOR DETERMINE ON MODIFY + IMPORTING keys FOR OnlineShop~updateProductDetails. +ENDCLASS. + +CLASS lcl_handler IMPLEMENTATION. + METHOD get_global_authorizations. + ENDMETHOD. + METHOD calculateTotalPrice. + DATA total_price TYPE ZR_OnlineShop_000-TotalPrice. + + " read transfered instances + READ ENTITIES OF ZR_OnlineShop_000 IN LOCAL MODE + ENTITY OnlineShop + FIELDS ( OrderID TotalPrice OrderItemPrice OrderItemQuantity ) + WITH CORRESPONDING #( keys ) + RESULT DATA(OnlineShops). + + LOOP AT OnlineShops ASSIGNING FIELD-SYMBOL(). + " calculate total value + -TotalPrice = -OrderItemPrice * -OrderItemQuantity. + ENDLOOP. + + "update instances + MODIFY ENTITIES OF ZR_OnlineShop_000 IN LOCAL MODE + ENTITY OnlineShop + UPDATE FIELDS ( TotalPrice ) + WITH VALUE #( FOR OnlineShop IN OnlineShops ( + %tky = OnlineShop-%tky + TotalPrice = -TotalPrice + ) ). + ENDMETHOD. + + METHOD setInitialOrderValues. + DATA delivery_date TYPE I_PurchaseReqnItemTP-DeliveryDate. + + "set delivery date proposal + cl_scal_api=>date_compute_day( + EXPORTING + iv_date = cl_abap_context_info=>get_system_date( ) + IMPORTING + ev_weekday_number = DATA(weekday_number) + ev_weekday_name = DATA(weekday_name) + ). + CASE weekday_number. + WHEN 6. + delivery_date = cl_abap_context_info=>get_system_date( ) + 16. + WHEN 7. + delivery_date = cl_abap_context_info=>get_system_date( ) + 15. + WHEN OTHERS. + delivery_date = cl_abap_context_info=>get_system_date( ) + 14. + ENDCASE. + + "read transfered instances + READ ENTITIES OF ZR_OnlineShop_000 IN LOCAL MODE + ENTITY OnlineShop + FIELDS ( OrderID OverallStatus DeliveryDate ) + WITH CORRESPONDING #( keys ) + RESULT DATA(OnlineShops). + + "delete entries with assigned order ID + DELETE OnlineShops WHERE OrderID IS NOT INITIAL. + CHECK OnlineShops IS NOT INITIAL. + + " **Dummy logic to determine order IDs** + " get max order ID from the relevant active and draft table entries + SELECT MAX( order_id ) FROM zaonlineshop_000 INTO @DATA(max_order_id). "active table + SELECT SINGLE FROM zdonlineshop_000 FIELDS MAX( orderid ) INTO @DATA(max_orderid_draft). "draft table + IF max_orderid_draft > max_order_id. + max_order_id = max_orderid_draft. + ENDIF. + + "set initial values of new instances + MODIFY ENTITIES OF ZR_OnlineShop_000 IN LOCAL MODE + ENTITY OnlineShop + UPDATE FIELDS ( OrderID OverallStatus DeliveryDate OrderItemPrice ) + WITH VALUE #( FOR OnlineShop IN OnlineShops INDEX INTO i ( + %tky = OnlineShop-%tky + OrderID = max_order_id + i + OverallStatus = c_overall_status-new "'New / Composing' + DeliveryDate = delivery_date + ) ). + ENDMETHOD. + + METHOD updateProductDetails. + "read transfered instances + READ ENTITIES OF ZR_OnlineShop_000 IN LOCAL MODE + ENTITY OnlineShop + FIELDS ( OrderItemID ) + WITH CORRESPONDING #( keys ) + RESULT DATA(OnlineShops). + + "read and set product details + LOOP AT OnlineShops ASSIGNING FIELD-SYMBOL(). + "read and set relevant product information + SELECT SINGLE * FROM zi_product_vh_reuse WHERE product = @-OrderItemID INTO @DATA(product). + -ProductGroup = product-productgroup. + -ProductText = product-producttext. + -OrderItemPrice = product-price. + -Currency = product-Currency. + -BaseUnit = product-baseunit. + ENDLOOP. + + "update instances + MODIFY ENTITIES OF ZR_OnlineShop_000 IN LOCAL MODE + ENTITY OnlineShop + UPDATE FIELDS ( ProductText OrderItemPrice Currency ProductGroup BaseUnit ) + WITH VALUE #( FOR OnlineShop IN OnlineShops INDEX INTO i ( + %tky = OnlineShop-%tky + ProductText = OnlineShop-ProductText + OrderItemPrice = OnlineShop-OrderItemPrice + Currency = OnlineShop-Currency + ProductGroup = OnlineShop-ProductGroup + BaseUnit = OnlineShop-BaseUnit + ) ). + ENDMETHOD. + +ENDCLASS. \ No newline at end of file diff --git a/exercises/rap/exercises/ex4/README.md b/exercises/rap/exercises/ex4/README.md new file mode 100644 index 0000000..23720a0 --- /dev/null +++ b/exercises/rap/exercises/ex4/README.md @@ -0,0 +1,165 @@ + +# Exercise 4: Create a Web API for the Onlineshop + +In this exercise we create an additional service. In the exercise before we created an Onlineshop service that we can use for a Fiori elements application which supports drafts (the ability to save UI entries in an unfinished or wrong state for the current user, in order to allow the user to correct the entry later. The entry will only become visible when the entry was finally corrected and saved.). These kind of services are not suitable to be called from other places than UIs, for example processes. As we later on want to create a process, we will now add a second service for web API usage. + +For this we need to add a couple of artefacts on top of the already existing ones. + +## Exercise 4.1: Create a new Data Definition + +1. In your project open the context menu on **Core Data Services** -> **Data Definitions** and select **New Data Definition**. + +![new_dd](images/100.png) + +2. Maintain the required information (`###` is your group ID) and click **Next >**. + - Name: _**`ZAPI_ONLINESHOP_###`**_ + - Description: _**`Onlineshop API`**_ + +![new_dd](images/110.png) + +3. Select your transport request and click **Finish** to create the data definition. + +4. Overwrite the contents of the generated data definition like this + +
+@AccessControl.authorizationCheck: #CHECK
+@Metadata.allowExtensions: true
+@EndUserText.label: 'Projection View for ZR_ONLINESHOP_###'
+define root view entity ZAPI_ONLINESHOP_###
+  provider contract transactional_query
+  as projection on ZR_ONLINESHOP_###
+{
+  key OrderUUID,
+  OrderID,
+  Product,
+  Quantity,
+  LocalLastChangedAt
+}
+
+ +5. Replace the placeholder `###` with your group ID. + +6. Save ![save icon](../../images/adt_save.png) and activate ![activate icon](../../images/adt_activate.png) the changes. + +## Exercise 4.2: Create a new Behavior Definition + +1. In your project open the context menu on **Core Data Services** -> **Behavior Definitions** and select **New Behavior Definition**. + +![new_dd](images/120.png) + +2. Maintain the required information (`###` is your group ID): + - Description: _**`Behavior for ZAPI_ONLINESHOP_###`**_ + - Root Entity: _**`ZAPI_ONLINESHOP_###`**_ + - Implementation Type: _**`Projection`**_ + + Click **Next >**. + +![new_dd](images/130.png) + +3. Select your transport request and click **Finish**. + +4. In the generated code get rid of the `use draft` line and all the lines that start with `use action` + +![new_dd](images/140.png) + +5. Add `alias onlineshop` as an alias, the code should look like this: + +
+projection;
+strict ( 2 );
+
+define behavior for ZAPI_ONLINESHOP_### alias onlineshop
+{
+  use create;
+  use update;
+  use delete;
+}
+
+ +7. Save ![save icon](../../images/adt_save.png) and activate ![activate icon](../../images/adt_activate.png) the changes. + +## Exercise 4.3: Create a new Service Definition + +1. In your project open the context menu on **Business Services** -> **Service Definition** and select **New Service Definition**. + +![new_dd](images/150.png) + +2. Maintain the required information (`###` is your group ID): + - Name: _**`Z_ONLINESHOP_###`**_ + - Description: _**`Service Definition Z_ONLINESHOP_###`**_ + - Source Type: _**`Definition`**_ + - Referenced Object: _**`ZAPI_ONLINESHOP_###`**_ + + Click **Next >**. + +![new_dd](images/160.png) + +3. Select your transport request and click **Finish**. + +5. Add the alias `as onlineshop`. The code should look like this: + +
+@EndUserText.label: 'Service Defition Z_ONLINESHOP_###'
+define service Z_ONLINESHOP_### {
+  expose ZAPI_ONLINESHOP_### as onlineshop;
+}
+
+ +6. Save ![save icon](../../images/adt_save.png) and activate ![activate icon](../../images/adt_activate.png) the changes. + +## Exercise 4.4: Create a new Service Binding + +1. In your project open the context menu on **Business Services** -> **Service Bindings** and select **New Service Bindings**. + +![new_dd](images/170.png) + +2. Maintain the required information (`###` is your group ID): + - Name: _**`Z_ONLINESHOP_###`**_ + - Description: _**`Web API for Onlineshop`**_ + - Binding Type: _**`OData V4 - Web API`**_ + - Service Definition: _**`Z_ONLINESHOP_###`**_ + + Click **Next >**. + +![new_dd](images/180.png) + +3. Select your transport request and click **Finish**. + +4. Save ![save icon](../../images/adt_save.png) and activate ![activate icon](../../images/adt_activate.png) the changes. + +5. On the resulting UI press the `Publish` button, the result looks like this: + +![new_dd](images/190.png) + +## Exercise 4.5: Test the API in the browser + +1. Press on the link `Service URL` in the picture above. This will open the service in the browser. + +2. In the browser, remove `?sap-client=100` from the URL and add `onlineshop` at the end of the URL, so it looks like this + +https://YY.YYYY.YYY.YY:44301/sap/opu/odata4/sap/z_onlineshop_###/srvd_a2x/sap/z_onlineshop_###/0001/onlineshop + +3. Press enter to load the page. The result should display the order you created in the previous exercise: + +
+{
+    "@odata.context": "$metadata#onlineshop",
+    "@odata.metadataEtag": "W/\"20230512011226\"",
+    "value": [
+        {
+            "OrderUUID": "41d67ed4-f6d7-1edd-bc8c-0d6a2c2a133f",
+            "OrderID": "        1",
+            "Product": "AS01",
+            "Quantity": 1,
+            "LocalLastChangedAt": "2023-05-12T01:00:52.710668Z",
+            "SAP__Messages": []
+        }
+    ]
+}
+
+ +## Summary + +You have created a Web API next to the one that is suitable for a UI and you can now use this API in a SAP Build Process. + +You can continue with the next exercise - **[Build Exercise 1: Create Actions in SAP Build to access the Onlineshop API](../../../build/exercises/ex1/README.md)** diff --git a/exercises/rap/exercises/ex4/images/100.png b/exercises/rap/exercises/ex4/images/100.png new file mode 100644 index 0000000..1d5b7e7 Binary files /dev/null and b/exercises/rap/exercises/ex4/images/100.png differ diff --git a/exercises/rap/exercises/ex4/images/110.png b/exercises/rap/exercises/ex4/images/110.png new file mode 100644 index 0000000..1aeb16e Binary files /dev/null and b/exercises/rap/exercises/ex4/images/110.png differ diff --git a/exercises/rap/exercises/ex4/images/120.png b/exercises/rap/exercises/ex4/images/120.png new file mode 100644 index 0000000..8b57928 Binary files /dev/null and b/exercises/rap/exercises/ex4/images/120.png differ diff --git a/exercises/rap/exercises/ex4/images/130.png b/exercises/rap/exercises/ex4/images/130.png new file mode 100644 index 0000000..0383d5e Binary files /dev/null and b/exercises/rap/exercises/ex4/images/130.png differ diff --git a/exercises/rap/exercises/ex4/images/140.png b/exercises/rap/exercises/ex4/images/140.png new file mode 100644 index 0000000..86ea521 Binary files /dev/null and b/exercises/rap/exercises/ex4/images/140.png differ diff --git a/exercises/rap/exercises/ex4/images/150.png b/exercises/rap/exercises/ex4/images/150.png new file mode 100644 index 0000000..c7c9312 Binary files /dev/null and b/exercises/rap/exercises/ex4/images/150.png differ diff --git a/exercises/rap/exercises/ex4/images/160.png b/exercises/rap/exercises/ex4/images/160.png new file mode 100644 index 0000000..785f50f Binary files /dev/null and b/exercises/rap/exercises/ex4/images/160.png differ diff --git a/exercises/rap/exercises/ex4/images/170.png b/exercises/rap/exercises/ex4/images/170.png new file mode 100644 index 0000000..91bb992 Binary files /dev/null and b/exercises/rap/exercises/ex4/images/170.png differ diff --git a/exercises/rap/exercises/ex4/images/180.png b/exercises/rap/exercises/ex4/images/180.png new file mode 100644 index 0000000..cfed904 Binary files /dev/null and b/exercises/rap/exercises/ex4/images/180.png differ diff --git a/exercises/rap/exercises/ex4/images/190.png b/exercises/rap/exercises/ex4/images/190.png new file mode 100644 index 0000000..a2e70ee Binary files /dev/null and b/exercises/rap/exercises/ex4/images/190.png differ diff --git a/exercises/rap/exercises/ex4/images/200.png b/exercises/rap/exercises/ex4/images/200.png new file mode 100644 index 0000000..a88d71d Binary files /dev/null and b/exercises/rap/exercises/ex4/images/200.png differ diff --git a/exercises/rap/exercises/ex99/README.md b/exercises/rap/exercises/ex99/README.md new file mode 100644 index 0000000..b32421a --- /dev/null +++ b/exercises/rap/exercises/ex99/README.md @@ -0,0 +1,55 @@ +# How to connect to an SAP S/4HANA on premise or private cloud system + +This document describes how to create an **ABAP Project** to connect to an SAP S/4HANA on premise or private cloud system. + + +1. Click on **File > New > New ABAP Project** + + ![New ABAP Project](images/100_create_a_new_abap_project.png) + +2. In the *System Connection* dialogue click on the link **new system connection** + + ![System Connection](images/110_create_a_new_abap_project.png) + +3. In the *Connection Settings* dialogue choose the connection type **Custom Application Server** + + Then enter the following connection information (The IP address of the application server is provided by the instructors) + - System ID: S4H + - Application Server: xxx.xxx.xxx.xxx + - Instance Number: 00 + + and **deactivate** the check box **Activate Secure Network Communication (SNC)** + + Press Next. + + ![Connection Settings](images/120_create_a_new_abap_project.png) + +4. In the *Logon to System* dialogue enter the following data. The user for you and the password are provided to you by the instructors + + - Client: 100 + - User: lowcode### + - Password: xxxxxxxx + - Language: EN + + Press Next + + ![Logon to System](images/130_create_a_new_abap_project.png) + +5. In the *Project Name* screen leave the default value proposed by ADT. + + ![Project Name](images/140_create_a_new_abap_project.png) + +6. Press **Finish**. + +7. Add `ZLOCAL` to your favorites packages. + + - Right click on the folder **Favorite Packages** in your newly created ABAP project. + + ![add_to_favorites](images/99_100_add_zlocal_to_favorites.png) + + - Search for `ZLOCAL`. Select the entry and press **OK**. + + ![add_to_favorites](images/99_110_add_zlocal_to_favorites.png) + + +Continue to - [Exercise 1: Create an ABAP Package](../ex1/README.md) diff --git a/exercises/rap/exercises/ex99/images/100_create_a_new_abap_project.png b/exercises/rap/exercises/ex99/images/100_create_a_new_abap_project.png new file mode 100644 index 0000000..3b1eebd Binary files /dev/null and b/exercises/rap/exercises/ex99/images/100_create_a_new_abap_project.png differ diff --git a/exercises/rap/exercises/ex99/images/100_edit_hosts.png b/exercises/rap/exercises/ex99/images/100_edit_hosts.png new file mode 100644 index 0000000..dba1862 Binary files /dev/null and b/exercises/rap/exercises/ex99/images/100_edit_hosts.png differ diff --git a/exercises/rap/exercises/ex99/images/110_create_a_new_abap_project.png b/exercises/rap/exercises/ex99/images/110_create_a_new_abap_project.png new file mode 100644 index 0000000..ef36680 Binary files /dev/null and b/exercises/rap/exercises/ex99/images/110_create_a_new_abap_project.png differ diff --git a/exercises/rap/exercises/ex99/images/110_edit_hosts.png b/exercises/rap/exercises/ex99/images/110_edit_hosts.png new file mode 100644 index 0000000..c87fd05 Binary files /dev/null and b/exercises/rap/exercises/ex99/images/110_edit_hosts.png differ diff --git a/exercises/rap/exercises/ex99/images/120_create_a_new_abap_project.png b/exercises/rap/exercises/ex99/images/120_create_a_new_abap_project.png new file mode 100644 index 0000000..8a82602 Binary files /dev/null and b/exercises/rap/exercises/ex99/images/120_create_a_new_abap_project.png differ diff --git a/exercises/rap/exercises/ex99/images/120_edit_hosts.png b/exercises/rap/exercises/ex99/images/120_edit_hosts.png new file mode 100644 index 0000000..58afd80 Binary files /dev/null and b/exercises/rap/exercises/ex99/images/120_edit_hosts.png differ diff --git a/exercises/rap/exercises/ex99/images/130_create_a_new_abap_project.png b/exercises/rap/exercises/ex99/images/130_create_a_new_abap_project.png new file mode 100644 index 0000000..a310f89 Binary files /dev/null and b/exercises/rap/exercises/ex99/images/130_create_a_new_abap_project.png differ diff --git a/exercises/rap/exercises/ex99/images/130_edit_hosts.png b/exercises/rap/exercises/ex99/images/130_edit_hosts.png new file mode 100644 index 0000000..537facb Binary files /dev/null and b/exercises/rap/exercises/ex99/images/130_edit_hosts.png differ diff --git a/exercises/rap/exercises/ex99/images/140_create_a_new_abap_project.png b/exercises/rap/exercises/ex99/images/140_create_a_new_abap_project.png new file mode 100644 index 0000000..5185bd7 Binary files /dev/null and b/exercises/rap/exercises/ex99/images/140_create_a_new_abap_project.png differ diff --git a/exercises/rap/exercises/ex99/images/99_100_add_zlocal_to_favorites.png b/exercises/rap/exercises/ex99/images/99_100_add_zlocal_to_favorites.png new file mode 100644 index 0000000..db2ec71 Binary files /dev/null and b/exercises/rap/exercises/ex99/images/99_100_add_zlocal_to_favorites.png differ diff --git a/exercises/rap/exercises/ex99/images/99_110_add_zlocal_to_favorites.png b/exercises/rap/exercises/ex99/images/99_110_add_zlocal_to_favorites.png new file mode 100644 index 0000000..5c651a4 Binary files /dev/null and b/exercises/rap/exercises/ex99/images/99_110_add_zlocal_to_favorites.png differ diff --git a/exercises/rap/exercises/ex99/images/README.md b/exercises/rap/exercises/ex99/images/README.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/exercises/rap/exercises/ex99/images/README.md @@ -0,0 +1 @@ + diff --git a/exercises/rap/exercises/ex99/images/logon.png b/exercises/rap/exercises/ex99/images/logon.png new file mode 100644 index 0000000..c0644de Binary files /dev/null and b/exercises/rap/exercises/ex99/images/logon.png differ diff --git a/exercises/rap/exercises/ex99/images/logon2.png b/exercises/rap/exercises/ex99/images/logon2.png new file mode 100644 index 0000000..28e91cc Binary files /dev/null and b/exercises/rap/exercises/ex99/images/logon2.png differ diff --git a/exercises/rap/exercises/ex99/images/logon3.png b/exercises/rap/exercises/ex99/images/logon3.png new file mode 100644 index 0000000..cf78d32 Binary files /dev/null and b/exercises/rap/exercises/ex99/images/logon3.png differ diff --git a/exercises/rap/exercises/ex99/images/logon4.png b/exercises/rap/exercises/ex99/images/logon4.png new file mode 100644 index 0000000..bad889c Binary files /dev/null and b/exercises/rap/exercises/ex99/images/logon4.png differ diff --git a/exercises/rap/exercises/ex99/images/logon5.png b/exercises/rap/exercises/ex99/images/logon5.png new file mode 100644 index 0000000..e64206d Binary files /dev/null and b/exercises/rap/exercises/ex99/images/logon5.png differ diff --git a/exercises/rap/exercises/ex99/images/logon6.png b/exercises/rap/exercises/ex99/images/logon6.png new file mode 100644 index 0000000..347f63f Binary files /dev/null and b/exercises/rap/exercises/ex99/images/logon6.png differ diff --git a/exercises/rap/exercises/ex99/images/logon7.png b/exercises/rap/exercises/ex99/images/logon7.png new file mode 100644 index 0000000..49b2ff0 Binary files /dev/null and b/exercises/rap/exercises/ex99/images/logon7.png differ diff --git a/exercises/rap/exercises/ex99/images/logon8.png b/exercises/rap/exercises/ex99/images/logon8.png new file mode 100644 index 0000000..f72d80b Binary files /dev/null and b/exercises/rap/exercises/ex99/images/logon8.png differ diff --git a/exercises/rap/exercises/ex99/logon.md b/exercises/rap/exercises/ex99/logon.md new file mode 100644 index 0000000..9e99531 --- /dev/null +++ b/exercises/rap/exercises/ex99/logon.md @@ -0,0 +1,44 @@ +# How to connect to an SAP S/4HANA on premise system (ABAP Dev Day 2023) + +This document describes how to create an **ABAP Project** to connect to an SAP S/4HANA on premise system. + +1. Click on **File > New > ABAP Project** to create a new ABAP project. + + ![New ABAP Project](images/logon.png) + +2. In the *System Connection* select **S4H** and click **Next >**. The system **S4H** is already configured in SAP logon. + + ![System Connection](images/logon2.png) + +3. Click **Next >**. + + ![Connection Settings](images/logon3.png) + +4. In the *Logon to System* dialogue enter the following data + + - Client: xxx + - User: DEVELOPER### + - Password: xxxxxxxx + - Language: xx + + Click **Next >**. + + ![Logon to System](images/logon4.png) + +5. In the *Project Name* screen you can choose an individual name for your project or leave the default value proposed by ADT. Press **Finish**. + + ![Project Name](images/logon5.png) + +7. Add `ZLOCAL` to your favorites packages. Right click on the folder **Favorite Packages** in your newly created ABAP project. + + ![add_to_favorites](images/logon6.png) + +8. Search for `ZLOCAL`. Select the entry and press **OK**. + + ![add_to_favorites](images/logon7.png) + +9. Check your result. + + ![add_to_favorites](images/logon8.png) + + diff --git a/exercises/rap/images/100_SAP_S4_HANA_Extensibility_Patterns.png b/exercises/rap/images/100_SAP_S4_HANA_Extensibility_Patterns.png new file mode 100644 index 0000000..be97757 Binary files /dev/null and b/exercises/rap/images/100_SAP_S4_HANA_Extensibility_Patterns.png differ diff --git a/exercises/rap/images/Online_Shop_List_Report_Page.png b/exercises/rap/images/Online_Shop_List_Report_Page.png new file mode 100644 index 0000000..3fd45a5 Binary files /dev/null and b/exercises/rap/images/Online_Shop_List_Report_Page.png differ diff --git a/exercises/rap/images/Online_Shop_OBject_Page.png b/exercises/rap/images/Online_Shop_OBject_Page.png new file mode 100644 index 0000000..2a9a93c Binary files /dev/null and b/exercises/rap/images/Online_Shop_OBject_Page.png differ diff --git a/exercises/rap/images/README.md b/exercises/rap/images/README.md new file mode 100644 index 0000000..3cb458f --- /dev/null +++ b/exercises/rap/images/README.md @@ -0,0 +1 @@ +Images diff --git a/exercises/rap/images/adt_activate.png b/exercises/rap/images/adt_activate.png new file mode 100644 index 0000000..bfdafb1 Binary files /dev/null and b/exercises/rap/images/adt_activate.png differ diff --git a/exercises/rap/images/adt_activateAll.png b/exercises/rap/images/adt_activateAll.png new file mode 100644 index 0000000..d32a960 Binary files /dev/null and b/exercises/rap/images/adt_activateAll.png differ diff --git a/exercises/rap/images/adt_bdef.png b/exercises/rap/images/adt_bdef.png new file mode 100644 index 0000000..1050c7a Binary files /dev/null and b/exercises/rap/images/adt_bdef.png differ diff --git a/exercises/rap/images/adt_class.png b/exercises/rap/images/adt_class.png new file mode 100644 index 0000000..e38c3b4 Binary files /dev/null and b/exercises/rap/images/adt_class.png differ diff --git a/exercises/rap/images/adt_ddls.png b/exercises/rap/images/adt_ddls.png new file mode 100644 index 0000000..a9f4915 Binary files /dev/null and b/exercises/rap/images/adt_ddls.png differ diff --git a/exercises/rap/images/adt_ddlx.png b/exercises/rap/images/adt_ddlx.png new file mode 100644 index 0000000..5c520ca Binary files /dev/null and b/exercises/rap/images/adt_ddlx.png differ diff --git a/exercises/rap/images/adt_package.png b/exercises/rap/images/adt_package.png new file mode 100644 index 0000000..5962338 Binary files /dev/null and b/exercises/rap/images/adt_package.png differ diff --git a/exercises/rap/images/adt_save.png b/exercises/rap/images/adt_save.png new file mode 100644 index 0000000..aa82b01 Binary files /dev/null and b/exercises/rap/images/adt_save.png differ diff --git a/exercises/rap/images/adt_srvb.png b/exercises/rap/images/adt_srvb.png new file mode 100644 index 0000000..4f0fd4b Binary files /dev/null and b/exercises/rap/images/adt_srvb.png differ diff --git a/exercises/rap/images/adt_srvd.png b/exercises/rap/images/adt_srvd.png new file mode 100644 index 0000000..e56a629 Binary files /dev/null and b/exercises/rap/images/adt_srvd.png differ diff --git a/exercises/rap/images/adt_tabl.png b/exercises/rap/images/adt_tabl.png new file mode 100644 index 0000000..abceeb2 Binary files /dev/null and b/exercises/rap/images/adt_tabl.png differ diff --git a/exercises/rap/images/copy.png b/exercises/rap/images/copy.png new file mode 100644 index 0000000..29c16a4 Binary files /dev/null and b/exercises/rap/images/copy.png differ diff --git a/exercises/rap/images/copy2.png b/exercises/rap/images/copy2.png new file mode 100644 index 0000000..44a6ba2 Binary files /dev/null and b/exercises/rap/images/copy2.png differ diff --git a/exercises/rap/images/copy3.png b/exercises/rap/images/copy3.png new file mode 100644 index 0000000..179b7f0 Binary files /dev/null and b/exercises/rap/images/copy3.png differ diff --git a/exercises/rap/images/copyrawcontents.png b/exercises/rap/images/copyrawcontents.png new file mode 100644 index 0000000..633ca52 Binary files /dev/null and b/exercises/rap/images/copyrawcontents.png differ diff --git a/exercises/rap/images/doc.png b/exercises/rap/images/doc.png new file mode 100644 index 0000000..e783350 Binary files /dev/null and b/exercises/rap/images/doc.png differ