ABAP RESTful Programming Model
The ABAP RESTful Programming Model consists of three main layers:
Data Modeling & Behavior
Business Services Provisioning
Service Consumption
The data modeling and behavior layer contains domain-specific business objects that
are defined with Core Data Services (CDS) and transactional behavior.
The business service provisioning layer consists of projection views with their
projection behavior to focus on a particular aspect of the data model which is exposed
as business services through the OData protocol.
The service consumption layer allows you to consume all types of OData services as
well as OData Web APIs.
Get to know the database layer
Now investigate how the development flow (creation of artifacts etc.) looks in more detail.
The database layer is defined by the definition of dictionary tables. The dictionary tables are
the basis of the travel booking data model.
Get to know the CDS based data model
Our semantic data model is defined by Core Data Services (CDS). Core Data Services
are views on top of the dictionary tables.
In the CDS layer you can use and manipulate data that is persisted in the database.
The projection is a subset of the fields of the underlying data model, that are relevant
for the application. For example UI annotations would be part of a projection view.
With the service definition you are able to define which data is exposed as a business
service.
Service bindings allow you to bind service definitions to a client-server communication
protocol such as OData. The service binding is used to start the SAP Fiori Elements
App Preview, which makes the application visible on the UI.
To develop a read-only application you need to carry out the steps contain in the
dashed rectangle.
Get to know the transactional behavior
The behavior definition determines the create, update and delete functionality.
The behavior implementation provides the implementation of a behavior. In the
managed approach (Greenfield implementation), the implementation of create, update
and delete is done automatically.
To develop a full transactional application the steps in the dashed rectangle are
required in addition.
Learn how to enhance behavior
You are able to check the data consistency of an existing instance of an entity by
adding validations.
Actions can be used as part of the business logic to execute non-standard operations,
such as status change.
To develop additional custom logic such as validations and actions the steps in the
dashed rectangle need to be carried out.
Create Table Persistence and Generate Data
Step 1: Create ABAP package
Open ABAP Development Tools (ADT) and select your ABAP Cloud Project you
created in Cloud.
Right-click on ZLOCAL and select ABAP Package as shown below.
Create a new ABAP package:
Name: ZTRAVEL_APP_XXX
Description: Package for travel XXX
Use your number instead of XXX .
Click Next >.
ZLOCAL will be added as software component. Click Next >.
Select Create new request and enter a request description.
Right-click on Favorite Packages and select Add Package.
Search for ZTRAVEL_APP_XXX , select it and click OK to add your package in the favorite
packages section.
Create a new database table:
Name: ZTRAVEL_XXX
Description: Database table for travel data XXX
Click Next >.
Click Finish to create your transport request.
Replace your code with following:
@EndUserText.label : 'Database table for travel data XXX'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #LIMITED
define table ztravel_xxx {
key client : abap.clnt not null;
key mykey : sysuuid_x16 not null;
travel_id : /dmo/travel_id;
agency_id : /dmo/agency_id;
customer_id : /dmo/customer_id;
begin_date : /dmo/begin_date;
end_date : /dmo/end_date;
@Semantics.amount.currencyCode : 'ztravel_xxx.currency_code'
booking_fee : /dmo/booking_fee;
@Semantics.amount.currencyCode : 'ztravel_xxx.currency_code'
total_price : /dmo/total_price;
currency_code : /dmo/currency_code;
description : /dmo/description;
overall_status : /dmo/overall_status;
created_by : syuname;
created_at : timestampl;
last_changed_by : syuname;
last_changed_at : timestampl;
}
Save and activate.
Create ABAP class
Right-click on your package ZTRAVEL_APP_XXX , select New > ABAP Class.
Create a new ABAP class:
Name: ZCL_GENERATE_TRAVEL_DATA_XXX
Description: Class for generating travel data
Click Next >.
Click Finish to create your transport request.
Replace your code with following:
CLASS ZCL_GENERATE_TRAVEL_DATA_XXX DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES IF_OO_ADT_CLASSRUN.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ZCL_GENERATE_TRAVEL_DATA_XXX IMPLEMENTATION.
METHOD IF_OO_ADT_CLASSRUN~MAIN.
DATA:itab TYPE TABLE OF ztravel_xxx.
* read current timestamp
GET TIME STAMP FIELD DATA(zv_tsl).
* fill internal travel table (itab)
itab = VALUE #(
( mykey = '02D5290E594C1EDA93815057FD946624' travel_id = '00000022' agency_id = '070001' customer_id
= '000077' begin_date = '20190624' end_date = '20190628' booking_fee = '60.00' total_price = '750.00'
currency_code = 'USD'
description = 'mv' overall_status = 'A' created_by = 'MUSTERMANN' created_at =
'20190612133945.5960060' last_changed_by = 'MUSTERFRAU' last_changed_at =
'20190702105400.3647680' )
( mykey = '02D5290E594C1EDA93815C50CD7AE62A' travel_id = '00000106' agency_id = '070005'
customer_id = '000005' begin_date = '20190613' end_date = '20190716' booking_fee = '17.00' total_price =
'650.00' currency_code = 'AFN'
description = 'Enter your comments here' overall_status = 'A' created_by = 'MUSTERMANN' created_at =
'20190613111129.2391370' last_changed_by = 'MUSTERMANN' last_changed_at = '20190711140753.1472620' )
( mykey = '02D5290E594C1EDA93858EED2DA2EB0B' travel_id = '00000103' agency_id = '070010'
customer_id = '000011' begin_date = '20190610' end_date = '20190714' booking_fee = '17.00' total_price =
'800.00' currency_code = 'AFN'
description = 'Enter your comments here' overall_status = 'X' created_by = 'MUSTERFRAU' created_at =
'20190613105654.4296640' last_changed_by = 'MUSTERFRAU' last_changed_at = '20190613111041.2251330' )
).
* delete existing entries in the database table
DELETE FROM ztravel_xxx.
* insert the new table entries
INSERT ztravel_xxx FROM TABLE @itab.
* check the result
SELECT * FROM ztravel_xxx INTO TABLE @itab.
out->write( sy-dbcnt ).
out->write( 'Travel data inserted successfully!').
ENDMETHOD.
ENDCLASS.
Save, activate and click F9 to run your ABAP class.
Switch to your database table and press F8 to see your data.
Define and Expose a CDS-Based Travel Data Model
Right-click on your package ZTRAVEL_APP_XXX , select New > Other ABAP Repository Object.
Search for data definition, select it and click Next >.
Create a data definition:
Name: ZI_TRAVEL_M_XXX
Description: Data model for travel
Click Next >.
Click Finish to use your transport request.
Define root view for ZI_TRAVEL_M_XXX and database table as source.
define root view ZI_TRAVEL_M_XXX as select from ztravel_xxx .
Your result should look like this. Replace your code with following:
@AbapCatalog.sqlViewName: 'ZVI_TRAVEL_M_XXX'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Travel data - XXX'
define root view ZI_TRAVEL_M_XXX
as select from ztravel_xxx as Travel
/* Associations */
association [0..1] to /DMO/I_Agency as _Agency on $projection.agency_id = _Agency.AgencyID
association [0..1] to /DMO/I_Customer as _Customer on $projection.customer_id = _Customer.CustomerID
association [0..1] to I_Currency as _Currency on $projection.currency_code = _Currency.Currency
key mykey,
travel_id,
agency_id,
customer_id,
begin_date,
end_date,
@Semantics.amount.currencyCode: 'currency_code'
booking_fee,
@Semantics.amount.currencyCode: 'currency_code'
total_price,
@Semantics.currencyCode: true
currency_code,
overall_status,
description,
/*-- Admin data --*/
@Semantics.user.createdBy: true
created_by,
@Semantics.systemDateTime.createdAt: true
created_at,
@Semantics.user.lastChangedBy: true
last_changed_by,
@Semantics.systemDateTime.lastChangedAt: true
last_changed_at,
/* Public associations */
_Agency,
_Customer,
_Currency
Save and activate.
Create projection view for travel
Right-click on your package ZTRAVEL_APP_XXX , select New > Other ABAP Repository
Object.
Search for data definition, select it and click Next >.
Create a data definition:
Name: ZC_TRAVEL_M_XXX
Description: Projection view for travel
Click Next >.
Click Finish to use your transport request.
Define root view entity for ZC_TRAVEL_M_XXX .
define root view entity ZC_TRAVEL_M_XXX as projection on ZI_Travel_M_XXX .
Your result should look like this. Replace your code with following:
@EndUserText.label: 'Travel projection view - Processor'
@AccessControl.authorizationCheck: #CHECK
@UI: {
headerInfo: { typeName: 'Travel', typeNamePlural: 'Travels', title: { type: #STANDARD, value:
'TravelID' } } }
@Search.searchable: true
define root view entity ZC_TRAVEL_M_XXX
as projection on ZI_TRAVEL_M_XXX
{
@UI.facet: [ { id: 'Travel',
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: 'Travel',
position: 10 } ]
@UI.hidden: true
key mykey as TravelUUID,
@UI: {
lineItem: [ { position: 10, importance: #HIGH } ],
identification: [ { position: 10, label: 'Travel ID [1,...,99999999]' } ] }
@Search.defaultSearchElement: true
travel_id as TravelID,
@UI: {
lineItem: [ { position: 20, importance: #HIGH } ],
identification: [ { position: 20 } ],
selectionField: [ { position: 20 } ] }
@Consumption.valueHelpDefinition: [{ entity : {name: '/DMO/I_Agency', element: 'AgencyID' } }]
@ObjectModel.text.element: ['AgencyName'] ----meaning?
@Search.defaultSearchElement: true
agency_id as AgencyID,
_Agency.Name as AgencyName,
@UI: {
lineItem: [ { position: 30, importance: #HIGH } ],
identification: [ { position: 30 } ],
selectionField: [ { position: 30 } ] }
@Consumption.valueHelpDefinition: [{ entity : {name: '/DMO/I_Customer', element: 'CustomerID'
} }]
@ObjectModel.text.element: ['CustomerName']
@Search.defaultSearchElement: true
customer_id as CustomerID,
@UI.hidden: true
_Customer.LastName as CustomerName,
@UI: {
lineItem: [ { position: 40, importance: #MEDIUM } ],
identification: [ { position: 40 } ] }
begin_date as BeginDate,
@UI: {
lineItem: [ { position: 41, importance: #MEDIUM } ],
identification: [ { position: 41 } ] }
end_date as EndDate,
@UI: {
lineItem: [ { position: 50, importance: #MEDIUM } ],
identification: [ { position: 50, label: 'Total Price' } ] }
@Semantics.amount.currencyCode: 'CurrencyCode'
total_price as TotalPrice,
@Consumption.valueHelpDefinition: [{entity: {name: 'I_Currency', element: 'Currency' }}]
currency_code as CurrencyCode,
@UI: {
lineItem: [ { position: 60, importance: #HIGH },
{ type: #FOR_ACTION, dataAction: 'acceptTravel', label: 'Accept Travel' } ],
identification: [ { position: 60, label: 'Status [O(Open)|A(Accepted)|X(Canceled)]' } ] }
overall_status as TravelStatus,
@UI.identification: [ { position: 70, label: 'Remarks' } ]
description as Description,
@UI.hidden: true
last_changed_at as LastChangedAt
Save and activate.
Create service definition
Right-click on your data definition ZC_TRAVEL_M_XXX and select New Service Definition.
Create a new service definition:
Name: ZUI_C_TRAVEL_M_XXX
Description: Service definition for travel
Click Next >.
Click Finish to use your transport request.
Replace your code with following:
@EndUserText.label: 'Service Definition for ZC_Travel_M_XXX'
define service ZUI_C_TRAVEL_M_XXX
expose ZC_TRAVEL_M_XXX as TravelProcessor;
expose /DMO/I_Customer as Passenger;
expose /DMO/I_Agency as TravelAgency;
expose /DMO/I_Airport as Airport;
expose I_Currency as Currency;
expose I_Country as Country;
Save and activate.
With the service definition you are able to define which data is exposed as a business service
in your travel booking application.
Create service binding
Right-click on your service definition ZUI_C_TRAVEL_M_XXX and select New Service Binding.
Create a new service binding:
Name: ZUI_C_TRAVEL_M_XXX
Description: Service binding for travel
Binding Type: ODATA V2 - UI
Click Next >.
Click Finish to use your transport request.
Activate your service binding.
1. Now your service binding is created and you are able to see your service with its
entities and associations.
The service binding allows you to bind the service definition to an ODATA protocol.
Therefore you are able to see the travel booking application on the UI.
2. Double-click on TravelProcessor to see the application on the UI.
Logon to your ABAP system.
Click GO to see your result.
Your columns are created. The annotation ensures that all columns are already
selected. As you can see, buttons like, create and update are missing. Therefore you
need to define your behavior definition.
Create Behavior Definition for Managed Scenario
Right-click on your data definition ZI_TRAVEL_M_XXX and select New Behavior
Definition.
Check your behavior definition. Your implementation type is managed.
Click Next >.
Click Finish to use your transport request.
Replace your code with following.
managed implementation in class ZCL_BP_I_TRAVEL_M_XXX unique;
define behavior for ZI_Travel_M_XXX alias Travel
persistent table ztravel_xxx
etag master last_changed_at
lock master
{
// administrative fields (read only)
field ( readonly ) last_changed_at, last_changed_by, created_at, created_by;
// mandatory fields that are required to create a travel
field ( mandatory ) agency_id, overall_status, booking_fee, currency_code;
// semantic key is calculated in a determination
field ( readonly ) travel_id;
// standard operations for travel entity
create;
update;
delete;
}
Save and activate.
A warning will appear first, but after the creation of the behavior implementation it will
disappear.
Now the behavior definition is created and determines the create, update and delete
functionality for travel booking.
Create behavior definition for projection view
Right-click on your data definition ZC_TRAVEL_M_XXX and select New Behavior
Definition.
Check your behavior definition. Your implementation type is projection.
Click Next >.
Click Finish to use your transport request.
Replace your code with following:
projection;
define behavior for ZC_TRAVEL_M_XXX alias TravelProcessor
use etag
// scenario specific field control
field ( mandatory ) BeginDate, EndDate, CustomerID;
use create;
use update;
use delete;
Save and activate.
Now switch to your service binding and double click on TravelProcessor .
Refresh your browser and check your result.
The create and delete button appears on the UI because of the managed scenario. You
can create and edit travel bookings or you’ re able to delete existing ones.
Enhance Behavior With Action and Validation
Switch to your behavior definition ZI_TRAVEL_M_XXX and add following action and validation
to your coding:
// instance action and dynamic action control
action ( features : instance ) acceptTravel result [1] $self;
// validations
validation validateCustomer on save { field customer_id; }
validation validateDates on save { field begin_date, end_date; }
// determination
determination CalculateTravelKey on modify
{ create; }
Your result should look like this. Replace your code with following:
managed implementation in class ZCL_BP_I_TRAVEL_M_XXX unique;
define behavior for ZI_TRAVEL_M_XXX alias Travel
persistent table ztravel_xxx
etag master last_changed_at
lock master
// key that will be automatically generated by the framework
field ( readonly, numbering : managed ) mykey;
// semantic key calculated in a determination
field ( readonly ) travel_id;
// administrative fields (read only)
field ( readonly ) last_changed_at, last_changed_by, created_at, created_by;
// mandatory fields that are required to create a travel
field ( mandatory ) agency_id, overall_status, booking_fee, currency_code;
// standard operations for travel entity
create;
update;
delete;
// instance action and dynamic action control
action ( features : instance ) acceptTravel result [1] $self;
// validations
validation validateCustomer on save { field customer_id; }
validation validateDates on save { field begin_date, end_date; }
// determination
determination CalculateTravelKey on modify
{ create; }
Save and activate.
Enhance behavior definition for projection view
use action acceptTravel;
Your result should look like this. Replace your code with following:
projection;
define behavior for ZC_TRAVEL_M_XXX alias TravelProcessor
use etag
// scenario specific field control
field ( mandatory ) BeginDate, EndDate, CustomerID;
use create;
use update;
use delete;
use action acceptTravel;
Save and activate.
The validation allows you to check the data consistency of your travel booking
application.
By using actions your are able to change the status of your booking status.
Create implementation class
In your behavior definition ZI_Travel_M_XXX set the cursor before the implementation
class ZCL_BP_I_TRAVEL_M_XXX and click CTRL + 1. Double-click on Create behavior
implementation class zcl_bp_i_travel_m_xxx to create your implementation class.
Create a new behavior implementation:
Description: Behavior implementation for ZI_TRAVEL_M_XXX
Click Next >.
Click Finish to use your transport request.
Enhance behavior implementation
Open your behavior implementation ZCL_BP_I_TRAVEL_M_XXX and switch to global
class to replace your code.
In your global class replace your code with following:
CLASS zcl_bp_i_travel_m_xxx DEFINITION
PUBLIC
ABSTRACT
FINAL
FOR BEHAVIOR OF ZI_Travel_M_XXX.
ENDCLASS.
CLASS zcl_bp_i_travel_m_xxx IMPLEMENTATION.
ENDCLASS.
Open your behavior implementation ZCL_BP_I_TRAVEL_M_XXX and switch to local types to
replace your code.
In your local types replace your code with following:
*"* use this source file for the definition and implementation of
*"* local helper classes, interface definitions and type
*"* declarations
CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
TYPES tt_travel_update TYPE TABLE FOR UPDATE zi_travel_m_xxx.
METHODS validate_customer FOR VALIDATION travel~validateCustomer
IMPORTING keys FOR travel.
METHODS validate_dates FOR VALIDATION travel~validateDates
IMPORTING keys FOR travel.
METHODS set_status_completed FOR MODIFY IMPORTING keys FOR
ACTION travel~acceptTravel RESULT result.
METHODS get_features FOR FEATURES IMPORTING keys REQUEST
requested_features FOR travel RESULT result.
METHODS CalculateTravelKey FOR DETERMINATION Travel~CalculateTravelKey
IMPORTING keys FOR Travel.
ENDCLASS.
CLASS lhc_travel IMPLEMENTATION.
**********************************************************************
* Validate customer data when saving travel data
*
**********************************************************************
METHOD validate_customer.
READ ENTITY zi_travel_m_xxx\\travel FROM VALUE #(
FOR <root_key> IN keys ( %key = <root_key>
%control = VALUE #( customer_id = if_abap_behv=>mk-on ) ) )
RESULT DATA(lt_travel).
DATA lt_customer TYPE SORTED TABLE OF /dmo/customer WITH UNIQUE KEY
customer_id.
" Optimization of DB select: extract distinct non-initial customer IDs
lt_customer = CORRESPONDING #( lt_travel DISCARDING DUPLICATES
MAPPING customer_id = customer_id EXCEPT * ).
DELETE lt_customer WHERE customer_id IS INITIAL.
CHECK lt_customer IS NOT INITIAL.
" Check if customer ID exist
SELECT FROM /dmo/customer FIELDS customer_id
FOR ALL ENTRIES IN @lt_customer
WHERE customer_id = @lt_customer-customer_id
INTO TABLE @DATA(lt_customer_db).
" Raise msg for non existing customer id
LOOP AT lt_travel INTO DATA(ls_travel).
IF ls_travel-customer_id IS NOT INITIAL AND NOT
line_exists( lt_customer_db[ customer_id = ls_travel-customer_id ] ).
APPEND VALUE #( mykey = ls_travel-mykey ) TO failed.
APPEND VALUE #( mykey = ls_travel-mykey
%msg = new_message( id =
/dmo/cx_flight_legacy=>customer_unkown-msgid
number = /dmo/cx_flight_legacy=>customer_unkown-
msgno
v1 = ls_travel-customer_id
severity = if_abap_behv_message=>severity-error )
%element-customer_id = if_abap_behv=>mk-on ) TO reported.
ENDIF.
ENDLOOP.
ENDMETHOD.
**********************************************************************
* Check validity of date
**********************************************************************
METHOD validate_dates.
READ ENTITY zi_travel_m_xxx\\travel FROM VALUE #(
FOR <root_key> IN keys ( %key = <root_key>
%control = VALUE #( begin_date = if_abap_behv=>mk-on
end_date = if_abap_behv=>mk-on ) ) )
RESULT DATA(lt_travel_result).
LOOP AT lt_travel_result INTO DATA(ls_travel_result).
IF ls_travel_result-end_date < ls_travel_result-begin_date. "end_date before
begin_date
APPEND VALUE #( %key = ls_travel_result-%key
mykey = ls_travel_result-mykey ) TO failed.
APPEND VALUE #( %key = ls_travel_result-%key
%msg = new_message( id =
/dmo/cx_flight_legacy=>end_date_before_begin_date-msgid
number =
/dmo/cx_flight_legacy=>end_date_before_begin_date-msgno
v1 = ls_travel_result-begin_date
v2 = ls_travel_result-end_date
v3 = ls_travel_result-travel_id
severity = if_abap_behv_message=>severity-error )
%element-begin_date = if_abap_behv=>mk-on
%element-end_date = if_abap_behv=>mk-on ) TO reported.
ELSEIF ls_travel_result-begin_date < cl_abap_context_info=>get_system_date( ).
"begin_date must be in the future
APPEND VALUE #( %key = ls_travel_result-%key
mykey = ls_travel_result-mykey ) TO failed.
APPEND VALUE #( %key = ls_travel_result-%key
%msg = new_message( id =
/dmo/cx_flight_legacy=>begin_date_before_system_date-msgid
number =
/dmo/cx_flight_legacy=>begin_date_before_system_date-msgno
severity = if_abap_behv_message=>severity-error )
%element-begin_date = if_abap_behv=>mk-on
%element-end_date = if_abap_behv=>mk-on ) TO reported.
ENDIF.
ENDLOOP.
ENDMETHOD.
********************************************************************************
* Implements travel action (in our case: for setting travel overall_status to completed)
********************************************************************************
METHOD set_status_completed.
" Modify in local mode: BO-related updates that are not relevant for authorization
checks
MODIFY ENTITIES OF zi_travel_m_xxx IN LOCAL MODE
ENTITY travel
UPDATE FROM VALUE #( FOR key IN keys ( mykey = key-mykey
overall_status = 'A' " Accepted
%control-overall_status = if_abap_behv=>mk-on ) )
FAILED failed
REPORTED reported.
" Read changed data for action result
READ ENTITIES OF zi_travel_m_xxx IN LOCAL MODE
ENTITY travel
FROM VALUE #( FOR key IN keys ( mykey = key-mykey
%control = VALUE #(
agency_id = if_abap_behv=>mk-on
customer_id = if_abap_behv=>mk-on
begin_date = if_abap_behv=>mk-on
end_date = if_abap_behv=>mk-on
booking_fee = if_abap_behv=>mk-on
total_price = if_abap_behv=>mk-on
currency_code = if_abap_behv=>mk-on
overall_status = if_abap_behv=>mk-on
description = if_abap_behv=>mk-on
created_by = if_abap_behv=>mk-on
created_at = if_abap_behv=>mk-on
last_changed_by = if_abap_behv=>mk-on
last_changed_at = if_abap_behv=>mk-on
)))
RESULT DATA(lt_travel).
result = VALUE #( FOR travel IN lt_travel ( mykey = travel-mykey
%param = travel
) ).
ENDMETHOD.
********************************************************************************
* Implements the dynamic feature handling for travel instances
*
********************************************************************************
METHOD get_features.
"%control-<fieldname> specifies which fields are read from the entities
READ ENTITY zi_travel_m_xxx FROM VALUE #( FOR keyval IN keys
( %key = keyval-%key
" %control-travel_id = if_abap_behv=>mk-on
%control-overall_status = if_abap_behv=>mk-on
))
RESULT DATA(lt_travel_result).
result = VALUE #( FOR ls_travel IN lt_travel_result
( %key = ls_travel-%key
%features-%action-acceptTravel = COND #( WHEN ls_travel-
overall_status = 'A'
THEN if_abap_behv=>fc-o-disabled ELSE
if_abap_behv=>fc-o-enabled )
) ).
ENDMETHOD.
METHOD calculatetravelkey.
SELECT FROM ztravel_xxx
FIELDS MAX( travel_id ) INTO @DATA(lv_max_travel_id).
LOOP AT keys INTO DATA(ls_key).
lv_max_travel_id = lv_max_travel_id + 1.
MODIFY ENTITIES OF zi_travel_m_xxx IN LOCAL MODE
ENTITY Travel
UPDATE SET FIELDS WITH VALUE #( ( mykey = ls_key-mykey
travel_id = lv_max_travel_id ) )
REPORTED DATA(ls_reported).
APPEND LINES OF ls_reported-travel TO reported-travel.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
Save and activate.
Now switch to your service binding and double click on TravelProcessor .
Check your result.
The behavior implementation is created for travel booking. By using the managed
approach, the implementation of create, update and delete is done automatically.
The accept travel button appears. Create a new travel booking with the booking status
O. O stands for open. Save your travel booking and you are able to accept your created
travel booking.
Hint: If your accept travel button does not appear, wait a few minutes or deactivate your
service binding and activate it again.
Create and Deploy HTML5 and SAP Fiori Launchpad Site
Modules
Create multi-target application
If you are using your trial user, then login to your SAP Cloud Platform trial cockpit and
select Launch SAP Web IDE.
Otherwise login to your SAP Cloud Platform cockpit, click Services, choose SAP Web
IDE Full-Stack and click Go to Service.
In your SAP Web IDE account select File > New > Project from Template.
Search for multi-target, select Multi-Target Application and click Next.
Enter project name MTA_Project_XXX and click Next.
Enter MTA_Project_XXX as application ID, select 0.0.1 as application
version. Check Use HTML5 Application Repository and click Finish.
Step 2: Copy API endpoint
Login to your SAP Cloud Platform cockpit trial and select trial.
Or Login to your SAP Cloud Platform cockpit and select your global account.
Select Subaccounts and your subaccount.
Copy your API endpoint for later use.
Step 3: Configure project settings
Switch to SAP Web IDE and right-click on your
project MTA_Project_XXX select Project > Project Settings.
Select Cloud Foundry as Project and custom Cloud Foundry settings.
API Endpoint: <your_api_endpoint>
Organization: <your_organization>
Space: <your_space>
Click Save.
Add ABAP service to multi-target application
Select your project MTA_Project_XXX > New > SAP Cloud Platform Service.
If you are using the SAP Cloud Platform trial cockpit, search for ABAP, select abap-
trial and click Next.
If you are using the SAP Cloud Platform cockpit, then search for ABAP, select it and
click Next.
Select Reuse instance, your instance, provide a resource name and click Finish.
Create HTML5 module
Right-click on your project MTA_Project_XXX and select New > HTML5 Module.
Choose List Report Application and click Next.
Provide following information:
Module Name: TRAVEL_APP_XXX
Title: TRAVEL_APP_XXX
Namespace: namespace_xxx
Click Next.
Select SAP Cloud Platform Service, then click on your resource.
Logon to SAP Cloud Platform ABAP environment trial or SAP Cloud Platform ABAP
environment and switch back to SAP Web IDE.
Select your resource ZUI_C_TRAVEL_M_XXX and click Next.
Check Selected Service Metadata and click Next.
Select TravelProcessor as OData collection and click Finish.
Remove destination service resource
Open your mta.yaml file, click on MTA Editor and Resources.
Select your destination resource dest_MTA_Project_XXX and delete it.
Save your mta.yaml file.
Test UI on Cloud Foundry
Right-click on TRAVEL_APP_XXX and select Run > Run Configurations.
Click + to add a new run configuration.
Select Run as Web Application.
Create your run configuration.
Name: Run TRAVEL APP XXX on Cloud Foundry
Select your flpSandbox.html file.
Click Run on Cloud Foundry, select Without Frame and click Save and Run.
Logon to your SAP Cloud Platform ABAP environment trial or SAP Cloud Platform
ABAP environment.
Select the TRAVEL_APP_XXX tile to test your application.
Select Go, to see your result.
Check your result.
Create SAP Fiori launchpad site module
Open SAP Web IDE and right-click on your project MTA_Project_XXX and
select New > SAP Fiori Launchpad Site Module.
Create a SAP Fiori launchpad site module:
Module name: FLP_Site_Module_XXX
Click Finish.
Create inbound tile
Open manifest.json and select Navigation.
Create semantic object:
Semantic object: Travel_App_XXX
Action: display
Create inbound tile:
Title: Travel_App_XXX
Subtitle: Travel_booking_application
icon: sap-icon://sap-logo-shape
Save your changes.
Create SAP Fiori launchpad site module
Open the CommonDataModel.json file in FLP_Site_Module_XXX and click Add Group.
Create new group:
Group name: Travel App XXX
Click on your group.
Add your project app Travel_App_XXX to your group and click Select.
Now your project app Travel_App_XXX is added to your group.
Deploy UI to Cloud Foundry
Right click on MTA_Project_XXX and select Build > Build with Cloud MTA Build Tool
(recommended).
Open mta_archives .
Right-click on MTA_Project_XXX_0.0.1.mtar , select Deploy > Deploy to SAP Cloud
Platform.
Deploy your mtar file to SAP Cloud Platform.
Cloud Foundry API Endpoint: <your_api_endpoint>
Organization: <your_organization>
Space: <your_space>
Click Deploy.
Run application on Cloud Foundry as business user
Open SAP Cloud Platform cockpit trial or SAP Cloud Platform cockpit and navigate to
your trial subaccount. Select your space dev.
Run your app router mta-project-xxx-approuter
Select mta-project-xxx-approuter .
Click on your application routes to open your application in your launchpad.
Logon to your SAP Cloud Platform ABAP environment trial or SAP Cloud Platform
ABAP environment system.
You application is now available as a tile in the launchpad. Select your
application Travel_App_XXX .
Click Go to see your result.
Check your result.