Exercises Wtih Solution
Exercises Wtih Solution
Exercise 1.....................................................................................................................................................2
Exercise 2.....................................................................................................................................................4
Exercise 3.....................................................................................................................................................5
Exercise 4.....................................................................................................................................................6
Exercise 5.....................................................................................................................................................7
Exercise 6.....................................................................................................................................................8
Exercise 7...................................................................................................................................................10
Exercise 8...................................................................................................................................................11
Exercise 9...................................................................................................................................................13
Exercise 10.................................................................................................................................................16
Exercise 11.................................................................................................................................................17
Exercise 12.................................................................................................................................................19
Exercise 13.................................................................................................................................................21
Final CDS Views (Exercises 14 and 15).......................................................................................................23
Policy BO View.......................................................................................................................................23
Person Insured BO View........................................................................................................................23
Policy Consumption View......................................................................................................................24
Person Insured Consumption View........................................................................................................25
Exercise 1
• Create a new program ZAXX_SELECT_CARRIER in your development package (ZXX_ABAP_HANA)
Select all fields from the carrier table SCARR
Output your selection on the screen (WRITE and NEW-LINE statements)
• Open the SQL console and select all carriers with currency code USD (field currcode)
Program
*&---------------------------------------------------------------------*
*& Report zzmh_ex01
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zzmh_ex01.
@AbapCatalog.sqlViewName: 'ZMH_SEL_CARR_01'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Select Carrier'
define view ZMH_SELECT_CARRIER_01 as select from scar
{
carrid,
carrname,
currcode,
url
}
*&---------------------------------------------------------------------*
*& Report ZZMH_CARR_01_SEL
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZZMH_CARR_01_SEL.
DATA cx_sql TYPE REF TO CX_SY_SQL_ERROR.
DATA lt_carr TYPE TABLE OF ZMH_SELECT_CARRIER_01.
TRY.
SELECT * FROM ZMH_SELECT_CARRIER_01
INTO TABLE @lt_carr
WHERE currcode = 'USD'.
LOOP AT lt_carr ASSIGNING FIELD-SYMBOL(<lfs_carr>).
WRITE: <lfs_carr>-carrid, <lfs_carr>-carrname, <lfs_carr>-currcode.
NEW-LINE.
ENDLOOP.
CATCH cx_sy_sql_error INTO cx_sql.
REFRESH lt_carr.
MESSAGE cx_sql->get_text( ) TYPE 'E' RAISING error.
ENDTRY.
Exercise 2
• Create a new CDS view ZAXX_CDS_SCARR in your package
• DDIC view name is ZAXX_SCARR
• Select the fields carrid, carrname and currcode from table scarr
• Use aliases for all tables and fields:
• carrid = carrierID – Key field
• carrname = carrierName
• currcode = currencyCode
• scarr = carrier
• Save the view and activate it. Execute the data browser and look at the result (F8)
• Also have a look at the created DDIC view (place cursor on DDIC view name and press F3)
• Add the currency code text from table TCURT to your CDS view
• Add an inner join to table TCURT (alias currencyText) to the CDS view. Join on the fields
currcode and waers
• Add the currency long text to the fields (table field ltext, alias currencyLongText)
• Add a where clause to the CDS view which only select English currency texts (spras = ‘E’)
CDS View
@AbapCatalog.sqlViewName: 'ZMH_SEL_CARR_02'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Example 2'
define view ZMH_SELECT_CARRIER_02 as select from scarr as carrier
inner join tcurt as currencyText on
currencyText.waers = carrier.currcode and currencyText.spras = 'E'
{
key carrier.carrid as carrierID,
carrier.carrname as carrierName,
carrier.currcode as currencyCode,
currencyText.ltext as currencyLongtext
}
Exercise 3
• Create a new CDS view ZAXX_CDS_SCARR_ASSOC in your package
DDIC view name: ‘ZAXX_SCA_ASSOC’
Rebuild the view of exercise 2. Use an association instead of a join
Instead of the currency long text, include the link to the TCURT table
• View the result of the view in the data browser (F8)
CDS View
@AbapCatalog.sqlViewName: 'ZMH_SEL_CARR_03'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Example 3'
define view ZMH_SELECT_CARRIER_03 as select from scarr as carrier
association [1..1] to tcurt as _currencyText on
carrier.currcode = _currencyText.waers and _currencyText.spras = 'E'
{
key carrier.carrid as carrierID,
carrier.carrname as carrierName,
carrier.currcode as currencyCode,
_currencyText
}
Exercise 4
• Create a new CDS view ZAXX_CDS_SPFLI_CASE in your package
DDIC view: ‘ZAXX_SPF_CASE’
Select the carrid, connid and distance columns from table spfli
Create a new Case statement which categorizes the flight distance
• If the distance is more than 3000 then the category should be ‘Long-Haul ‘
• If the distance is between 1000 and 3000 then the category should be
‘Medium-Haul’
• If the distance is less than 1000 the category should be ‘Short-Haul’
CDS View
@AbapCatalog.sqlViewName: 'ZMH_SEL_CARR_04'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Example 3'
define view ZMH_SELECT_CARRIER_04 as select from spfli as schedule
association [1..1] to scarr as _carrier
on schedule.carrid = _carrier.carrid
{
_carrier,
key schedule.carrid,
key schedule.connid,
_carrier.carrname,
schedule.cityfrom,
schedule.cityto,
schedule.distance,
case when schedule.distance > 3000 then 'Long Haul'
when schedule.distance > 1000 then 'Medium Haul'
else 'Short Haul'
end as distance_rating
}
Exercise 5
• Create a new CDS view ZAXX_CDS_SFLIGHT_CURR in your package
Select the columns carrid, connid, fldate, price, currency from table sflight
Convert the price into USD. Use the currency_conversion function
• Source currency is the currency field
• Amount is the price field
• Use the fldate as exchange rate date
• Target currency is USD. Since USD is a char type and the target currency field is a
cuky field you have to cast here: cast ('USD' as abap.cuky( 5 ))
CDS View
@AbapCatalog.sqlViewName: 'ZMH_SEL_CARR_05'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Example 5'
define view ZMH_SELECT_CARRIER_05 as select from sflight as flight
{
key flight.carrid,
key flight.connid,
key flight.fldate,
@Semantics.amount.currencyCode: 'flight.currency'
flight.price,
@Semantics.currencyCode: true
flight.currency,
currency_conversion(
amount => price,
source_currency => currency,
target_currency => cast ( 'USD' as abap.cuky( 5 )),
exchange_rate_date => fldate,
error_handling => 'SET_TO_NULL'
) as usdPrice
}
Exercise 6
Exercise 7
• Create the CDS BO model ZAXX_BO_POLICY for your policy BO based on table ZAXX_POLICY
Define the view as a BO view: @ObjectModel.modelCategory: #BUSINESS_OBJECT
Define the view as the root of the BO model: @ObjectModel.compositionRoot: true
Enable transactional processing for the view:
@ObjectModel.transactionalProcessingEnabled: true
Define your ZAXX_POLICY table as the DDIC table for the view:
@ObjectModel.writeActivePersistence: 'ZAXX_POLICY‘
Enable Create, Update and Delete options: @ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true @ObjectModel.updateEnabled: true
Define the Policy ID as the representative key: @ObjectModel.representativeKey:
'Policy_ID’
Add the policy_id, status, type and policyholder fields of the ZAXX_POLICY table to the
view
Define the policy_id field as the key of the view
CDS View
@AbapCatalog.sqlViewName: 'ZMH_BO_POL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Policy BO View'
@ObjectModel.modelCategory: #BUSINESS_OBJECT
@ObjectModel.compositionRoot: true
@ObjectModel.transactionalProcessingEnabled: true
@ObjectModel.writeActivePersistence: 'ZMH_POLICY'
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.representativeKey: 'policy_id'
@AbapCatalog.sqlViewName: 'ZMH_BO_POL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Policy BO View'
@ObjectModel.modelCategory: #BUSINESS_OBJECT
@ObjectModel.compositionRoot: true
@ObjectModel.transactionalProcessingEnabled: true
@ObjectModel.writeActivePersistence: 'ZMH_POLICY'
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.representativeKey: 'policy_id'
@AbapCatalog.sqlViewName: 'ZMH_BO_PERSINS'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Person Insured Business Object View'
@ObjectModel.writeActivePersistence: 'ZMH_PERS_INS'
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.representativeKey: 'person_id'
• Create a new determination for your ZAXX_BO_PERS_INSURED BOPF object which fills the policy
ID field
Name: DETERMINE_IDS
Category: React after modification
Triggers: Create
Accept the default for the implementing class
• Fill the policy ID with the policy ID of the parent object
Use the boRetrieveByAssociation Eclipse template
The template will return a table, you can just read the first entry of that table into a new
reference field lr_zaxx_bo_policy
In the loop over the person insured, also fill the policy ID before the update
• Define the policy ID and person ID fields in the ZAXX_BO_PERS_INSURED view as read only
fields: @ObjectModel.readOnly: true
• Test your BO
Determination of Policy
method /BOBF/IF_FRW_DETERMINATION~EXECUTE.
DATA lt_zmh_bo_policy TYPE ztmhbo_policy.
io_read->retrieve(
EXPORTING
iv_node = zif_mh_bo_policy_c=>sc_node-zmh_bo_policy
it_key = it_key
IMPORTING
et_data = lt_zmh_bo_policy ).
IF ( sy-subrc = 0 ).
lr_bo_policy->policy_id = lv_polid.
io_modify->update(
EXPORTING
iv_node = zif_mh_bo_policy_c=>sc_node-zmh_bo_policy
iv_key = lr_bo_policy->key
is_data = lr_bo_policy
).
ENDIF.
ENDLOOP.
endmethod.
ENDCLASS.
method /BOBF/IF_FRW_DETERMINATION~EXECUTE.
DATA lt_zmh_bo_pers_ins TYPE ztmhbo_pers_ins.
io_read->retrieve(
EXPORTING
iv_node = zif_mh_bo_policy_c=>sc_node-zmh_bo_pers_ins
it_key = it_key
IMPORTING
et_data = lt_zmh_bo_pers_ins ).
io_read->retrieve_by_association(
EXPORTING
iv_node = zif_mh_bo_policy_c=>sc_node-zmh_bo_pers_ins
it_key = it_key
iv_association = zif_mh_bo_policy_c=>sc_association-zmh_bo_pers_ins-to_parent
iv_fill_data = abap_true
IMPORTING
et_data = lt_zmh_bo_policy ).
io_modify->update(
EXPORTING
iv_node = zif_mh_bo_policy_c=>sc_node-zmh_bo_pers_ins
iv_key = lr_bo_pers_ins->key
is_data = lr_bo_pers_ins
).
ENDLOOP.
endmethod.
ENDCLASS.
Exercise 10
• Create a new action SET_CANCELLED for the ZAXX_BO_POLICY BO
Cardinality: Single Instance
Keep default for implementation class
Define the exporting parameters of the action (return node ZAXX_BO_POLICY)
• Implement the EXECUTE method of the generated class
Retrieve the BO
Loop over the retrieved BO table
In the loop, set the status field to CANC
Also, in the loop update the BO
Test the new action
method /BOBF/IF_FRW_ACTION~EXECUTE.
DATA lt_zmh_bo_policy TYPE ztmhbo_policy.
io_read->retrieve(
EXPORTING
iv_node = zif_mh_bo_policy_c=>sc_node-zmh_bo_policy
it_key = it_key
IMPORTING
et_data = lt_zmh_bo_policy ).
io_modify->update(
EXPORTING
iv_node = zif_mh_bo_policy_c=>sc_node-zmh_bo_policy
iv_key = lr_bo_policy->key
is_data = lr_bo_policy
).
ENDIF.
endmethod.
ENDCLASS.
Exercise 11
• Add a new validation VALIDATE_CURRENCY to the ZAXX_BO_PERS_INSURED BO
Validation is a consistency check.
Check has to be executed before saving for the create, update and check triggers
Keep the default for the implementation class
• Implement the EXECUTE method of the generated class
Retrieve the BO
Loop over the retrieved BO table
If the sum insured field is filled, but the currency field is empty, throw an error message.
• Store message ZAH_MESSAGES 001 with parameters first name and last name in
a local message variable
• Add the message to the eo_message object via the add_message method
(instantiate the eo_message object if that’s not the case yet)
IF eo_message IS NOT BOUND.
eo_message = /bobf/cl_frw_factory=>get_message( ).
ENDIF.
eo_message->add_message( ls_message ).
• Add the key of the BO to the IT_FAILED_KEY table
• Test the validation
method /BOBF/IF_FRW_VALIDATION~EXECUTE.
DATA lt_zmh_bo_pers_ins TYPE ztmhbo_pers_ins.
io_read->retrieve(
EXPORTING
iv_node = zif_mh_bo_policy_c=>sc_node-zmh_bo_pers_ins
it_key = it_key
IMPORTING
et_data = lt_zmh_bo_pers_ins ).
MESSAGE e001(ZZMH_POL_MESSAGES)
WITH ls_bo_pers_ins->name_first ls_bo_pers_ins->name_last
INTO ls_message.
ls_failed_key-key = ls_bo_pers_ins->key.
APPEND ls_failed_key TO et_failed_key.
ENDIF.
ENDLOOP.
endmethod.
ENDCLASS.
Exercise 12
• Create a new CDS Consumption view ZAXX_C_POLICY based on the policy BO view
DDIC view ZAXX_C_POL
Enable Create, Update and Delete processing via annotations
Delegate transactional processing to the BO view:
@ObjectModel.transactionalProcessingDelegated: true
Define the Policy ID as the representative key: @ObjectModel.representativeKey:
'Policy_ID‘
Select all fields of the ZAXX_BO_POLICY view
Define the Policy ID field as the key and read only field (@ObjectModel.readOnly: true)
Define the view as consumption view for an Odata service: OData.publish: true
• Register the new service
Go to the /IWFND/MAINT_SERVICE transaction and click Add Service
Enter LOCAL as the System Alias in the following screen and search for your service
(name will be ZAXX_C_POLICY_CDS)
Select your service and click Add Selected Services
• Test your new service in the Gateway client
In the /IWFND/MAINT_SERVICE select your service and click on SAP Gateway Client in
the ICF Nodes section
Select the whole connection via
/sap/opu/odata/sap/ZAXX_C_POLICY_CDS/ZAXX_C_POLICY
Select one entity via /sap/opu/odata/sap/ZAXX_C_POLICY_CDS/ZAXX_C_POLICY(‘<enter
one of the policy IDs you created here>’)
Consumption View
@AbapCatalog.sqlViewName: 'ZMH_C_POL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Policy Consumption View'
@VDM.viewType: #CONSUMPTION
@OData.publish: true
@ObjectModel.transactionalProcessingDelegated: true
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.representativeKey: 'policy_id'
@AbapCatalog.sqlViewName: 'ZMH_C_POL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Policy Consumption View'
@VDM.viewType: #CONSUMPTION
@OData.publish: true
@ObjectModel.transactionalProcessingDelegated: true
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.representativeKey: 'policy_id'
@AbapCatalog.sqlViewName: 'ZMH_C_PERSINS'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Person Insured Consumption View'
@VDM.viewType: #CONSUMPTION
@OData.publish: true
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.representativeKey: 'person_id'
Policy BO View
@AbapCatalog.sqlViewName: 'ZMH_BO_POL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Policy BO View'
@ObjectModel.modelCategory: #BUSINESS_OBJECT
@ObjectModel.compositionRoot: true
@ObjectModel.transactionalProcessingEnabled: true
@ObjectModel.writeActivePersistence: 'ZMH_POLICY'
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.representativeKey: 'policy_id'
@AbapCatalog.sqlViewName: 'ZMH_BO_PERSINS'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Person Insured Business Object View'
@ObjectModel.writeActivePersistence: 'ZMH_PERS_INS'
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.representativeKey: 'person_id'
@AbapCatalog.sqlViewName: 'ZMH_C_POL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Policy Consumption View'
@VDM.viewType: #CONSUMPTION
@OData.publish: true
@ObjectModel.transactionalProcessingDelegated: true
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.representativeKey: 'policy_id'
@UI.headerInfo.typeName: 'Policy'
@UI.headerInfo.typeNamePlural: 'Policies'
@UI.headerInfo.title.value: 'pol_holder'
@UI.headerInfo.title.type: #STANDARD
@UI.headerInfo.description.value: 'policy_id'
@UI.headerInfo.description.type: #STANDARD
@AbapCatalog.sqlViewName: 'ZMH_C_PERSINS'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Person Insured Consumption View'
@VDM.viewType: #CONSUMPTION
@OData.publish: true
@ObjectModel.createEnabled: true
@ObjectModel.deleteEnabled: true
@ObjectModel.updateEnabled: true
@ObjectModel.representativeKey: 'person_id'