├── images ├── readme.md ├── 1085.png ├── intro_0000.png ├── intro_0010.png └── intro_0020.jpg ├── exercises ├── ex3 │ ├── images │ │ ├── readme.md │ │ ├── 2010.png │ │ ├── 2020.png │ │ ├── 2025.png │ │ ├── 2030.png │ │ ├── 2040.png │ │ ├── 2050.png │ │ ├── 2060.png │ │ ├── 2065.png │ │ ├── 2070.png │ │ ├── 2080.png │ │ ├── 2090.png │ │ ├── 2110.png │ │ ├── 2120.png │ │ ├── 2130.png │ │ ├── 2140.png │ │ ├── 2500.png │ │ ├── activate.png │ │ └── mass_activate.png │ ├── sources │ │ ├── ex3_CLAS_zbp_i_rap_inventory_####.txt │ │ ├── EPM_PRODUCT_SOAP.xml │ │ └── ex3_WSDL.txt │ └── README.md ├── ex0 │ ├── images │ │ ├── 0010.png │ │ ├── 0020.png │ │ ├── 0030.png │ │ ├── 0040.png │ │ ├── 0050.png │ │ ├── 0060.png │ │ ├── 0070.png │ │ ├── 0080.png │ │ ├── 0090.png │ │ ├── 0100.png │ │ ├── 0105.png │ │ ├── 0700.png │ │ ├── 0710.png │ │ ├── 0720.png │ │ ├── 0740.png │ │ ├── 0750.png │ │ ├── 0760.png │ │ ├── 0770.png │ │ └── 00_00_0010.png │ ├── readme_import_helper_class.md │ └── README.md ├── ex1 │ ├── images │ │ ├── 0010.png │ │ ├── 0020.png │ │ ├── 0030.png │ │ ├── 0040.png │ │ ├── 0050.png │ │ ├── 0060.png │ │ ├── 0070.png │ │ ├── 0080.png │ │ ├── 0090.png │ │ ├── 0100.png │ │ ├── 0105.png │ │ ├── 0110.png │ │ ├── 0200.png │ │ ├── 0210.png │ │ ├── 0220.png │ │ ├── 0230.png │ │ ├── 0250.png │ │ ├── 0270.png │ │ ├── 0280.png │ │ ├── 0290.png │ │ ├── 0300.png │ │ ├── 0310.png │ │ ├── 0320.png │ │ ├── 0350.png │ │ ├── 0360.png │ │ ├── 0370.png │ │ ├── 0380.png │ │ ├── 0390.png │ │ ├── 0400.png │ │ ├── 0410.png │ │ ├── 0420.png │ │ ├── 0430.png │ │ ├── 0435.png │ │ ├── 0440.png │ │ ├── 0450.png │ │ ├── 0460.png │ │ ├── 0470.png │ │ ├── 0500.png │ │ ├── 0510.png │ │ ├── 0520.png │ │ ├── 0530.png │ │ ├── 0540.png │ │ ├── 0550.png │ │ ├── 0560.png │ │ ├── 0570.png │ │ ├── 1000.png │ │ ├── 1010.png │ │ ├── 1020.png │ │ ├── 1030.png │ │ ├── 1040.png │ │ ├── 1045.png │ │ ├── 1050.png │ │ ├── activate.png │ │ ├── 01_01_0010.png │ │ ├── 01_02_0010.png │ │ ├── 00_001_DEV268.png │ │ ├── 00_002_DEV268.png │ │ ├── 00_003_DEV268.png │ │ ├── 00_004_DEV268.png │ │ └── 00_005_DEV268.png │ ├── sources │ │ ├── ex1_template_for_RAP_GENERATOR.json │ │ ├── ex1_TABL_zrap_inven_####.txt │ │ ├── ex1_CLAS_zbp_i_rap_inventory_####.txt │ │ └── zcl_generate_dev268.txt │ └── README.md └── ex2 │ ├── images │ ├── 1000.png │ ├── 1005.png │ ├── 1010.png │ ├── 1020.png │ ├── 1022.png │ ├── 1024.png │ ├── 1026.png │ ├── 1030.png │ ├── 1040.png │ ├── 1050.png │ ├── 1060.png │ ├── 1070.png │ ├── 1080.png │ ├── 1085.png │ ├── 1090.png │ ├── 1100.png │ ├── 1110.png │ ├── 1120.png │ ├── 1130.png │ ├── 1135.png │ ├── 1137.png │ ├── 1139.png │ ├── 1160.png │ ├── 1170.png │ ├── 1200.png │ ├── 1210.png │ ├── 1220.png │ ├── 1230.png │ ├── 1240.png │ ├── 1250.png │ ├── 1260.png │ ├── 1270.png │ ├── 1280.png │ ├── 1290.png │ ├── 1295.png │ ├── 1300.png │ ├── 1310.png │ ├── 1320.png │ ├── 1330.png │ ├── 1340.png │ ├── 1350.png │ ├── 1355.png │ ├── 1360.png │ ├── 1370.png │ ├── 1380.png │ ├── 1390.png │ ├── activate.png │ ├── 02_01_0010.png │ └── 02_02_0010.png │ ├── sources │ ├── ex2_SRVD_ZUI_RAP_INVENTORY_####.txt │ ├── ex2_DDLS_ZCE_RAP_PRODUCTS_####.txt │ ├── ex2_CLAS_zcl_ce_rap_products_####_step_1.txt │ ├── zcl_ce_rap_products_#### │ └── ex2_CLAS_zcl_ce_rap_products_####_final.txt │ └── README.md ├── .abapgit.xml ├── src ├── #dmo#cl_gen_dev268_artifacts.clas.xml └── #dmo#cl_gen_dev268_artifacts.clas.abap ├── .reuse └── dep5 ├── README.md ├── LICENSES └── Apache-2.0.txt └── LICENSE /images/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /exercises/ex3/images/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/1085.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/images/1085.png -------------------------------------------------------------------------------- /images/intro_0000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/images/intro_0000.png -------------------------------------------------------------------------------- /images/intro_0010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/images/intro_0010.png -------------------------------------------------------------------------------- /images/intro_0020.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/images/intro_0020.jpg -------------------------------------------------------------------------------- /exercises/ex0/images/0010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0010.png -------------------------------------------------------------------------------- /exercises/ex0/images/0020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0020.png -------------------------------------------------------------------------------- /exercises/ex0/images/0030.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0030.png -------------------------------------------------------------------------------- /exercises/ex0/images/0040.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0040.png -------------------------------------------------------------------------------- /exercises/ex0/images/0050.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0050.png -------------------------------------------------------------------------------- /exercises/ex0/images/0060.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0060.png -------------------------------------------------------------------------------- /exercises/ex0/images/0070.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0070.png -------------------------------------------------------------------------------- /exercises/ex0/images/0080.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0080.png -------------------------------------------------------------------------------- /exercises/ex0/images/0090.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0090.png -------------------------------------------------------------------------------- /exercises/ex0/images/0100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0100.png -------------------------------------------------------------------------------- /exercises/ex0/images/0105.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0105.png -------------------------------------------------------------------------------- /exercises/ex0/images/0700.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0700.png -------------------------------------------------------------------------------- /exercises/ex0/images/0710.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0710.png -------------------------------------------------------------------------------- /exercises/ex0/images/0720.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0720.png -------------------------------------------------------------------------------- /exercises/ex0/images/0740.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0740.png -------------------------------------------------------------------------------- /exercises/ex0/images/0750.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0750.png -------------------------------------------------------------------------------- /exercises/ex0/images/0760.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0760.png -------------------------------------------------------------------------------- /exercises/ex0/images/0770.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/0770.png -------------------------------------------------------------------------------- /exercises/ex1/images/0010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0010.png -------------------------------------------------------------------------------- /exercises/ex1/images/0020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0020.png -------------------------------------------------------------------------------- /exercises/ex1/images/0030.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0030.png -------------------------------------------------------------------------------- /exercises/ex1/images/0040.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0040.png -------------------------------------------------------------------------------- /exercises/ex1/images/0050.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0050.png -------------------------------------------------------------------------------- /exercises/ex1/images/0060.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0060.png -------------------------------------------------------------------------------- /exercises/ex1/images/0070.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0070.png -------------------------------------------------------------------------------- /exercises/ex1/images/0080.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0080.png -------------------------------------------------------------------------------- /exercises/ex1/images/0090.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0090.png -------------------------------------------------------------------------------- /exercises/ex1/images/0100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0100.png -------------------------------------------------------------------------------- /exercises/ex1/images/0105.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0105.png -------------------------------------------------------------------------------- /exercises/ex1/images/0110.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0110.png -------------------------------------------------------------------------------- /exercises/ex1/images/0200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0200.png -------------------------------------------------------------------------------- /exercises/ex1/images/0210.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0210.png -------------------------------------------------------------------------------- /exercises/ex1/images/0220.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0220.png -------------------------------------------------------------------------------- /exercises/ex1/images/0230.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0230.png -------------------------------------------------------------------------------- /exercises/ex1/images/0250.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0250.png -------------------------------------------------------------------------------- /exercises/ex1/images/0270.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0270.png -------------------------------------------------------------------------------- /exercises/ex1/images/0280.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0280.png -------------------------------------------------------------------------------- /exercises/ex1/images/0290.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0290.png -------------------------------------------------------------------------------- /exercises/ex1/images/0300.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0300.png -------------------------------------------------------------------------------- /exercises/ex1/images/0310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0310.png -------------------------------------------------------------------------------- /exercises/ex1/images/0320.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0320.png -------------------------------------------------------------------------------- /exercises/ex1/images/0350.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0350.png -------------------------------------------------------------------------------- /exercises/ex1/images/0360.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0360.png -------------------------------------------------------------------------------- /exercises/ex1/images/0370.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0370.png -------------------------------------------------------------------------------- /exercises/ex1/images/0380.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0380.png -------------------------------------------------------------------------------- /exercises/ex1/images/0390.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0390.png -------------------------------------------------------------------------------- /exercises/ex1/images/0400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0400.png -------------------------------------------------------------------------------- /exercises/ex1/images/0410.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0410.png -------------------------------------------------------------------------------- /exercises/ex1/images/0420.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0420.png -------------------------------------------------------------------------------- /exercises/ex1/images/0430.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0430.png -------------------------------------------------------------------------------- /exercises/ex1/images/0435.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0435.png -------------------------------------------------------------------------------- /exercises/ex1/images/0440.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0440.png -------------------------------------------------------------------------------- /exercises/ex1/images/0450.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0450.png -------------------------------------------------------------------------------- /exercises/ex1/images/0460.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0460.png -------------------------------------------------------------------------------- /exercises/ex1/images/0470.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0470.png -------------------------------------------------------------------------------- /exercises/ex1/images/0500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0500.png -------------------------------------------------------------------------------- /exercises/ex1/images/0510.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0510.png -------------------------------------------------------------------------------- /exercises/ex1/images/0520.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0520.png -------------------------------------------------------------------------------- /exercises/ex1/images/0530.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0530.png -------------------------------------------------------------------------------- /exercises/ex1/images/0540.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0540.png -------------------------------------------------------------------------------- /exercises/ex1/images/0550.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0550.png -------------------------------------------------------------------------------- /exercises/ex1/images/0560.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0560.png -------------------------------------------------------------------------------- /exercises/ex1/images/0570.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/0570.png -------------------------------------------------------------------------------- /exercises/ex1/images/1000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/1000.png -------------------------------------------------------------------------------- /exercises/ex1/images/1010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/1010.png -------------------------------------------------------------------------------- /exercises/ex1/images/1020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/1020.png -------------------------------------------------------------------------------- /exercises/ex1/images/1030.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/1030.png -------------------------------------------------------------------------------- /exercises/ex1/images/1040.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/1040.png -------------------------------------------------------------------------------- /exercises/ex1/images/1045.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/1045.png -------------------------------------------------------------------------------- /exercises/ex1/images/1050.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/1050.png -------------------------------------------------------------------------------- /exercises/ex2/images/1000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1000.png -------------------------------------------------------------------------------- /exercises/ex2/images/1005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1005.png -------------------------------------------------------------------------------- /exercises/ex2/images/1010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1010.png -------------------------------------------------------------------------------- /exercises/ex2/images/1020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1020.png -------------------------------------------------------------------------------- /exercises/ex2/images/1022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1022.png -------------------------------------------------------------------------------- /exercises/ex2/images/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1024.png -------------------------------------------------------------------------------- /exercises/ex2/images/1026.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1026.png -------------------------------------------------------------------------------- /exercises/ex2/images/1030.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1030.png -------------------------------------------------------------------------------- /exercises/ex2/images/1040.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1040.png -------------------------------------------------------------------------------- /exercises/ex2/images/1050.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1050.png -------------------------------------------------------------------------------- /exercises/ex2/images/1060.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1060.png -------------------------------------------------------------------------------- /exercises/ex2/images/1070.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1070.png -------------------------------------------------------------------------------- /exercises/ex2/images/1080.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1080.png -------------------------------------------------------------------------------- /exercises/ex2/images/1085.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1085.png -------------------------------------------------------------------------------- /exercises/ex2/images/1090.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1090.png -------------------------------------------------------------------------------- /exercises/ex2/images/1100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1100.png -------------------------------------------------------------------------------- /exercises/ex2/images/1110.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1110.png -------------------------------------------------------------------------------- /exercises/ex2/images/1120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1120.png -------------------------------------------------------------------------------- /exercises/ex2/images/1130.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1130.png -------------------------------------------------------------------------------- /exercises/ex2/images/1135.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1135.png -------------------------------------------------------------------------------- /exercises/ex2/images/1137.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1137.png -------------------------------------------------------------------------------- /exercises/ex2/images/1139.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1139.png -------------------------------------------------------------------------------- /exercises/ex2/images/1160.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1160.png -------------------------------------------------------------------------------- /exercises/ex2/images/1170.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1170.png -------------------------------------------------------------------------------- /exercises/ex2/images/1200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1200.png -------------------------------------------------------------------------------- /exercises/ex2/images/1210.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1210.png -------------------------------------------------------------------------------- /exercises/ex2/images/1220.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1220.png -------------------------------------------------------------------------------- /exercises/ex2/images/1230.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1230.png -------------------------------------------------------------------------------- /exercises/ex2/images/1240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1240.png -------------------------------------------------------------------------------- /exercises/ex2/images/1250.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1250.png -------------------------------------------------------------------------------- /exercises/ex2/images/1260.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1260.png -------------------------------------------------------------------------------- /exercises/ex2/images/1270.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1270.png -------------------------------------------------------------------------------- /exercises/ex2/images/1280.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1280.png -------------------------------------------------------------------------------- /exercises/ex2/images/1290.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1290.png -------------------------------------------------------------------------------- /exercises/ex2/images/1295.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1295.png -------------------------------------------------------------------------------- /exercises/ex2/images/1300.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1300.png -------------------------------------------------------------------------------- /exercises/ex2/images/1310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1310.png -------------------------------------------------------------------------------- /exercises/ex2/images/1320.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1320.png -------------------------------------------------------------------------------- /exercises/ex2/images/1330.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1330.png -------------------------------------------------------------------------------- /exercises/ex2/images/1340.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1340.png -------------------------------------------------------------------------------- /exercises/ex2/images/1350.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1350.png -------------------------------------------------------------------------------- /exercises/ex2/images/1355.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1355.png -------------------------------------------------------------------------------- /exercises/ex2/images/1360.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1360.png -------------------------------------------------------------------------------- /exercises/ex2/images/1370.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1370.png -------------------------------------------------------------------------------- /exercises/ex2/images/1380.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1380.png -------------------------------------------------------------------------------- /exercises/ex2/images/1390.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/1390.png -------------------------------------------------------------------------------- /exercises/ex3/images/2010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2010.png -------------------------------------------------------------------------------- /exercises/ex3/images/2020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2020.png -------------------------------------------------------------------------------- /exercises/ex3/images/2025.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2025.png -------------------------------------------------------------------------------- /exercises/ex3/images/2030.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2030.png -------------------------------------------------------------------------------- /exercises/ex3/images/2040.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2040.png -------------------------------------------------------------------------------- /exercises/ex3/images/2050.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2050.png -------------------------------------------------------------------------------- /exercises/ex3/images/2060.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2060.png -------------------------------------------------------------------------------- /exercises/ex3/images/2065.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2065.png -------------------------------------------------------------------------------- /exercises/ex3/images/2070.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2070.png -------------------------------------------------------------------------------- /exercises/ex3/images/2080.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2080.png -------------------------------------------------------------------------------- /exercises/ex3/images/2090.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2090.png -------------------------------------------------------------------------------- /exercises/ex3/images/2110.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2110.png -------------------------------------------------------------------------------- /exercises/ex3/images/2120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2120.png -------------------------------------------------------------------------------- /exercises/ex3/images/2130.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2130.png -------------------------------------------------------------------------------- /exercises/ex3/images/2140.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2140.png -------------------------------------------------------------------------------- /exercises/ex3/images/2500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/2500.png -------------------------------------------------------------------------------- /exercises/ex1/images/activate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/activate.png -------------------------------------------------------------------------------- /exercises/ex2/images/activate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/activate.png -------------------------------------------------------------------------------- /exercises/ex3/images/activate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/activate.png -------------------------------------------------------------------------------- /exercises/ex0/images/00_00_0010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex0/images/00_00_0010.png -------------------------------------------------------------------------------- /exercises/ex1/images/01_01_0010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/01_01_0010.png -------------------------------------------------------------------------------- /exercises/ex1/images/01_02_0010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/01_02_0010.png -------------------------------------------------------------------------------- /exercises/ex2/images/02_01_0010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/02_01_0010.png -------------------------------------------------------------------------------- /exercises/ex2/images/02_02_0010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex2/images/02_02_0010.png -------------------------------------------------------------------------------- /exercises/ex1/images/00_001_DEV268.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/00_001_DEV268.png -------------------------------------------------------------------------------- /exercises/ex1/images/00_002_DEV268.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/00_002_DEV268.png -------------------------------------------------------------------------------- /exercises/ex1/images/00_003_DEV268.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/00_003_DEV268.png -------------------------------------------------------------------------------- /exercises/ex1/images/00_004_DEV268.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/00_004_DEV268.png -------------------------------------------------------------------------------- /exercises/ex1/images/00_005_DEV268.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex1/images/00_005_DEV268.png -------------------------------------------------------------------------------- /exercises/ex3/images/mass_activate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP-archive/teched2020-DEV268/HEAD/exercises/ex3/images/mass_activate.png -------------------------------------------------------------------------------- /exercises/ex2/sources/ex2_SRVD_ZUI_RAP_INVENTORY_####.txt: -------------------------------------------------------------------------------- 1 | define service ZUI_RAP_INVENTORY_#### { 2 | expose ZC_RAP_INVENTORY_#### as Inventory; 3 | expose ZCE_RAP_PRODUCTS_#### as Products; 4 | } 5 | -------------------------------------------------------------------------------- /exercises/ex1/sources/ex1_template_for_RAP_GENERATOR.json: -------------------------------------------------------------------------------- 1 | { 2 | "implementationType": "managed_uuid", 3 | "namespace": "Z", 4 | "suffix": "_####", 5 | "prefix": "RAP_", 6 | "package": "ZRAP_INVENTORY_####", 7 | "datasourcetype": "table", 8 | "hierarchy": { 9 | "entityName": "Inventory", 10 | "dataSource": "zrap_inven_####", 11 | "objectId": "inventory_id" 12 | } 13 | } -------------------------------------------------------------------------------- /.abapgit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | E 6 | /src/ 7 | PREFIX 8 | 9 | /.gitignore 10 | /LICENSE 11 | /README.md 12 | /package.json 13 | /.travis.yml 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/#dmo#cl_gen_dev268_artifacts.clas.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | /DMO/CL_GEN_DEV268_ARTIFACTS 7 | E 8 | Generate artifacts needed for DEV268 workshop 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /exercises/ex1/sources/ex1_TABL_zrap_inven_####.txt: -------------------------------------------------------------------------------- 1 | @EndUserText.label : 'Inventory data' 2 | @AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE 3 | @AbapCatalog.tableCategory : #TRANSPARENT 4 | @AbapCatalog.deliveryClass : #A 5 | @AbapCatalog.dataMaintenance : #RESTRICTED 6 | define table zrap_inven_#### { 7 | key client : abap.clnt not null; 8 | key uuid : sysuuid_x16 not null; 9 | inventory_id : abap.numc(6) not null; 10 | product_id : abap.char(10); 11 | @Semantics.quantity.unitOfMeasure : 'zrap_inven_####.quantity_unit' 12 | quantity : abap.quan(13,3); 13 | quantity_unit : abap.unit(3); 14 | @Semantics.amount.currencyCode : 'zrap_inven_####.currency_code' 15 | price : abap.curr(16,2); 16 | currency_code : abap.cuky; 17 | remark : abap.char(256); 18 | not_available : abap_boolean; 19 | created_by : syuname; 20 | created_at : timestampl; 21 | last_changed_by : syuname; 22 | last_changed_at : timestampl; 23 | 24 | } -------------------------------------------------------------------------------- /exercises/ex1/sources/ex1_CLAS_zbp_i_rap_inventory_####.txt: -------------------------------------------------------------------------------- 1 | CLASS lhc_Inventory DEFINITION INHERITING FROM cl_abap_behavior_handler. 2 | PRIVATE SECTION. 3 | 4 | METHODS CalculateInventoryID FOR DETERMINE ON SAVE 5 | IMPORTING keys FOR Inventory~CalculateInventoryID. 6 | 7 | ENDCLASS. 8 | 9 | CLASS lhc_Inventory IMPLEMENTATION. 10 | 11 | METHOD CalculateInventoryID. 12 | 13 | "Ensure idempotence 14 | READ ENTITIES OF zi_rap_inventory_1234 IN LOCAL MODE 15 | ENTITY Inventory 16 | FIELDS ( InventoryID ) 17 | WITH CORRESPONDING #( keys ) 18 | RESULT DATA(inventories). 19 | 20 | DELETE inventories WHERE InventoryID IS NOT INITIAL. 21 | CHECK inventories IS NOT INITIAL. 22 | 23 | "Get max travelID 24 | SELECT SINGLE FROM zrap_inven_1234 FIELDS MAX( inventory_id ) INTO @DATA(max_inventory). 25 | 26 | "update involved instances 27 | MODIFY ENTITIES OF zi_rap_inventory_1234 IN LOCAL MODE 28 | ENTITY Inventory 29 | UPDATE FIELDS ( InventoryID ) 30 | WITH VALUE #( FOR inventory IN inventories INDEX INTO i ( 31 | %tky = inventory-%tky 32 | inventoryID = max_inventory + i ) ) 33 | REPORTED DATA(reported_entities). 34 | 35 | "fill reported 36 | reported = CORRESPONDING #( DEEP reported_entities ). 37 | 38 | ENDMETHOD. 39 | 40 | ENDCLASS. -------------------------------------------------------------------------------- /exercises/ex0/readme_import_helper_class.md: -------------------------------------------------------------------------------- 1 | 2 | ## Import of the helper class /dmo/cl_gen_dev268_artifacts 3 | 4 | When you are running this mission in your own Steampunk system you have to 5 | 6 | 1. import the helper class /dmo/cl_gen_dev268_artifacts and you have to 7 | 2. import the RAP Generator https://github.com/SAP-samples/cloud-abap-rap 8 | 9 | ### Create a package /DMO/DEV268 10 | 11 | 1. Create a package with the name **/DMO/DEV268** and choose **ZLOCAL** as the super package. 12 | 13 | ![Create package](images/0700.png) 14 | 15 | and create a new transport request. 16 | 17 | ![Create transport request](images/0710.png) 18 | 19 | ### Link package to ABAP Git repository 20 | 21 | 1. Click on the tab **abapGit Repositories** 22 | 2. Click on the **green plus sign** on right hand side 23 | 3. Enter the following URL https://github.com/SAP-samples/teched2020-DEV268.git 24 | 4. Press **Next** 25 | 26 | ![Link abapGit repository](images/0720.png) 27 | 28 | 1. In the next screen enter the name of the package that you have created in the first step **/DMO/DEV268**. 29 | 2. Mark the check box **Pull after link** 30 | 3. Press **Next** 31 | 32 | ![Select package and branch](images/0740.png) 33 | 34 | In the screen **Select Transport Request** select the transport request thatpress **Finish** 35 | 36 | In the screen **Pull from abapGit Repository** select **Finish** 37 | 38 | ![Pull](images/0750.png) 39 | 40 | Navigate to the imported class **/dmo/cl_gen_dev268_artifacts** and press **Activate** 41 | 42 | ![Activate class](images/0770.png) 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /.reuse/dep5: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: teched2020-DEV268 3 | Upstream-Contact: () 4 | Source: https://github.com/sap-samples/teched2020-DEV268 5 | Disclaimer: The code in this project may include calls to APIs (“API Calls”) of 6 | SAP or third-party products or services developed outside of this project 7 | (“External Products”). 8 | “APIs” means application programming interfaces, as well as their respective 9 | specifications and implementing code that allows software to communicate with 10 | other software. 11 | API Calls to External Products are not licensed under the open source license 12 | that governs this project. The use of such API Calls and related External 13 | Products are subject to applicable additional agreements with the relevant 14 | provider of the External Products. In no event shall the open source license 15 | that governs this project grant any rights in or to any External Products,or 16 | alter, expand or supersede any terms of the applicable additional agreements. 17 | If you have a valid license agreement with SAP for the use of a particular SAP 18 | External Product, then you may make use of any API Calls included in this 19 | project’s code for that SAP External Product, subject to the terms of such 20 | license agreement. If you do not have a valid license agreement for the use of 21 | a particular SAP External Product, then you may only make use of any API Calls 22 | in this project for that SAP External Product for your internal, non-productive 23 | and non-commercial test and evaluation of such API Calls. Nothing herein grants 24 | you any rights to use or access any SAP External Product, or provide any third 25 | parties the right to use of access any SAP External Product, through API Calls. 26 | 27 | Files: * 28 | Copyright: 2020 SAP SE or an SAP affiliate company and teched2020-DEV268 contributors 29 | License: Apache-2.0 30 | -------------------------------------------------------------------------------- /exercises/ex2/sources/ex2_DDLS_ZCE_RAP_PRODUCTS_####.txt: -------------------------------------------------------------------------------- 1 | @EndUserText.label: 'Custom entity for products from ES5' 2 | @ObjectModel.query.implementedBy: 'ABAP:ZCL_CE_RAP_PRODUCTS_####' 3 | define custom entity ZCE_RAP_PRODUCTS_#### 4 | { 5 | key Product : abap.char( 10 ) ; 6 | @OData.property.valueControl: 'Currency_vc' 7 | @Semantics.currencyCode: true 8 | Currency : abap.cuky ; 9 | Currency_vc : rap_cp_odata_value_control ; 10 | @OData.property.valueControl: 'Height_vc' 11 | @Semantics.quantity.unitOfMeasure: 'DimensionUnit' 12 | Height : abap.dec( 13, 3 ) ; 13 | Height_vc : rap_cp_odata_value_control ; 14 | @OData.property.valueControl: 'Width_vc' 15 | @Semantics.quantity.unitOfMeasure: 'DimensionUnit' 16 | Width : abap.dec( 13, 3 ) ; 17 | Width_vc : rap_cp_odata_value_control ; 18 | @OData.property.valueControl: 'Depth_vc' 19 | @Semantics.quantity.unitOfMeasure: 'DimensionUnit' 20 | Depth : abap.dec( 13, 3 ) ; 21 | Depth_vc : rap_cp_odata_value_control ; 22 | @OData.property.valueControl: 'DimensionUnit_vc' 23 | @Semantics.unitOfMeasure: true 24 | DimensionUnit : abap.unit( 3 ) ; 25 | DimensionUnit_vc : rap_cp_odata_value_control ; 26 | @OData.property.valueControl: 'ProductPictureURL_vc' 27 | ProductPictureURL : abap.char( 255 ) ; 28 | ProductPictureURL_vc : rap_cp_odata_value_control ; 29 | @OData.property.valueControl: 'ProductValueAddedTax_vc' 30 | ProductValueAddedTax : abap.int1 ; 31 | ProductValueAddedTax_vc : rap_cp_odata_value_control ; 32 | @OData.property.valueControl: 'Supplier_vc' 33 | Supplier : abap.char( 10 ) ; 34 | Supplier_vc : rap_cp_odata_value_control ; 35 | @OData.property.valueControl: 'ProductBaseUnit_vc' 36 | ProductBaseUnit : abap.char( 3 ) ; 37 | ProductBaseUnit_vc : rap_cp_odata_value_control ; 38 | @OData.property.valueControl: 'Weight_vc' 39 | @Semantics.quantity.unitOfMeasure: 'WeightUnit' 40 | Weight : abap.dec( 13, 3 ) ; 41 | Weight_vc : rap_cp_odata_value_control ; 42 | @OData.property.valueControl: 'ProductUUID_vc' 43 | ProductUUID : sysuuid_x16 ; 44 | ProductUUID_vc : rap_cp_odata_value_control ; 45 | @OData.property.valueControl: 'WeightUnit_vc' 46 | @Semantics.unitOfMeasure: true 47 | WeightUnit : abap.unit( 3 ) ; 48 | WeightUnit_vc : rap_cp_odata_value_control ; 49 | @OData.property.valueControl: 'OriginalLanguage_vc' 50 | OriginalLanguage : abap.char( 2 ) ; 51 | OriginalLanguage_vc : rap_cp_odata_value_control ; 52 | @OData.property.valueControl: 'ProductType_vc' 53 | ProductType : abap.char( 2 ) ; 54 | ProductType_vc : rap_cp_odata_value_control ; 55 | @OData.property.valueControl: 'ProductCategory_vc' 56 | ProductCategory : abap.char( 40 ) ; 57 | ProductCategory_vc : rap_cp_odata_value_control ; 58 | @OData.property.valueControl: 'CreatedByUser_vc' 59 | CreatedByUser : sysuuid_x16 ; 60 | CreatedByUser_vc : rap_cp_odata_value_control ; 61 | @OData.property.valueControl: 'CreationDateTime_vc' 62 | CreationDateTime : tzntstmpl ; 63 | CreationDateTime_vc : rap_cp_odata_value_control ; 64 | @OData.property.valueControl: 'LastChangedByUser_vc' 65 | LastChangedByUser : sysuuid_x16 ; 66 | LastChangedByUser_vc : rap_cp_odata_value_control ; 67 | @OData.property.valueControl: 'LastChangedDateTime_vc' 68 | LastChangedDateTime : tzntstmpl ; 69 | LastChangedDateTime_vc : rap_cp_odata_value_control ; 70 | @OData.property.valueControl: 'Price_vc' 71 | @Semantics.amount.currencyCode: 'Currency' 72 | Price : abap.curr( 16, 3 ) ; 73 | Price_vc : rap_cp_odata_value_control ; 74 | 75 | } 76 | -------------------------------------------------------------------------------- /exercises/ex2/sources/ex2_CLAS_zcl_ce_rap_products_####_step_1.txt: -------------------------------------------------------------------------------- 1 | CLASS zcl_ce_rap_products_#### DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | INTERFACES if_oo_adt_classrun . 9 | 10 | TYPES t_product_range TYPE RANGE OF zrap_####_sepmra_i_product_e-product. 11 | TYPES t_business_data TYPE TABLE OF zrap_####_sepmra_i_product_e. 12 | 13 | METHODS get_products 14 | IMPORTING 15 | it_filter_cond TYPE if_rap_query_filter=>tt_name_range_pairs OPTIONAL 16 | top TYPE i OPTIONAL 17 | skip TYPE i OPTIONAL 18 | EXPORTING 19 | et_business_data TYPE t_business_data 20 | RAISING 21 | /iwbep/cx_cp_remote 22 | /iwbep/cx_gateway 23 | cx_web_http_client_error 24 | cx_http_dest_provider_error 25 | . 26 | 27 | PROTECTED SECTION. 28 | PRIVATE SECTION. 29 | ENDCLASS. 30 | 31 | 32 | 33 | CLASS zcl_ce_rap_products_#### IMPLEMENTATION. 34 | 35 | METHOD if_oo_adt_classrun~main. 36 | 37 | DATA business_data TYPE TABLE OF zrap_####_sepmra_i_product_e. 38 | DATA filter_conditions TYPE if_rap_query_filter=>tt_name_range_pairs . 39 | DATA ranges_table TYPE if_rap_query_filter=>tt_range_option . 40 | ranges_table = VALUE #( ( sign = 'I' option = 'GE' low = 'HT-1200' ) ). 41 | filter_conditions = VALUE #( ( name = 'PRODUCT' range = ranges_table ) ). 42 | 43 | TRY. 44 | get_products( 45 | EXPORTING 46 | it_filter_cond = filter_conditions 47 | top = 3 48 | skip = 1 49 | IMPORTING 50 | et_business_data = business_data 51 | ) . 52 | out->write( business_data ). 53 | CATCH cx_root INTO DATA(exception). 54 | out->write( cl_message_helper=>get_latest_t100_exception( exception )->if_message~get_longtext( ) ). 55 | ENDTRY. 56 | 57 | ENDMETHOD. 58 | 59 | METHOD get_products. 60 | 61 | DATA: filter_factory TYPE REF TO /iwbep/if_cp_filter_factory, 62 | filter_node TYPE REF TO /iwbep/if_cp_filter_node, 63 | root_filter_node TYPE REF TO /iwbep/if_cp_filter_node. 64 | 65 | DATA: http_client TYPE REF TO if_web_http_client, 66 | odata_client_proxy TYPE REF TO /iwbep/if_cp_client_proxy, 67 | read_list_request TYPE REF TO /iwbep/if_cp_request_read_list, 68 | read_list_response TYPE REF TO /iwbep/if_cp_response_read_lst. 69 | 70 | DATA(http_destination) = cl_http_destination_provider=>create_by_url( i_url = 'https://sapes5.sapdevcenter.com' ). 71 | http_client = cl_web_http_client_manager=>create_by_http_destination( i_destination = http_destination ). 72 | 73 | odata_client_proxy = cl_web_odata_client_factory=>create_v2_remote_proxy( 74 | EXPORTING 75 | iv_service_definition_name = 'ZSC_RAP_PRODUCTS_####' 76 | io_http_client = http_client 77 | iv_relative_service_root = '/sap/opu/odata/sap/ZPDCDS_SRV/' ). 78 | 79 | " Navigate to the resource and create a request for the read operation 80 | read_list_request = odata_client_proxy->create_resource_for_entity_set( 'SEPMRA_I_PRODUCT_E' )->create_request_for_read( ). 81 | 82 | " Create the filter tree 83 | filter_factory = read_list_request->create_filter_factory( ). 84 | LOOP AT it_filter_cond INTO DATA(filter_condition). 85 | filter_node = filter_factory->create_by_range( iv_property_path = filter_condition-name 86 | it_range = filter_condition-range ). 87 | IF root_filter_node IS INITIAL. 88 | root_filter_node = filter_node. 89 | ELSE. 90 | root_filter_node = root_filter_node->and( filter_node ). 91 | ENDIF. 92 | ENDLOOP. 93 | 94 | IF root_filter_node IS NOT INITIAL. 95 | read_list_request->set_filter( root_filter_node ). 96 | ENDIF. 97 | 98 | IF top > 0 . 99 | read_list_request->set_top( top ). 100 | ENDIF. 101 | 102 | read_list_request->set_skip( skip ). 103 | 104 | " Execute the request and retrieve the business data 105 | read_list_response = read_list_request->execute( ). 106 | read_list_response->get_business_data( IMPORTING et_business_data = et_business_data ). 107 | 108 | ENDMETHOD. 109 | 110 | ENDCLASS. 111 | -------------------------------------------------------------------------------- /exercises/ex0/README.md: -------------------------------------------------------------------------------- 1 | [Home - DEV268](../../README.md#exercises) 2 | 3 | # Getting started 4 | 5 | Before starting with the exercise please make sure that you have worked on the prerequisites that can be found in detail [here](../../README.md#requirements) 6 | 7 | 8 | ## Connect to the system 9 | 10 | 1. Start the ABAP Development Tools (aka ABAP in Eclipse) 11 | 12 | 2. Select a directory as workspace. Click **Launch** 13 | 14 | ![Select directory](images/0010.png) 15 | 16 | 3. Close the Welcome screen 17 | 18 | ![Close Welcome screen](images/0020.png) 19 | 20 | 4. Check the perspective. If the perspective is still the *Java perspective*, then ... 21 | 22 | ![Java perspective](images/0030.png) 23 | 24 | 5. Open ABAP perspective (if needed) 25 | 26 | - Click on the **Open perspective** button 27 | - Select **ABAP** 28 | - Click **Open** 29 | 30 | ![OpenABAP perspective](images/0040.png) 31 | 32 | 5. Click **File > New > ABAP Cloud Project** to open a new ABAP Cloud project. 33 | 34 | ![OpenABAP perspective](images/0050.png) 35 | 36 | 5. Choose the option **SAP Cloud Platform Cloud Foundry Environment** and then click **Next** . 37 | 38 | ![System connection options](images/0060.png) 39 | 40 | >**Please note** 41 | 42 | > You have two options how to connect to your SAP Cloud Platform ABAP environment system. We suggest to use the first option. Logon to the **SAP Cloud Platform Cloud Foundry Environment** and navigate to your ABAP instance. The other option would be to connect directly to the ABAP environment. For this you however would have to provide the service key that you have downloaded when setting up your ABAP instance. 43 | 44 | 6. Provide the SAP Cloud Foundry connection settings. 45 | 46 | In this dialogue select the following values 47 | 48 | - Region: Select the region e.g. **Europe (Frankfurt)** or **US East (VA)**. 49 | - Username: Enter your **email adress** 50 | - Password: Enter your **password** you use to log on to SAP Cloud platform 51 | 52 | ![CF connection options](images/0070.png) 53 | 54 | Click **Next**. 55 | 56 | > The API endpoint will be selected according to the region you have chosen. 57 | 58 | 7. Select service instance details 59 | 60 | - Organization: Select your organization e.g. **xxxxxxtrial** 61 | - Space: Select the space in your CF sub account e.g. **dev** 62 | - Service instance: Click on the name of your ABAP trial instance e.g. **default_abap-trial**. 63 | 64 | Click **Next**. 65 | 66 | ![CF connection settings](images/0080.png) 67 | 68 | 8. Check service connection settings and press **Next**. 69 | 70 | ![Service instance connection](images/0090.png) 71 | 72 | 8. You can keep the default project name, e.g. **TRL_EN** unchanged and click **Finish** 73 | 74 | ![Project name](images/0100.png) 75 | 76 | 9. Your ABAP Cloud Project should now look like follows 77 | 78 | ![Project name](images/0105.png) 79 | 80 | 81 | ## Import of the helper class /dmo/cl_gen_dev268_artifacts 82 | 83 | When you are running this mission in your own Steampunk system you have to 84 | 85 | 1. import the helper class /dmo/cl_gen_dev268_artifacts and you have to 86 | 2. import the RAP Generator https://github.com/SAP-samples/cloud-abap-rap 87 | 88 | ### Create a package /DMO/DEV268 89 | 90 | 1. Create a package with the name **/DMO/DEV268** and choose **ZLOCAL** as the super package. 91 | 92 | ![Create package](images/0700.png) 93 | 94 | and create a new transport request. 95 | 96 | ![Create transport request](images/0710.png) 97 | 98 | ### Link package to ABAP Git repository 99 | 100 | 1. Click on the tab **abapGit Repositories** 101 | 2. Click on the **green plus sign** on right hand side 102 | 3. Enter the following URL https://github.com/SAP-samples/teched2020-DEV268.git 103 | 4. Press **Next** 104 | 105 | ![Link abapGit repository](images/0720.png) 106 | 107 | 1. In the next screen enter the name of the package that you have created in the first step **/DMO/DEV268**. 108 | 2. Mark the check box **Pull after link** 109 | 3. Press **Next** 110 | 111 | ![Select package and branch](images/0740.png) 112 | 113 | In the screen **Select Transport Request** select the transport request thatpress **Finish** 114 | 115 | In the screen **Pull from abapGit Repository** select **Finish** 116 | 117 | ![Pull](images/0750.png) 118 | 119 | Navigate to the imported class **/dmo/cl_gen_dev268_artifacts** and press **Activate** 120 | 121 | ![Activate class](images/0770.png) 122 | 123 | 124 | ## Summary 125 | 126 | Now you are ready to start with the first exercise. 127 | 128 | Continue to - [Exercise 1](../ex1/README.md) 129 | -------------------------------------------------------------------------------- /exercises/ex3/sources/ex3_CLAS_zbp_i_rap_inventory_####.txt: -------------------------------------------------------------------------------- 1 | CLASS lhc_Inventory DEFINITION INHERITING FROM cl_abap_behavior_handler. 2 | PRIVATE SECTION. 3 | 4 | METHODS CalculateInventoryID FOR DETERMINE ON SAVE 5 | IMPORTING keys FOR Inventory~CalculateInventoryID. 6 | METHODS GetPrice FOR DETERMINE ON MODIFY 7 | IMPORTING keys FOR Inventory~GetPrice. 8 | 9 | ENDCLASS. 10 | 11 | CLASS lhc_Inventory IMPLEMENTATION. 12 | 13 | METHOD CalculateInventoryID. 14 | 15 | "Ensure idempotence 16 | READ ENTITIES OF zi_rap_inventory_#### IN LOCAL MODE 17 | ENTITY Inventory 18 | FIELDS ( InventoryID ) 19 | WITH CORRESPONDING #( keys ) 20 | RESULT DATA(inventories). 21 | 22 | DELETE inventories WHERE InventoryID IS NOT INITIAL. 23 | CHECK inventories IS NOT INITIAL. 24 | 25 | "Get max travelID 26 | SELECT SINGLE FROM zrap_inven_#### FIELDS MAX( inventory_id ) INTO @DATA(max_inventory). 27 | 28 | "update involved instances 29 | MODIFY ENTITIES OF zi_rap_inventory_#### IN LOCAL MODE 30 | ENTITY Inventory 31 | UPDATE FIELDS ( InventoryID ) 32 | WITH VALUE #( FOR inventory IN inventories INDEX INTO i ( 33 | %tky = inventory-%tky 34 | inventoryID = max_inventory + i ) ) 35 | REPORTED DATA(reported_entities). 36 | 37 | "fill reported 38 | reported = CORRESPONDING #( DEEP reported_entities ). 39 | 40 | ENDMETHOD. 41 | 42 | METHOD GetPrice. 43 | 44 | DATA destination TYPE REF TO if_soap_destination. 45 | DATA proxy TYPE REF TO zrap_####_co_epm_product_soap . 46 | DATA reported_inventory_soap LIKE reported-inventory. 47 | "Ensure idempotence 48 | READ ENTITIES OF zi_rap_inventory_#### IN LOCAL MODE 49 | ENTITY Inventory 50 | FIELDS ( Price ProductID ) 51 | WITH CORRESPONDING #( keys ) 52 | RESULT DATA(inventories). 53 | 54 | DELETE inventories WHERE Price IS NOT INITIAL. 55 | CHECK inventories IS NOT INITIAL. 56 | 57 | DELETE inventories WHERE ProductID =''. 58 | CHECK inventories IS NOT INITIAL. 59 | 60 | LOOP AT inventories ASSIGNING FIELD-SYMBOL(). 61 | 62 | TRY. 63 | 64 | IF destination IS INITIAL. 65 | destination = cl_soap_destination_provider=>create_by_url( i_url = 'https://sapes5.sapdevcenter.com/sap/bc/srt/xip/sap/zepm_product_soap/002/epm_product_soap/epm_product_soap' ). 66 | ENDIF. 67 | IF proxy IS INITIAL. 68 | proxy = NEW zrap_####_co_epm_product_soap( 69 | destination = destination 70 | ). 71 | ENDIF. 72 | 73 | DATA(request) = VALUE zrap_####_req_msg_type( req_msg_type-product = -ProductID ). 74 | proxy->get_price( 75 | EXPORTING 76 | input = request 77 | IMPORTING 78 | output = DATA(response) 79 | ). 80 | 81 | -Price = response-res_msg_type-price . 82 | -CurrencyCode = response-res_msg_type-currency. 83 | "handle response 84 | 85 | CATCH cx_soap_destination_error INTO DATA(soap_destination_error). 86 | DATA(error_message) = soap_destination_error->get_text( ). 87 | CATCH cx_ai_system_fault INTO DATA(ai_system_fault). 88 | error_message = | code: { ai_system_fault->code } codetext: { ai_system_fault->codecontext } |. 89 | CATCH zrap_####_cx_fault_msg_type INTO DATA(soap_exception). 90 | error_message = soap_exception->error_text. 91 | "fill reported structure to be displayed on the UI 92 | APPEND VALUE #( uuid = -uuid 93 | %msg = new_message( id = 'ZCM_RAP_GENERATOR' 94 | number = '016' 95 | v1 = error_message 96 | "v2 = messages[ 1 ]-msgv2 97 | "v3 = messages[ 1 ]-msgv3 98 | "v4 = messages[ 1 ]-msgv4 99 | severity = CONV #( 'E' ) ) 100 | %element-price = if_abap_behv=>mk-on 101 | 102 | 103 | ) TO reported_inventory_soap. 104 | "inventory entries where no price could be retrieved must not be passed to the MODIFY statement 105 | DELETE inventories INDEX sy-tabix. 106 | ENDTRY. 107 | 108 | ENDLOOP. 109 | 110 | "update involved instances 111 | MODIFY ENTITIES OF zi_rap_inventory_#### IN LOCAL MODE 112 | ENTITY Inventory 113 | UPDATE FIELDS ( Price CurrencyCode ) 114 | WITH VALUE #( FOR inventory IN inventories ( 115 | %tky = inventory-%tky 116 | Price = inventory-Price 117 | CurrencyCode = inventory-CurrencyCode 118 | ) ) 119 | REPORTED DATA(reported_entities). 120 | 121 | "fill reported 122 | reported = CORRESPONDING #( DEEP reported_entities ). 123 | 124 | "add reported from SOAP call 125 | LOOP AT reported_inventory_soap INTO DATA(reported_inventory). 126 | APPEND reported_inventory TO reported-inventory. 127 | ENDLOOP. 128 | 129 | 130 | ENDMETHOD. 131 | 132 | ENDCLASS. -------------------------------------------------------------------------------- /exercises/ex2/sources/zcl_ce_rap_products_####: -------------------------------------------------------------------------------- 1 | CLASS zcl_ce_rap_products_#### DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | INTERFACES if_oo_adt_classrun . 9 | INTERFACES if_rap_query_provider. 10 | 11 | TYPES t_product_range TYPE RANGE OF zrap_####_sepmra_i_product_e-product. 12 | TYPES t_business_data TYPE TABLE OF zrap_####_sepmra_i_product_e. 13 | 14 | METHODS get_products 15 | IMPORTING 16 | it_filter_cond TYPE if_rap_query_filter=>tt_name_range_pairs OPTIONAL 17 | top TYPE i OPTIONAL 18 | skip TYPE i OPTIONAL 19 | EXPORTING 20 | et_business_data TYPE t_business_data 21 | RAISING 22 | /iwbep/cx_cp_remote 23 | /iwbep/cx_gateway 24 | cx_web_http_client_error 25 | cx_http_dest_provider_error 26 | . 27 | 28 | PROTECTED SECTION. 29 | PRIVATE SECTION. 30 | ENDCLASS. 31 | 32 | 33 | 34 | CLASS zcl_ce_rap_products_#### IMPLEMENTATION. 35 | 36 | METHOD if_oo_adt_classrun~main. 37 | 38 | DATA business_data TYPE TABLE OF zrap_####_sepmra_i_product_e. 39 | DATA filter_conditions TYPE if_rap_query_filter=>tt_name_range_pairs . 40 | DATA ranges_table TYPE if_rap_query_filter=>tt_range_option . 41 | ranges_table = VALUE #( ( sign = 'I' option = 'GE' low = 'HT-1200' ) ). 42 | filter_conditions = VALUE #( ( name = 'PRODUCT' range = ranges_table ) ). 43 | 44 | TRY. 45 | get_products( 46 | EXPORTING 47 | it_filter_cond = filter_conditions 48 | top = 3 49 | skip = 1 50 | IMPORTING 51 | et_business_data = business_data 52 | ) . 53 | out->write( business_data ). 54 | CATCH cx_root INTO DATA(exception). 55 | out->write( cl_message_helper=>get_latest_t100_exception( exception )->if_message~get_longtext( ) ). 56 | ENDTRY. 57 | 58 | ENDMETHOD. 59 | 60 | METHOD get_products. 61 | 62 | DATA: filter_factory TYPE REF TO /iwbep/if_cp_filter_factory, 63 | filter_node TYPE REF TO /iwbep/if_cp_filter_node, 64 | root_filter_node TYPE REF TO /iwbep/if_cp_filter_node. 65 | 66 | DATA: http_client TYPE REF TO if_web_http_client, 67 | odata_client_proxy TYPE REF TO /iwbep/if_cp_client_proxy, 68 | read_list_request TYPE REF TO /iwbep/if_cp_request_read_list, 69 | read_list_response TYPE REF TO /iwbep/if_cp_response_read_lst. 70 | 71 | DATA(http_destination) = cl_http_destination_provider=>create_by_url( i_url = 'https://sapes5.sapdevcenter.com' ). 72 | http_client = cl_web_http_client_manager=>create_by_http_destination( i_destination = http_destination ). 73 | 74 | odata_client_proxy = cl_web_odata_client_factory=>create_v2_remote_proxy( 75 | EXPORTING 76 | iv_service_definition_name = 'ZSC_RAP_PRODUCTS_####' 77 | io_http_client = http_client 78 | iv_relative_service_root = '/sap/opu/odata/sap/ZPDCDS_SRV/' ). 79 | 80 | " Navigate to the resource and create a request for the read operation 81 | read_list_request = odata_client_proxy->create_resource_for_entity_set( 'SEPMRA_I_PRODUCT_E' )->create_request_for_read( ). 82 | 83 | " Create the filter tree 84 | filter_factory = read_list_request->create_filter_factory( ). 85 | LOOP AT it_filter_cond INTO DATA(filter_condition). 86 | filter_node = filter_factory->create_by_range( iv_property_path = filter_condition-name 87 | it_range = filter_condition-range ). 88 | IF root_filter_node IS INITIAL. 89 | root_filter_node = filter_node. 90 | ELSE. 91 | root_filter_node = root_filter_node->and( filter_node ). 92 | ENDIF. 93 | ENDLOOP. 94 | 95 | IF root_filter_node IS NOT INITIAL. 96 | read_list_request->set_filter( root_filter_node ). 97 | ENDIF. 98 | 99 | IF top > 0 . 100 | read_list_request->set_top( top ). 101 | ENDIF. 102 | 103 | read_list_request->set_skip( skip ). 104 | 105 | " Execute the request and retrieve the business data 106 | read_list_response = read_list_request->execute( ). 107 | read_list_response->get_business_data( IMPORTING et_business_data = et_business_data ). 108 | 109 | ENDMETHOD. 110 | 111 | 112 | METHOD if_rap_query_provider~select. 113 | DATA business_data TYPE TABLE OF zrap_####_sepmra_i_product_e. 114 | DATA(top) = io_request->get_paging( )->get_page_size( ). 115 | DATA(skip) = io_request->get_paging( )->get_offset( ). 116 | DATA(requested_fields) = io_request->get_requested_elements( ). 117 | DATA(sort_order) = io_request->get_sort_elements( ). 118 | 119 | TRY. 120 | DATA(filter_condition) = io_request->get_filter( )->get_as_ranges( ). 121 | 122 | get_products( 123 | EXPORTING 124 | it_filter_cond = filter_condition 125 | top = CONV i( top ) 126 | skip = CONV i( skip ) 127 | IMPORTING 128 | et_business_data = business_data 129 | ) . 130 | 131 | io_response->set_total_number_of_records( lines( business_data ) ). 132 | io_response->set_data( business_data ). 133 | 134 | CATCH cx_root INTO DATA(exception). 135 | DATA(exception_message) = cl_message_helper=>get_latest_t100_exception( exception )->if_message~get_longtext( ). 136 | ENDTRY. 137 | ENDMETHOD. 138 | 139 | ENDCLASS. 140 | -------------------------------------------------------------------------------- /exercises/ex2/sources/ex2_CLAS_zcl_ce_rap_products_####_final.txt: -------------------------------------------------------------------------------- 1 | CLASS zcl_ce_rap_products_#### DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | INTERFACES if_oo_adt_classrun . 9 | INTERFACES if_rap_query_provider. 10 | 11 | TYPES t_product_range TYPE RANGE OF zrap_####_sepmra_i_product_e-product. 12 | TYPES t_business_data TYPE TABLE OF zrap_####_sepmra_i_product_e. 13 | 14 | METHODS get_products 15 | IMPORTING 16 | it_filter_cond TYPE if_rap_query_filter=>tt_name_range_pairs OPTIONAL 17 | top TYPE i OPTIONAL 18 | skip TYPE i OPTIONAL 19 | EXPORTING 20 | et_business_data TYPE t_business_data 21 | RAISING 22 | /iwbep/cx_cp_remote 23 | /iwbep/cx_gateway 24 | cx_web_http_client_error 25 | cx_http_dest_provider_error 26 | . 27 | 28 | PROTECTED SECTION. 29 | PRIVATE SECTION. 30 | ENDCLASS. 31 | 32 | 33 | 34 | CLASS zcl_ce_rap_products_#### IMPLEMENTATION. 35 | 36 | METHOD if_oo_adt_classrun~main. 37 | 38 | DATA business_data TYPE TABLE OF zrap_####_sepmra_i_product_e. 39 | DATA filter_conditions TYPE if_rap_query_filter=>tt_name_range_pairs . 40 | DATA ranges_table TYPE if_rap_query_filter=>tt_range_option . 41 | ranges_table = VALUE #( ( sign = 'I' option = 'GE' low = 'HT-1200' ) ). 42 | filter_conditions = VALUE #( ( name = 'PRODUCT' range = ranges_table ) ). 43 | 44 | TRY. 45 | get_products( 46 | EXPORTING 47 | it_filter_cond = filter_conditions 48 | top = 3 49 | skip = 1 50 | IMPORTING 51 | et_business_data = business_data 52 | ) . 53 | out->write( business_data ). 54 | CATCH cx_root INTO DATA(exception). 55 | out->write( cl_message_helper=>get_latest_t100_exception( exception )->if_message~get_longtext( ) ). 56 | ENDTRY. 57 | 58 | ENDMETHOD. 59 | 60 | METHOD get_products. 61 | 62 | DATA: filter_factory TYPE REF TO /iwbep/if_cp_filter_factory, 63 | filter_node TYPE REF TO /iwbep/if_cp_filter_node, 64 | root_filter_node TYPE REF TO /iwbep/if_cp_filter_node. 65 | 66 | DATA: http_client TYPE REF TO if_web_http_client, 67 | odata_client_proxy TYPE REF TO /iwbep/if_cp_client_proxy, 68 | read_list_request TYPE REF TO /iwbep/if_cp_request_read_list, 69 | read_list_response TYPE REF TO /iwbep/if_cp_response_read_lst. 70 | 71 | DATA(http_destination) = cl_http_destination_provider=>create_by_url( i_url = 'https://sapes5.sapdevcenter.com' ). 72 | http_client = cl_web_http_client_manager=>create_by_http_destination( i_destination = http_destination ). 73 | 74 | odata_client_proxy = cl_web_odata_client_factory=>create_v2_remote_proxy( 75 | EXPORTING 76 | iv_service_definition_name = 'ZSC_RAP_PRODUCTS_####' 77 | io_http_client = http_client 78 | iv_relative_service_root = '/sap/opu/odata/sap/ZPDCDS_SRV/' ). 79 | 80 | " Navigate to the resource and create a request for the read operation 81 | read_list_request = odata_client_proxy->create_resource_for_entity_set( 'SEPMRA_I_PRODUCT_E' )->create_request_for_read( ). 82 | 83 | " Create the filter tree 84 | filter_factory = read_list_request->create_filter_factory( ). 85 | LOOP AT it_filter_cond INTO DATA(filter_condition). 86 | filter_node = filter_factory->create_by_range( iv_property_path = filter_condition-name 87 | it_range = filter_condition-range ). 88 | IF root_filter_node IS INITIAL. 89 | root_filter_node = filter_node. 90 | ELSE. 91 | root_filter_node = root_filter_node->and( filter_node ). 92 | ENDIF. 93 | ENDLOOP. 94 | 95 | IF root_filter_node IS NOT INITIAL. 96 | read_list_request->set_filter( root_filter_node ). 97 | ENDIF. 98 | 99 | IF top > 0 . 100 | read_list_request->set_top( top ). 101 | ENDIF. 102 | 103 | read_list_request->set_skip( skip ). 104 | 105 | " Execute the request and retrieve the business data 106 | read_list_response = read_list_request->execute( ). 107 | read_list_response->get_business_data( IMPORTING et_business_data = et_business_data ). 108 | 109 | ENDMETHOD. 110 | 111 | 112 | METHOD if_rap_query_provider~select. 113 | DATA business_data TYPE TABLE OF zrap_####_sepmra_i_product_e. 114 | DATA(top) = io_request->get_paging( )->get_page_size( ). 115 | DATA(skip) = io_request->get_paging( )->get_offset( ). 116 | DATA(requested_fields) = io_request->get_requested_elements( ). 117 | DATA(sort_order) = io_request->get_sort_elements( ). 118 | 119 | TRY. 120 | DATA(filter_condition) = io_request->get_filter( )->get_as_ranges( ). 121 | 122 | get_products( 123 | EXPORTING 124 | it_filter_cond = filter_condition 125 | top = CONV i( top ) 126 | skip = CONV i( skip ) 127 | IMPORTING 128 | et_business_data = business_data 129 | ) . 130 | 131 | io_response->set_total_number_of_records( lines( business_data ) ). 132 | io_response->set_data( business_data ). 133 | 134 | CATCH cx_root INTO DATA(exception). 135 | DATA(exception_message) = cl_message_helper=>get_latest_t100_exception( exception )->if_message~get_longtext( ). 136 | ENDTRY. 137 | ENDMETHOD. 138 | 139 | ENDCLASS. 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEV268 - SAP BTP ABAP Environment Connectivity and Integration 2 | 3 | [![REUSE status](https://api.reuse.software/badge/github.com/SAP-samples/teched2020-DEV268)](https://api.reuse.software/info/github.com/SAP-samples/teched2020-DEV268) 4 | 5 | ## Description 6 | 7 | This repository contains the material for the SAP TechEd 2020 session called *DEV268 - SAP Cloud Platform, ABAP Environment Connectivity and Integration.* 8 | 9 | ## Disclaimer 10 | 11 | > Note that this workshop was first offered in 2020; consequently, all its assets were created before the branding changes related to SAP technology were announced in January 2021. For example, SAP Cloud Platform, ABAP environment has been renamed to SAP Business Technology Platform (BTP), ABAP environment. 12 | 13 | ## Overview 14 | 15 | In this session we will show you how you can use SAP Cloud Platform, ABAP environment for side-by-side extension scenarios with SAP S/4 HANA using the ABAP RESTful Application Programming Model 16 | 17 | ![Side-by-side extension](images/intro_0020.jpg) 18 | 19 | Our scenario is an inventory application that runs on SAP Cloud Platform, ABAP environment. This application will use product master data from an on premise S/4 HANA system that will be retrieved via calling an OData service and via calling a SOAP web service. 20 | 21 | To speed up the development we will use a tool called the RAP Generator that generates the complete stack of a RAP business object based on one or more tables that have to be created beforehand. 22 | 23 | For this workshop we even prepared a class that also creates the table for the inventory data and then calls the RAP Generator to generate the RAP business object on top. This allows us to skip writing lots of boiler plate coding that you otherwise would have to write yourself. 24 | 25 | And we can start much faster with the implementation of our side-by-side integration scenario, so that it fits into the schedule of a 2-hour hands-on session. 26 | 27 | ## Requirements 28 | 29 | - You have created a trial account on SAP Cloud Platform: [Get a Free Trial Account on SAP Cloud Platform](https://developers.sap.com/tutorials/hcp-create-trial-account.html). 30 | - You have installed the ABAP Development Tools (ADT). [Get the ABAP Development Tools (ADT)](https://tools.hana.ondemand.com/#abap), section „Procedure“. 31 | - You have prepared your ABAP Trial which can be easily be done via the [SAP Cloud Platform cockpit](https://cockpit.hanatrial.ondemand.com) in just 3 steps. 32 | - Click on Enter **Your Trial Account**. 33 | ![Enter Trial](images/intro_0000.png) 34 | - Click on **Boosters** in the menu on the left hand side 35 | - Choose the tile **Prepare an Account for ABAP Trial** and follow the wizard 36 | ![Start booster](images/intro_0010.png) 37 | 38 | For a detailed step-by-step description check out our [Onboarding Tutorial](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/720c423ef1a8498ab690cf0e5512ba50.html#loio720c423ef1a8498ab690cf0e5512ba50__Create_ABAP_Trial_Instance). 39 | 40 | ## Download and Installation 41 | 42 | You have to download and install the ABAP Development Tools (ADT) as described in section [Requirements](#requirements) 43 | 44 | ## Known Issues 45 | 46 | There are no known issues. 47 | 48 | ## Exercises 49 | 50 | These are the steps of our hands-ons session: 51 | 52 | - [Getting Started](exercises/ex0/) 53 | - [Connect to the system](exercises/ex0#connect-to-the-system) 54 | - [Import the helper class - required on non-trial systems](exercises/ex0#import-of-the-helper-class-dmocl_gen_dev268_artifacts) 55 | - [Exercise 1 - Generate a starter application](exercises/ex1/README.md) 56 | - [Generate the data model](exercises/ex1/README.md#generate-the-data-model) 57 | - [Publish service](exercises/ex1#publish-service) 58 | - [Check the generated repository objects](exercises/ex1#check-the-generated-repository-objects) 59 | - [Behavior Implementation](exercises/ex1#behavior-implementation) 60 | - [Summary](exercises/ex1#summary) 61 | - [Solution](exercises/ex1/sources) 62 | 63 | - [Exercise 2 - Consume an OData service](exercises/ex2/README.md) 64 | - [Create the service consumption model](exercises/ex2#create-the-service-consumption-model) 65 | - [Create a console application to test the OData service](exercises/ex2#create-a-console-application-to-test-the-odata-service) 66 | - [Create a custom entity and implement the query implementation class](exercises/ex2#create-a-custom-entity-and-implement-the-query-implementation-class) 67 | - [Create a custom entity](exercises/ex2#create-a-custom-entity) 68 | - [Implement the query implemenation class](exercises/ex2#implement-the-query-implemenation-class) 69 | - [Add the custom entity as a value help](exercises/ex2#add-the-custom-entity-as-a-value-help) 70 | - [Test the service](exercises/ex2#test-the-service) 71 | - [Summary](exercises/ex2#summary) 72 | - [Solution](exercises/ex2/sources) 73 | 74 | - [Exercise 3 - Consume a SOAP Web service](exercises/ex3/README.md) 75 | - [Download the WSDL](exercises/ex3#download-the-wsdl) 76 | - [Create the Service Consumption Model](exercises/ex3#create-the-service-consumption-model) 77 | - [Add and implement a determination](exercises/ex3/README.md#add-and-implement-a-determination) 78 | - [Test the service](exercises/ex3/README.md#test-the-service) 79 | - [Solution](exercises/ex3/sources) 80 | 81 | 82 | ## How to obtain support 83 | 84 | Support for the content in this repository is available during the actual time of the online session for which this content has been designed. Otherwise, you may request support via the [Issues](../../issues) tab. 85 | 86 | ## License 87 | Copyright (c) 2020 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. 88 | 89 | -------------------------------------------------------------------------------- /exercises/ex3/sources/EPM_PRODUCT_SOAP.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | false 10 | 11 | 12 | 13 | 14 | false 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | false 24 | 25 | 26 | 27 | 28 | false 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | false 39 | 40 | 41 | 0050568C901D1ED79182D1F2706880F5 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | no 50 | false 51 | true 52 | false 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /exercises/ex3/sources/ex3_WSDL.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | false 10 | 11 | 12 | 13 | 14 | false 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | false 24 | 25 | 26 | 27 | 28 | false 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | false 39 | 40 | 41 | 0050568C901D1ED79182D1F2706880F5 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | no 50 | false 51 | true 52 | false 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /exercises/ex1/sources/zcl_generate_dev268.txt: -------------------------------------------------------------------------------- 1 | CLASS zcl_generate_dev268_#### DEFINITION 2 | PUBLIC 3 | INHERITING FROM cl_xco_cp_adt_simple_classrun 4 | FINAL 5 | CREATE PUBLIC . 6 | 7 | PUBLIC SECTION. 8 | 9 | PROTECTED SECTION. 10 | METHODS main REDEFINITION. 11 | PRIVATE SECTION. 12 | 13 | DATA package_name TYPE sxco_package VALUE 'ZRAP_INVENTORY_####'. 14 | DATA unique_number TYPE string VALUE '####'. 15 | DATA table_name_inventory TYPE sxco_dbt_object_name. 16 | DATA dev_system_environment TYPE REF TO if_xco_cp_gen_env_dev_system. 17 | DATA transport TYPE sxco_transport . 18 | 19 | 20 | METHODS generate_table IMPORTING io_put_operation TYPE REF TO if_xco_cp_gen_d_o_put 21 | table_name TYPE sxco_dbt_object_name 22 | table_short_description TYPE if_xco_cp_gen_tabl_dbt_s_form=>tv_short_description . 23 | 24 | METHODS get_json_string RETURNING VALUE(json_string) TYPE string. 25 | 26 | ENDCLASS. 27 | 28 | CLASS zcl_generate_dev268_#### IMPLEMENTATION. 29 | METHOD main. 30 | DATA json_string TYPE string. 31 | json_string = get_json_string( ). 32 | 33 | package_name = to_upper( package_name ). 34 | DATA(lo_package) = xco_cp_abap_repository=>object->devc->for( package_name ). 35 | 36 | IF NOT lo_package->exists( ). 37 | RAISE EXCEPTION TYPE /dmo/cx_rap_generator 38 | EXPORTING 39 | textid = /dmo/cx_rap_generator=>package_does_not_exist 40 | mv_value = CONV #( package_name ). 41 | ENDIF. 42 | 43 | table_name_inventory = |ZRAP_INVEN_{ unique_number }|. 44 | DATA(lo_table) = xco_cp_abap_repository=>object->tabl->for( CONV #( table_name_inventory ) ). 45 | 46 | IF lo_table->exists( ) = abap_false. 47 | 48 | DATA(lv_package_software_component) = lo_package->read( )-property-software_component->name. 49 | DATA(lo_transport_layer) = lo_package->read( )-property-transport_layer. 50 | DATA(lo_transport_target) = lo_transport_layer->get_transport_target( ). 51 | DATA(lv_transport_target) = lo_transport_target->value. 52 | DATA(lo_transport_request) = xco_cp_cts=>transports->workbench( lo_transport_target->value )->create_request( | create tables | ). 53 | DATA(lv_transport) = lo_transport_request->value. 54 | transport = lv_transport. 55 | dev_system_environment = xco_cp_generation=>environment->dev_system( lv_transport ). 56 | 57 | DATA(lo_objects_put_operation) = dev_system_environment->create_put_operation( ). 58 | 59 | generate_table( 60 | EXPORTING 61 | io_put_operation = lo_objects_put_operation 62 | table_name = table_name_inventory 63 | table_short_description = | Inventory data group { unique_number }| 64 | ). 65 | 66 | DATA(lo_result) = lo_objects_put_operation->execute( ). 67 | 68 | out->write( | table { table_name_inventory } created| ). 69 | 70 | DATA(lo_findings) = lo_result->findings. 71 | DATA(lt_findings) = lo_findings->get( ). 72 | 73 | IF lt_findings IS NOT INITIAL. 74 | out->write( lt_findings ). 75 | ENDIF. 76 | 77 | ELSE. 78 | out->write( | table { table_name_inventory } already exists| ). 79 | ENDIF. 80 | 81 | 82 | 83 | "create RAP BO 84 | 85 | DATA(rap_generator) = NEW /dmo/cl_rap_generator( json_string ). 86 | DATA(todos) = rap_generator->generate_bo( ). 87 | DATA(rap_bo_name) = rap_generator->root_node->rap_root_node_objects-service_binding. 88 | out->write( |RAP BO { rap_bo_name } generated successfully| ). 89 | out->write( |Todo's:| ). 90 | LOOP AT todos INTO DATA(todo). 91 | out->write( todo ). 92 | ENDLOOP. 93 | 94 | 95 | ENDMETHOD. 96 | 97 | 98 | METHOD generate_table. 99 | 100 | DATA(lo_specification) = io_put_operation->for-tabl-for-database_table->add_object( table_name 101 | )->set_package( package_name 102 | )->create_form_specification( ). 103 | 104 | lo_specification->set_short_description( table_short_description ). 105 | lo_specification->set_delivery_class( xco_cp_database_table=>delivery_class->l ). 106 | lo_specification->set_data_maintenance( xco_cp_database_table=>data_maintenance->allowed ). 107 | 108 | 109 | DATA database_table_field TYPE REF TO if_xco_gen_tabl_dbt_s_fo_field . 110 | 111 | database_table_field = lo_specification->add_field( 'CLIENT' ). 112 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'MANDT' ) )->set_key_indicator( )->set_not_null( ). 113 | 114 | database_table_field = lo_specification->add_field( 'UUID' ). 115 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'SYSUUID_X16' ) )->set_key_indicator( )->set_not_null( ). 116 | 117 | database_table_field = lo_specification->add_field( 'INVENTORY_ID' ). 118 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->numc( 6 ) ). 119 | 120 | database_table_field = lo_specification->add_field( 'PRODUCT_ID' ). 121 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->char( 10 ) ). 122 | 123 | 124 | database_table_field = lo_specification->add_field( 'QUANTITY' ). 125 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->quan( iv_length = 13 iv_decimals = 3 ) ). 126 | database_table_field->currency_quantity->set_reference_table( CONV #( to_upper( table_name ) ) )->set_reference_field( 'QUANTITY_UNIT' ). 127 | 128 | database_table_field = lo_specification->add_field( 'QUANTITY_UNIT' ). 129 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->unit( 3 ) ). 130 | 131 | database_table_field = lo_specification->add_field( 'PRICE' ). 132 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->curr( iv_length = 16 iv_decimals = 2 ) ). 133 | database_table_field->currency_quantity->set_reference_table( CONV #( to_upper( table_name ) ) )->set_reference_field( 'CURRENCY_CODE' ). 134 | 135 | database_table_field = lo_specification->add_field( 'CURRENCY_CODE' ). 136 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->cuky ). 137 | 138 | database_table_field = lo_specification->add_field( 'REMARK' ). 139 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->char( 256 ) ). 140 | 141 | database_table_field = lo_specification->add_field( 'NOT_AVAILABLE' ). 142 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'ABAP_BOOLEAN' ) ). 143 | 144 | database_table_field = lo_specification->add_field( 'CREATED_BY' ). 145 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'SYUNAME' ) ). 146 | 147 | database_table_field = lo_specification->add_field( 'CREATED_AT' ). 148 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'TIMESTAMPL' ) ). 149 | 150 | database_table_field = lo_specification->add_field( 'LAST_CHANGED_BY' ). 151 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'SYUNAME' ) ). 152 | 153 | database_table_field = lo_specification->add_field( 'LAST_CHANGED_AT' ). 154 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'TIMESTAMPL' ) ). 155 | 156 | ENDMETHOD. 157 | 158 | METHOD get_json_string. 159 | 160 | json_string ='{' && |\r\n| && 161 | ' "implementationType": "managed_uuid",' && |\r\n| && 162 | ' "namespace": "Z",' && |\r\n| && 163 | | "suffix": "_{ unique_number }",| && |\r\n| && 164 | ' "prefix": "RAP_",' && |\r\n| && 165 | | "package": "{ package_name }",| && |\r\n| && 166 | ' "datasourcetype": "table",' && |\r\n| && 167 | ' "bindingtype": "odata_v2_ui",' && |\r\n| && 168 | | "transportrequest": "{ transport }",| && |\r\n| && 169 | ' "hierarchy": {' && |\r\n| && 170 | ' "entityName": "Inventory",' && |\r\n| && 171 | | "dataSource": "zrap_inven_{ unique_number }",| && |\r\n| && 172 | ' "objectId": "inventory_id" ' && |\r\n| && 173 | ' }' && |\r\n| && 174 | '}'. 175 | 176 | ENDMETHOD. 177 | 178 | ENDCLASS. 179 | -------------------------------------------------------------------------------- /LICENSES/Apache-2.0.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | 3 | Version 2.0, January 2004 4 | 5 | http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, 6 | AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | 11 | 12 | "License" shall mean the terms and conditions for use, reproduction, and distribution 13 | as defined by Sections 1 through 9 of this document. 14 | 15 | 16 | 17 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 18 | owner that is granting the License. 19 | 20 | 21 | 22 | "Legal Entity" shall mean the union of the acting entity and all other entities 23 | that control, are controlled by, or are under common control with that entity. 24 | For the purposes of this definition, "control" means (i) the power, direct 25 | or indirect, to cause the direction or management of such entity, whether 26 | by contract or otherwise, or (ii) ownership of fifty percent (50%) or more 27 | of the outstanding shares, or (iii) beneficial ownership of such entity. 28 | 29 | 30 | 31 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions 32 | granted by this License. 33 | 34 | 35 | 36 | "Source" form shall mean the preferred form for making modifications, including 37 | but not limited to software source code, documentation source, and configuration 38 | files. 39 | 40 | 41 | 42 | "Object" form shall mean any form resulting from mechanical transformation 43 | or translation of a Source form, including but not limited to compiled object 44 | code, generated documentation, and conversions to other media types. 45 | 46 | 47 | 48 | "Work" shall mean the work of authorship, whether in Source or Object form, 49 | made available under the License, as indicated by a copyright notice that 50 | is included in or attached to the work (an example is provided in the Appendix 51 | below). 52 | 53 | 54 | 55 | "Derivative Works" shall mean any work, whether in Source or Object form, 56 | that is based on (or derived from) the Work and for which the editorial revisions, 57 | annotations, elaborations, or other modifications represent, as a whole, an 58 | original work of authorship. For the purposes of this License, Derivative 59 | Works shall not include works that remain separable from, or merely link (or 60 | bind by name) to the interfaces of, the Work and Derivative Works thereof. 61 | 62 | 63 | 64 | "Contribution" shall mean any work of authorship, including the original version 65 | of the Work and any modifications or additions to that Work or Derivative 66 | Works thereof, that is intentionally submitted to Licensor for inclusion in 67 | the Work by the copyright owner or by an individual or Legal Entity authorized 68 | to submit on behalf of the copyright owner. For the purposes of this definition, 69 | "submitted" means any form of electronic, verbal, or written communication 70 | sent to the Licensor or its representatives, including but not limited to 71 | communication on electronic mailing lists, source code control systems, and 72 | issue tracking systems that are managed by, or on behalf of, the Licensor 73 | for the purpose of discussing and improving the Work, but excluding communication 74 | that is conspicuously marked or otherwise designated in writing by the copyright 75 | owner as "Not a Contribution." 76 | 77 | 78 | 79 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 80 | of whom a Contribution has been received by Licensor and subsequently incorporated 81 | within the Work. 82 | 83 | 2. Grant of Copyright License. Subject to the terms and conditions of this 84 | License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, 85 | no-charge, royalty-free, irrevocable copyright license to reproduce, prepare 86 | Derivative Works of, publicly display, publicly perform, sublicense, and distribute 87 | the Work and such Derivative Works in Source or Object form. 88 | 89 | 3. Grant of Patent License. Subject to the terms and conditions of this License, 90 | each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, 91 | no-charge, royalty-free, irrevocable (except as stated in this section) patent 92 | license to make, have made, use, offer to sell, sell, import, and otherwise 93 | transfer the Work, where such license applies only to those patent claims 94 | licensable by such Contributor that are necessarily infringed by their Contribution(s) 95 | alone or by combination of their Contribution(s) with the Work to which such 96 | Contribution(s) was submitted. If You institute patent litigation against 97 | any entity (including a cross-claim or counterclaim in a lawsuit) alleging 98 | that the Work or a Contribution incorporated within the Work constitutes direct 99 | or contributory patent infringement, then any patent licenses granted to You 100 | under this License for that Work shall terminate as of the date such litigation 101 | is filed. 102 | 103 | 4. Redistribution. You may reproduce and distribute copies of the Work or 104 | Derivative Works thereof in any medium, with or without modifications, and 105 | in Source or Object form, provided that You meet the following conditions: 106 | 107 | (a) You must give any other recipients of the Work or Derivative Works a copy 108 | of this License; and 109 | 110 | (b) You must cause any modified files to carry prominent notices stating that 111 | You changed the files; and 112 | 113 | (c) You must retain, in the Source form of any Derivative Works that You distribute, 114 | all copyright, patent, trademark, and attribution notices from the Source 115 | form of the Work, excluding those notices that do not pertain to any part 116 | of the Derivative Works; and 117 | 118 | (d) If the Work includes a "NOTICE" text file as part of its distribution, 119 | then any Derivative Works that You distribute must include a readable copy 120 | of the attribution notices contained within such NOTICE file, excluding those 121 | notices that do not pertain to any part of the Derivative Works, in at least 122 | one of the following places: within a NOTICE text file distributed as part 123 | of the Derivative Works; within the Source form or documentation, if provided 124 | along with the Derivative Works; or, within a display generated by the Derivative 125 | Works, if and wherever such third-party notices normally appear. The contents 126 | of the NOTICE file are for informational purposes only and do not modify the 127 | License. You may add Your own attribution notices within Derivative Works 128 | that You distribute, alongside or as an addendum to the NOTICE text from the 129 | Work, provided that such additional attribution notices cannot be construed 130 | as modifying the License. 131 | 132 | You may add Your own copyright statement to Your modifications and may provide 133 | additional or different license terms and conditions for use, reproduction, 134 | or distribution of Your modifications, or for any such Derivative Works as 135 | a whole, provided Your use, reproduction, and distribution of the Work otherwise 136 | complies with the conditions stated in this License. 137 | 138 | 5. Submission of Contributions. Unless You explicitly state otherwise, any 139 | Contribution intentionally submitted for inclusion in the Work by You to the 140 | Licensor shall be under the terms and conditions of this License, without 141 | any additional terms or conditions. Notwithstanding the above, nothing herein 142 | shall supersede or modify the terms of any separate license agreement you 143 | may have executed with Licensor regarding such Contributions. 144 | 145 | 6. Trademarks. This License does not grant permission to use the trade names, 146 | trademarks, service marks, or product names of the Licensor, except as required 147 | for reasonable and customary use in describing the origin of the Work and 148 | reproducing the content of the NOTICE file. 149 | 150 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to 151 | in writing, Licensor provides the Work (and each Contributor provides its 152 | Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 153 | KIND, either express or implied, including, without limitation, any warranties 154 | or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR 155 | A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness 156 | of using or redistributing the Work and assume any risks associated with Your 157 | exercise of permissions under this License. 158 | 159 | 8. Limitation of Liability. In no event and under no legal theory, whether 160 | in tort (including negligence), contract, or otherwise, unless required by 161 | applicable law (such as deliberate and grossly negligent acts) or agreed to 162 | in writing, shall any Contributor be liable to You for damages, including 163 | any direct, indirect, special, incidental, or consequential damages of any 164 | character arising as a result of this License or out of the use or inability 165 | to use the Work (including but not limited to damages for loss of goodwill, 166 | work stoppage, computer failure or malfunction, or any and all other commercial 167 | damages or losses), even if such Contributor has been advised of the possibility 168 | of such damages. 169 | 170 | 9. Accepting Warranty or Additional Liability. While redistributing the Work 171 | or Derivative Works thereof, You may choose to offer, and charge a fee for, 172 | acceptance of support, warranty, indemnity, or other liability obligations 173 | and/or rights consistent with this License. However, in accepting such obligations, 174 | You may act only on Your own behalf and on Your sole responsibility, not on 175 | behalf of any other Contributor, and only if You agree to indemnify, defend, 176 | and hold each Contributor harmless for any liability incurred by, or claims 177 | asserted against, such Contributor by reason of your accepting any such warranty 178 | or additional liability. END OF TERMS AND CONDITIONS 179 | 180 | APPENDIX: How to apply the Apache License to your work. 181 | 182 | To apply the Apache License to your work, attach the following boilerplate 183 | notice, with the fields enclosed by brackets "[]" replaced with your own identifying 184 | information. (Don't include the brackets!) The text should be enclosed in 185 | the appropriate comment syntax for the file format. We also recommend that 186 | a file or class name and description of purpose be included on the same "printed 187 | page" as the copyright notice for easier identification within third-party 188 | archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | 194 | you may not use this file except in compliance with the License. 195 | 196 | You may obtain a copy of the License at 197 | 198 | http://www.apache.org/licenses/LICENSE-2.0 199 | 200 | Unless required by applicable law or agreed to in writing, software 201 | 202 | distributed under the License is distributed on an "AS IS" BASIS, 203 | 204 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 205 | 206 | See the License for the specific language governing permissions and 207 | 208 | limitations under the License. 209 | -------------------------------------------------------------------------------- /exercises/ex3/README.md: -------------------------------------------------------------------------------- 1 | # TOC 2 | [Home](../../README.md#exercises) 3 | # Exercise 3 - Consume a SOAP Web Service 4 | 5 | - [Download the WSDL](#download-the-wsdl) 6 | - [Create the Service Consumption Model](#create-the-service-consumption-model) 7 | - [Add and implement a determination](#add-and-implement-a-determination) 8 | - [Test the service](#test-the-service) 9 | - [Summary](#summary) 10 | - [Solution](#solution) 11 | 12 | In the following exercise you will learn how to call a SOAP web service and how to embed this into your inventory application by using it as part of a determination. The SOAP web service that we are going to use is a demo web service available on the SAP Gateway Demo system ES5. 13 | 14 | ## Download the WSDL 15 | 16 | 1. Create a text file with the extension .XML locally on your computer 17 | 2. Copy the content of the WSDL file into that file. The WSDL can be found here: [Link to WSDL](sources/ex3_WSDL.txt) 18 | 19 | 20 | ## Create the Service Consumption Model 21 | 22 | In this step we will create a service consumption model based on the WSDL file that you have downloaded in the previous step. 23 | 24 | 1. Navigate to the folder **Business Services > Service Consumption Models** 25 | 26 | 2. Right-click on the folder **Service Consumption Models** and choose **New Service Consumption Model** 27 | 28 | ![New Service Consumption Model](images/2010.png) 29 | 30 | 3. The New Service Consumption Model dialogue opens. Here enter the following data: 31 | 32 | Name: `ZSC_RAP_GETPRICE_####`
33 | Description: `Product price from ES5`
34 | Remote Consumption Model: `Web Service` (to be selected from the drop down box) 35 | 36 | ![Service Consumption Model](images/2020.png) 37 | 38 | 4. The WSDL file of the SOAP web service that you want to consume must be uploaded in file format. If you have not yet downloaded the WSDL file you have to do this now. 39 | 40 | - Click **Browse** to select the WSDL file that you have downloaded earlier in this exercise 41 | - Prefix: **`ZRAP_####_`** 42 | 43 | ![Web Service Consumption Proxy](images/2030.png) 44 | 45 | > **Caution** 46 | > Opposed to the prefix that we have chosen for **OData Service Consumption Proxy** we have to choose a leading **Z**. 47 | > If not, we get an error message that states: 48 | > *Package ZRAP_INVENTORY_#### is a customer package, object RAP_####_ is in SAP namespace. Use a valid combination of object name* 49 | > ![Web Service Consumption Proxy](images/2025.png) 50 | 51 | 52 | 53 | 54 | 5. Selection of transport request 55 | 56 | - Select a transport request 57 | - Press **Finish** 58 | 59 | ![Selection of transport request](images/2040.png) 60 | 61 | 6. Service Consumption Model 62 | 63 | The Web Service does only have one service operation `get_price`. 64 | 65 | > **Please note** 66 | > The wizard provides code samples for each service operation. The code can be copied using the the *Copy to clipboard* button. 67 | > We will not do this since in this exercise since we have provided a detailed code sample (see below) which is however based on the code snippet mentioned above. 68 | 69 | 70 | ![Web Service Consumption Proxy](images/2050.png) 71 | 72 | 7. Activate your changes 73 | 74 | Press the ![Activate your changes](images/activate.png) button to generate the service consumption model alongside with all dependend objects. 75 | 76 | 8. Check generated objects 77 | 78 | When refreshing your package in the *Project Explorer* you will notice that several objects have been generated. For those that are used to the generation of SOAP Web Service proxies in on premise systems they will look familiar. 79 | 80 | ![Web Service Consumption Proxy](images/2060.png) 81 | 82 | 83 | 84 | ## Add and implement a determination 85 | 86 | 1. Add a determination in the **behavior definition** 87 | 88 | - Open your behavior definition `ZI_RAP_INVENTORY_####` 89 | - Add the following code snippet to add a determination for the field `Price` 90 | 91 |
 92 |    determination GetPrice on modify { field ProductID; }
 93 |    
94 | 95 | ![Web Service Consumption Proxy](images/2065.png) 96 | 97 | - Select the determination name `GetPrice` and press **CTRL+1** for a quick fix 98 | - Double click on the quick fix **Add missing method for determination GetPrice in local handler class ...** 99 | 100 | ![Web Service Consumption Proxy](images/2070.png) 101 | 102 | 2. Add the following code in the implementation of the method `GetPrice`. 103 | 104 | > **Coding explained** 105 | > The following code is using large parts of the code snippets provided by the service consumption model. 106 | > It has however been adjusted to fit our needs. 107 | > 1. The destination is not retrieved by calling the method `cl_soap_destination_provider=>create_by_cloud_destination( )` but by using the method `cl_soap_destination_provider=>create_by_url( )`. This is because the destination service is not available in the ABAP trial systems in SAP Cloud Platform. 108 | > 2. Instead of using an inline declaration for `destination`and `proxy` these variables are defined beforehand. This way we can avoid that the destination and proxy object are created several times in case multiple inventories are to be created. 109 | > 3. The data retrieved from the SOAP call is used to update the inventory data via EML. 110 | 111 | > **Do not forget to search and replace the placeholder `####` with the unique number that you have chosen beforehand.** 112 | 113 |
114 |   
115 |      METHOD GetPrice.
116 | 
117 |     DATA destination  TYPE REF TO if_soap_destination.
118 |     DATA proxy TYPE REF TO zrap_####_co_epm_product_soap .
119 |     DATA reported_inventory_soap LIKE reported-inventory.
120 |     "Ensure idempotence
121 |     READ ENTITIES OF zi_rap_inventory_#### IN LOCAL MODE
122 |       ENTITY Inventory
123 |         FIELDS ( Price ProductID )
124 |         WITH CORRESPONDING #( keys )
125 |       RESULT DATA(inventories).
126 | 
127 |     DELETE inventories WHERE Price IS NOT INITIAL.
128 |     CHECK inventories IS NOT INITIAL.
129 | 
130 |     DELETE inventories WHERE ProductID =''.
131 |     CHECK inventories IS NOT INITIAL.
132 | 
133 |     LOOP AT inventories ASSIGNING FIELD-SYMBOL(<inventory>).
134 | 
135 |       TRY.
136 | 
137 |           IF destination IS INITIAL.
138 |             destination = cl_soap_destination_provider=>create_by_url( i_url = 'https://sapes5.sapdevcenter.com/sap/bc/srt/xip/sap/zepm_product_soap/002/epm_product_soap/epm_product_soap' ).
139 |           ENDIF.
140 |           IF proxy IS INITIAL.
141 |             proxy = NEW zrap_####_co_epm_product_soap(
142 |                              destination = destination
143 |                            ).
144 |           ENDIF.
145 | 
146 |           DATA(request) = VALUE zrap_####_req_msg_type( req_msg_type-product = <inventory>-ProductID ).
147 |           proxy->get_price(
148 |             EXPORTING
149 |               input = request
150 |             IMPORTING
151 |               output = DATA(response)
152 |           ).
153 | 
154 |           <inventory>-Price = response-res_msg_type-price .
155 |           <inventory>-CurrencyCode = response-res_msg_type-currency.
156 |           "handle response
157 | 
158 |         CATCH cx_soap_destination_error INTO DATA(soap_destination_error).
159 |           DATA(error_message) = soap_destination_error->get_text(  ).
160 |         CATCH cx_ai_system_fault INTO DATA(ai_system_fault).
161 |           error_message = | code: { ai_system_fault->code  } codetext: { ai_system_fault->codecontext  }  |.
162 |         CATCH zrap_####_cx_fault_msg_type INTO DATA(soap_exception).
163 |           error_message = soap_exception->error_text.
164 |           "fill reported structure to be displayed on the UI
165 |           APPEND VALUE #( uuid = <inventory>-uuid
166 |                           %msg = new_message( id = 'ZCM_RAP_GENERATOR'
167 |                                               number = '016'
168 |                                               v1 = error_message
169 |                                               "v2 = messages[ 1 ]-msgv2
170 |                                               "v3 = messages[ 1 ]-msgv3
171 |                                               "v4 = messages[ 1 ]-msgv4
172 |                                               severity = CONV #( 'E' ) )
173 |                            %element-price = if_abap_behv=>mk-on
174 | 
175 | 
176 |     ) TO reported_inventory_soap.
177 |           "inventory entries where no price could be retrieved must not be passed to the MODIFY statement
178 |           DELETE inventories INDEX sy-tabix.
179 |       ENDTRY.
180 | 
181 |     ENDLOOP.
182 | 
183 |     "update involved instances
184 |     MODIFY ENTITIES OF zi_rap_inventory_#### IN LOCAL MODE
185 |       ENTITY Inventory
186 |         UPDATE FIELDS ( Price CurrencyCode )
187 |         WITH VALUE #( FOR inventory IN inventories (
188 |                            %tky      = inventory-%tky
189 |                            Price  = inventory-Price
190 |                            CurrencyCode  = inventory-CurrencyCode
191 |                            ) )
192 |     REPORTED DATA(reported_entities).
193 | 
194 |     "fill reported
195 |     reported = CORRESPONDING #( DEEP reported_entities ).
196 | 
197 |     "add reported from SOAP call
198 |     LOOP AT reported_inventory_soap INTO DATA(reported_inventory).
199 |       APPEND reported_inventory TO reported-inventory.
200 |     ENDLOOP.
201 | 
202 | 
203 |   ENDMETHOD.
204 | 
205 | 
206 | 207 | 3. Activate your changes. 208 | 209 | ## Test the service 210 | 211 | 1. Test service with Fiori Elements preview. 212 | 213 | - Open the service binding ZUI_RAP_INVENTORY_####_02 (either via Ctrl+Shift+A or via navigation in the Project Explorer) 214 | - Select the entity `Ìnventory`. 215 | - Press the **Preview** button 216 | 217 | ![Open the Fiori Elements preview](images/2080.png) 218 | 2. Create a new inventory entry and select a valid product id using the value help 219 | 220 | - Select a valid ProductID via the value help (e.g. HT-1000) 221 | 222 | ![Create inventory with valid product name](images/2110.png) 223 | 224 | 3. Press the **Create** button 225 | 226 | - When pressing the **Create** button the determination for the price will call the SOAP service 227 | - The inventory will be created with the price and the currency retrieved from the backend 228 | 229 | ![Inventory with product price](images/2120.png) 230 | 231 | 4. Create an inventory entry with an invalid ProductID (e.g. www). 232 | 233 | - Enter an invalid ProductID, e.g. `www` 234 | 235 | ![Inventory with invalid product price](images/2130.png) 236 | 237 | - The SOAP call will not be able to find the ProductId in the backend and will hence respond with the error message `Product not found. Try e.g. HT-1000 :)`. 238 | 239 | ![Error message from SOAP call](images/2140.png) 240 | 241 | ## Summary 242 | 243 | In this session you have learned how you can use SAP Cloud Platform, ABAP environment to implement a side-by-side extension scenarios for an SAP S/4 HANA system using the ABAP RESTful Application Programming Model. 244 | 245 | You have retrieved data from the SAP S/4HANA system using OData and SOAP based communication to implement 246 | 247 | - a value help to select a product for an inventory entry 248 | - a determination for the price of a product 249 | 250 | ![Extension scenarios](images/2500.png) 251 | 252 | In a licensed SAP Cloud Platform, ABAP Environment system you would also be able to create a service consumption model for RFC function modules. 253 | 254 | ## Solution 255 | 256 | [Source code used in this exercise](sources) 257 | -------------------------------------------------------------------------------- /src/#dmo#cl_gen_dev268_artifacts.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS /dmo/cl_gen_dev268_artifacts DEFINITION 2 | PUBLIC 3 | INHERITING FROM cl_xco_cp_adt_simple_classrun 4 | FINAL 5 | CREATE PUBLIC . 6 | 7 | PUBLIC SECTION. 8 | 9 | PROTECTED SECTION. 10 | METHODS main REDEFINITION. 11 | PRIVATE SECTION. 12 | 13 | CONSTANTS: 14 | co_prefix TYPE string VALUE 'ZRAP_INVENTORY_', 15 | co_zlocal_package TYPE sxco_package VALUE 'ZLOCAL', 16 | co_session_name TYPE string VALUE 'DEV268'. 17 | 18 | 19 | DATA package_name TYPE sxco_package VALUE 'ZRAP_INVENTORY_####'. 20 | DATA unique_number TYPE string VALUE '####'. 21 | DATA table_name_inventory TYPE sxco_dbt_object_name. 22 | DATA dev_system_environment TYPE REF TO if_xco_cp_gen_env_dev_system. 23 | DATA transport TYPE sxco_transport . 24 | DATA transport_request TYPE sxco_transport. 25 | 26 | METHODS generate_table IMPORTING io_put_operation TYPE REF TO if_xco_cp_gen_d_o_put 27 | table_name TYPE sxco_dbt_object_name 28 | table_short_description TYPE if_xco_cp_gen_tabl_dbt_s_form=>tv_short_description . 29 | 30 | METHODS get_json_string RETURNING VALUE(json_string) TYPE string. 31 | 32 | METHODS get_unique_suffix IMPORTING VALUE(s_prefix) TYPE string RETURNING VALUE(s_unique_suffix) TYPE string. 33 | METHODS create_transport RETURNING VALUE(lo_transport) TYPE sxco_transport. 34 | METHODS create_package IMPORTING VALUE(lo_transport) TYPE sxco_transport. 35 | 36 | 37 | ENDCLASS. 38 | 39 | 40 | 41 | CLASS /dmo/cl_gen_dev268_artifacts IMPLEMENTATION. 42 | 43 | METHOD main. 44 | DATA json_string TYPE string. 45 | 46 | 47 | unique_number = get_unique_suffix( co_prefix ). 48 | 49 | package_name = |ZRAP_INVENTORY_{ unique_number }|. 50 | 51 | package_name = to_upper( package_name ). 52 | 53 | out->write( | BEGIN OF GENERATION ({ cl_abap_context_info=>get_system_date( ) } { cl_abap_context_info=>get_system_time( ) } UTC) ... | ). 54 | out->write( | - Package: { package_name } | ). 55 | out->write( | - Group ID: { unique_number } | ). 56 | 57 | "create transport 58 | transport_request = create_transport( ). 59 | "create package 60 | create_package( transport_request ). 61 | 62 | json_string = get_json_string( ). 63 | 64 | DATA(lo_package) = xco_cp_abap_repository=>object->devc->for( package_name ). 65 | * 66 | * IF NOT lo_package->exists( ). 67 | * RAISE EXCEPTION TYPE /dmo/cx_rap_generator 68 | * EXPORTING 69 | * textid = /dmo/cx_rap_generator=>package_does_not_exist 70 | * mv_value = CONV #( package_name ). 71 | * ENDIF. 72 | 73 | table_name_inventory = |ZRAP_INVEN_{ unique_number }|. 74 | DATA(lo_table) = xco_cp_abap_repository=>object->tabl->for( CONV #( table_name_inventory ) ). 75 | 76 | IF lo_table->exists( ) = abap_false. 77 | 78 | * DATA(lv_package_software_component) = lo_package->read( )-property-software_component->name. 79 | * DATA(lo_transport_layer) = lo_package->read( )-property-transport_layer. 80 | * DATA(lo_transport_target) = lo_transport_layer->get_transport_target( ). 81 | * DATA(lv_transport_target) = lo_transport_target->value. 82 | * DATA(lo_transport_request) = xco_cp_cts=>transports->workbench( lo_transport_target->value )->create_request( | create tables | ). 83 | * DATA(lv_transport) = lo_transport_request->value. 84 | * transport = lv_transport. 85 | * dev_system_environment = xco_cp_generation=>environment->dev_system( lv_transport ). 86 | 87 | dev_system_environment = xco_cp_generation=>environment->dev_system( transport_request ). 88 | 89 | DATA(lo_objects_put_operation) = dev_system_environment->create_put_operation( ). 90 | 91 | generate_table( 92 | EXPORTING 93 | io_put_operation = lo_objects_put_operation 94 | table_name = table_name_inventory 95 | table_short_description = | Inventory data group { unique_number }| 96 | ). 97 | 98 | DATA(lo_result) = lo_objects_put_operation->execute( ). 99 | 100 | out->write( | table { table_name_inventory } created| ). 101 | 102 | DATA(lo_findings) = lo_result->findings. 103 | DATA(lt_findings) = lo_findings->get( ). 104 | 105 | IF lt_findings IS NOT INITIAL. 106 | out->write( lt_findings ). 107 | ENDIF. 108 | 109 | ELSE. 110 | out->write( | table { table_name_inventory } already exists| ). 111 | ENDIF. 112 | 113 | 114 | 115 | "create RAP BO 116 | 117 | DATA(rap_generator) = NEW /dmo/cl_rap_generator( json_string ). 118 | DATA(todos) = rap_generator->generate_bo( ). 119 | DATA(rap_bo_name) = rap_generator->root_node->rap_root_node_objects-service_binding. 120 | out->write( |RAP BO { rap_bo_name } generated successfully| ). 121 | out->write( |Todo's:| ). 122 | LOOP AT todos INTO DATA(todo). 123 | out->write( todo ). 124 | ENDLOOP. 125 | 126 | 127 | ENDMETHOD. 128 | 129 | 130 | METHOD generate_table. 131 | 132 | DATA(lo_specification) = io_put_operation->for-tabl-for-database_table->add_object( table_name 133 | )->set_package( package_name 134 | )->create_form_specification( ). 135 | 136 | lo_specification->set_short_description( table_short_description ). 137 | lo_specification->set_delivery_class( xco_cp_database_table=>delivery_class->l ). 138 | lo_specification->set_data_maintenance( xco_cp_database_table=>data_maintenance->allowed ). 139 | 140 | 141 | DATA database_table_field TYPE REF TO if_xco_gen_tabl_dbt_s_fo_field . 142 | 143 | database_table_field = lo_specification->add_field( 'CLIENT' ). 144 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'MANDT' ) )->set_key_indicator( )->set_not_null( ). 145 | 146 | database_table_field = lo_specification->add_field( 'UUID' ). 147 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'SYSUUID_X16' ) )->set_key_indicator( )->set_not_null( ). 148 | 149 | database_table_field = lo_specification->add_field( 'INVENTORY_ID' ). 150 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->numc( 6 ) ). 151 | 152 | database_table_field = lo_specification->add_field( 'PRODUCT_ID' ). 153 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->char( 10 ) ). 154 | 155 | 156 | database_table_field = lo_specification->add_field( 'QUANTITY' ). 157 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->quan( iv_length = 13 iv_decimals = 3 ) ). 158 | database_table_field->currency_quantity->set_reference_table( CONV #( to_upper( table_name ) ) )->set_reference_field( 'QUANTITY_UNIT' ). 159 | 160 | database_table_field = lo_specification->add_field( 'QUANTITY_UNIT' ). 161 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->unit( 3 ) ). 162 | 163 | database_table_field = lo_specification->add_field( 'PRICE' ). 164 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->curr( iv_length = 16 iv_decimals = 2 ) ). 165 | database_table_field->currency_quantity->set_reference_table( CONV #( to_upper( table_name ) ) )->set_reference_field( 'CURRENCY_CODE' ). 166 | 167 | database_table_field = lo_specification->add_field( 'CURRENCY_CODE' ). 168 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->cuky ). 169 | 170 | database_table_field = lo_specification->add_field( 'REMARK' ). 171 | database_table_field->set_type( xco_cp_abap_dictionary=>built_in_type->char( 256 ) ). 172 | 173 | database_table_field = lo_specification->add_field( 'NOT_AVAILABLE' ). 174 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'ABAP_BOOLEAN' ) ). 175 | 176 | database_table_field = lo_specification->add_field( 'CREATED_BY' ). 177 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'SYUNAME' ) ). 178 | 179 | database_table_field = lo_specification->add_field( 'CREATED_AT' ). 180 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'TIMESTAMPL' ) ). 181 | 182 | database_table_field = lo_specification->add_field( 'LAST_CHANGED_BY' ). 183 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'SYUNAME' ) ). 184 | 185 | database_table_field = lo_specification->add_field( 'LAST_CHANGED_AT' ). 186 | database_table_field->set_type( xco_cp_abap_dictionary=>data_element( 'TIMESTAMPL' ) ). 187 | 188 | ENDMETHOD. 189 | 190 | METHOD get_json_string. 191 | 192 | json_string ='{' && |\r\n| && 193 | ' "implementationType": "managed_uuid",' && |\r\n| && 194 | ' "namespace": "Z",' && |\r\n| && 195 | | "suffix": "_{ unique_number }",| && |\r\n| && 196 | ' "prefix": "RAP_",' && |\r\n| && 197 | | "package": "{ package_name }",| && |\r\n| && 198 | ' "datasourcetype": "table",' && |\r\n| && 199 | ' "bindingtype": "odata_v2_ui",' && |\r\n| && 200 | | "transportrequest": "{ transport_request }",| && |\r\n| && 201 | ' "hierarchy": {' && |\r\n| && 202 | ' "entityName": "Inventory",' && |\r\n| && 203 | | "dataSource": "zrap_inven_{ unique_number }",| && |\r\n| && 204 | ' "objectId": "inventory_id" ' && |\r\n| && 205 | ' }' && |\r\n| && 206 | '}'. 207 | 208 | ENDMETHOD. 209 | 210 | 211 | METHOD create_package. 212 | DATA(lo_put_operation) = xco_cp_generation=>environment->dev_system( lo_transport )->for-devc->create_put_operation( ). 213 | DATA(lo_specification) = lo_put_operation->add_object( package_name )->create_form_specification( ). 214 | lo_specification->set_short_description( |{ co_session_name } tutorial package - { unique_number }| ). 215 | lo_specification->properties->set_super_package( co_zlocal_package )->set_software_component( co_zlocal_package ). 216 | lo_put_operation->execute( ). 217 | ENDMETHOD. 218 | 219 | METHOD create_transport. 220 | DATA(ls_package) = xco_cp_abap_repository=>package->for( co_zlocal_package )->read( ). 221 | DATA(lv_transport_layer) = ls_package-property-transport_layer->value. 222 | DATA(lv_transport_target) = ls_package-property-transport_layer->get_transport_target( )->value. 223 | DATA(lo_transport_request) = xco_cp_cts=>transports->workbench( lv_transport_target )->create_request( |{ co_session_name } generated tranport request - { unique_number }| ). 224 | 225 | * IF lo_transport_request->get_status( ) = xco_cp_transport=>filter->status( xco_cp_transport=>status->modifiable ). 226 | * DATA(lo_transport_modifiable) = abap_true. 227 | * ENDIF. 228 | 229 | lo_transport = lo_transport_request->value. 230 | ENDMETHOD. 231 | 232 | METHOD get_unique_suffix. 233 | DATA: li_counter(4) TYPE n, 234 | ls_counter TYPE string, 235 | ls_package_name TYPE sxco_package, 236 | is_valid_package TYPE abap_bool. 237 | 238 | 239 | s_unique_suffix = ''. 240 | is_valid_package = abap_false. 241 | li_counter = 0. 242 | ls_counter = li_counter. 243 | ls_package_name = s_prefix && ls_counter. 244 | 245 | WHILE is_valid_package = abap_false. 246 | "check package name 247 | DATA(lo_package) = xco_cp_abap_repository=>object->devc->for( ls_package_name ). 248 | IF NOT lo_package->exists( ). 249 | is_valid_package = abap_true. 250 | s_unique_suffix = ls_counter. 251 | ENDIF. 252 | li_counter = li_counter + 1. 253 | ls_counter = li_counter. 254 | ls_package_name = s_prefix && ls_counter. 255 | ENDWHILE. 256 | ENDMETHOD. 257 | 258 | ENDCLASS. 259 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /exercises/ex1/README.md: -------------------------------------------------------------------------------- 1 | 2 | [Home](../../README.md#exercises) 3 | 4 | # Exercise 1 5 | 6 | 7 | - [Generate the data model](#generate-the-data-model) 8 | - [Publish service](#publish-service) 9 | - [Check the generated repository objects](#check-the-generated-repository-objects) 10 | - [Behavior Implementation](#behavior-implementation) 11 | - [Summary](#summary) 12 | - [Solution](sources) 13 | 14 | In this exercise, we will create a starter application to collect inventory data. 15 | 16 | The usual process of development would be that you as a developer would now start to manually create the following repository objects for each entity 17 | 18 | - Table 19 | - CDS interface view 20 | - CDS projection view 21 | - Metadata Extension view 22 | - Behavior definition 23 | - Behavior implementation 24 | 25 | before you can start with the implementation of the business logic. 26 | 27 | In the ABAP trial systems we have thus prepared a helper class **/dmo/cl_gen_dev268_artifacts** to generate the database table to store the inventory data and different CDS artefacts needed for the next exercises. 28 | 29 | Since this is a green field scenario the application will be implemented using a **managed business object** that is based on the **ABAP RESTful Application Programming Model (RAP)**. 30 | 31 | This application will then be enhanced such that it leverages OData service calls and SOAP calls to retrieve data from a SAP S/4HANA backend. These services are either called as a value help or to perform a determination for the price of a product whenthe inventory data is created or updated. 32 | 33 | ## Generate the data model 34 | 35 | 1. Select the **Open ABAP Development Object** icon or press **Ctrl+Shift+A**. 36 | 37 | ![Open ABAP Development Object](images/00_001_DEV268.png) 38 | 39 | 2. In the *Open ABAP Development Object* dialogue enter **/dmo/cl_gen_dev268_artifacts** as search string and press **OK**. 40 | 41 | ![Generate Data Model](images/00_002_DEV268.png) 42 | 43 | 2. The class **/dmo/cl_gen_dev268_artifacts** is displayed in a new tab. 44 | 45 | ![Generate Data Model](images/00_003_DEV268.png) 46 | 47 | 3. Press **F9** to run the ABAP class as a console application. As a result, you will see a success message in the Console. 48 | 49 | ![Generate Data Model](images/00_004_DEV268.png) 50 | 51 | 4. Please note down your group ID **`####`** and copy the name of the newly created package **ZRAP_INVENTORY_####** 52 |
    
 53 |      ... 
 54 |      - Package: ZRAP_INVENTORY_#### 
 55 |      - Group ID: ####
 56 |      ...
 57 |      
58 | 59 | 5. Right click on the folder **Favorite Packages** and select **Add Package...**. 60 | 61 | ![Open ABAP Development Object](images/00_005_DEV268.png) 62 | 63 | 6. Enter the name of your package **ZRAP_INVENTORY_####** and press **OK**. 64 | 65 | 66 | ## Publish service 67 | 68 | 1. The helper class **/dmo/cl_gen_dev268_artifacts** has done the following: 69 | 70 | - Using the XCO framework it has created a table to store the inventory data 71 | - It then has called the RAP Genertor which has generated the following repository objects for your convenience based on the table that has been generated beforehand 72 | 73 | Business Services 74 | - ZUI_RAP_INVENTORY_####_02 - Service Binding 75 | - ZUI_RAP_INVENTORY_#### - Service Definition 76 | 77 | CDS views 78 | - ZC_RAP_INVENTORY_#### - Projection view 79 | - ZI_RAP_INVENTORY_#### - Interface view 80 | 81 | Metadata Extension 82 | - ZC_RAP_INVENTORY_#### - MDE for the projection view 83 | 84 | Behavior Defintion 85 | - ZC_RAP_INVENTORY_#### - for the projection view 86 | - ZI_RAP_INVENTORY_#### - for the interface view 87 | 88 | 89 | > What is now left is to publish the service binding since this can not be automated (yet). 90 | 91 | 92 | 2. Open the service binding and double click on **ZUI_RAP_INVENTORY_####_O2** 93 | (in older versions of the RAP Generator it reads _02 instead of _O2) 94 | 95 | ![Open Service Binding](images/0435.png) 96 | 97 | 3. Click on **Publish** to publish the Service Binding. 98 | 99 | ![Publish Service Binding](images/0440.png) 100 | 101 | 4. Select the entity **Inventory** and press the **Preview** button to start the *Fiori Elements Preview*. 102 | 103 | (The service also contains an entity I_Currency since the RAP Generator has added a value help for Currencies to the projection view.) 104 | 105 | ![Start Fiori Elements Preview](images/0460.png) 106 | 107 | 5. Check the Fiori Elements Preview App. You will notice that we got a nearly full fledged UI with capabilities for 108 | 109 | - Searching 110 | - Filtering 111 | - Create and Delete inventory data 112 | - Update, visible when having created data 113 | 114 | This is because all possible behaviors (create, update and delete) have been enabled by default in our generated code. 115 | You will see that all CRUD operations are working out of the box (apart from calculating the inventory id, which we will do in a second). 116 | In addition all columns of the table are displayed by default as well since we have generated appropriate UI annoations. 117 | If you do not want to see all columns (either on the list- or the object page) you can comment out these annotations. 118 | This is however much simpler than having to write all these annotations from scratch. 119 | 120 | 16. You can try and start entering values for your first inventory item. 121 | However no checks nor any value help have been implemented yet. 122 | Especially not for the determination of the semantic key **InventoryId**. 123 | 124 | This we will do in the next step. 125 | 126 | 127 | ![Fiori Elements Preview](images/0470.png) 128 | 129 | ## Check the generated repository objects 130 | 131 | The **interface view ZI_RAP_Inventory_####** was generated such that based on the ABAP field names aliases have been created such that the ABAP field name was converted into camelCase notation. 132 | 133 |
134 | define root view entity ZI_RAP_INVENTORY_1234
135 |   as select from zrap_inven_1234
136 | {
137 |   key UUID as UUID,  
138 |   INVENTORY_ID as InventoryID,  
139 |   PRODUCT_ID as ProductID,  
140 |   @Semantics.quantity.unitOfMeasure: 'QuantityUnit'
141 |   QUANTITY as Quantity,  
142 |   QUANTITY_UNIT as QuantityUnit,
143 |   ...
144 |  }
145 | 
146 | 147 | The **projection view ZC_RAP_Inventory_####** was generated such that it contains annotations for **search** and a value help for the field **CurrencyCode**. 148 | 149 |
150 | define root view entity ZC_RAP_INVENTORY_####
151 |   as projection on ZI_RAP_Inventory_####
152 | {
153 |   @Search.defaultSearchElement: true
154 |   key UUID,
155 |   
156 |   @Search.defaultSearchElement: true
157 |   InventoryID,
158 |   
159 |   ProductID,
160 |   
161 |   Quantity,
162 |   
163 |   QuantityUnit,
164 |   
165 |   @Semantics.amount.currencyCode: 'CurrencyCode'
166 |   Price,
167 |   
168 |   @Consumption.valueHelpDefinition: [ {
169 |     entity: {
170 |       name: 'I_Currency', 
171 |       element: 'Currency'
172 |     }
173 |   } ]
174 |   CurrencyCode,
175 | 
176 | 177 | The **behavior definion ZI_RAP_Inventory_####** was generated such that the field **InventoryID** which acts as a semantic key was marked as readonly. 178 | 179 |
180 | field ( readonly ) InventoryID;
181 | 
182 | 183 | also a mapping was added that maps the ABAP field names to the field names of the CDS views. 184 | 185 |
186 |   mapping for zrap_inven_1234
187 |   {
188 |     UUID = UUID;
189 |     InventoryID = INVENTORY_ID;
190 |     ProductID = PRODUCT_ID;
191 |     Quantity = QUANTITY;
192 |     QuantityUnit = QUANTITY_UNIT;
193 |     Remark = REMARK;
194 |     NotAvailable = NOT_AVAILABLE;
195 |     CreatedBy = CREATED_BY;
196 |     CreatedAt = CREATED_AT;
197 |     LastChangedBy = LAST_CHANGED_BY;
198 |     LastChangedAt = LAST_CHANGED_AT;
199 |   }
200 | 
201 | 202 | And we find a determination that was generated for the semantic key field (that has to be implemented though). 203 | 204 | Please make sure that the determination that is performed during the **'save*** sequence for the InventoryID is triggered by **'create'** operation. 205 | *(in older versions the RAP Generator created a determination that acts on the modify operation)* 206 | 207 |
208 | determination CalculateInventoryID on save { create; }
209 | 
210 | 211 | ## Change the generated code of the Metadata Extension File 212 | 213 | Last but not least, you will find it handy that a **Metadata Extension View ZC_RAP_Inventory_####** has also been generated that automatically publishes all field on the list page as well as on the object page by setting appropriate **@UI** annotations. 214 | 215 | Also the administrative fields like created_at as well as the UUID based key field are hidden by setting **@UI.hidden** to true. 216 | 217 | In the version of the RAP Generator which is currently deployed to SAP BTP ABAP evnironment trial ualso the fields **CurrencyCode** and **QuantityUnit** have been marked as **@UI.hidden**. 218 | 219 | Please change the code such that you remove the annotation **@UI.hidden** for QuantityUnit and CurrencyCode so that the code now reads: 220 | 221 | - QuantityUnit 222 | 223 |
224 |   @UI.lineItem: [ {
225 |   position: 50 ,
226 |   importance: #HIGH,
227 |   label: 'Unit'
228 |   } ]
229 |   @UI.identification: [ {
230 |     position: 50 ,
231 |     label: 'Unit'
232 |   } ]
233 |   QuantityUnit;
234 |   
235 | 236 | - CurrencyCode 237 | 238 |
239 |   @UI.lineItem: [ {
240 |   position: 70 ,
241 |   importance: #HIGH,
242 |   label: 'Currency'
243 |   } ]
244 |   @UI.identification: [ {
245 |     position: 70 ,
246 |     label: 'Currency'
247 |   } ] 
248 |   CurrencyCode;
249 |   
250 | 251 | - Do not forget to **Activate** your changes. 252 | 253 | ## Behavior Implementation 254 | 255 | 1. In the **Project Explorer** navigate to **Source Code Library > Classes** and double click on **ZBP_I_RAP_INVENTORY_####** 256 | 257 | ![Open Behavior Implementation](images/0500.png) 258 | 259 | 2. Navigate to the tab **Local Types** 260 | 261 | In the source code of the local class you will see that there is one method called **calculateinventoryid**. 262 | 263 | 3. Add the code shown below to implement the determination for the field **InventoryID** 264 | 265 | The code of the behavior implementation contains already an (empty) implementation for the determiniation that shall calculate the semantic key InventoryID. 266 | 267 | The implementation of the behavior defintion must (for technical reasons) take place in local classes that follow the naming convention **lhc_\** (here **lhc_Inventory**). 268 | We suggest to use the source code shown below to implement the calculation of the semantic key of our managed business object for inventory data. In a productive application you would rather use a number range. 269 | To keep our implementation simple we will use the approach to simply count the number of objects that are available. 270 | By a simple increment of this number we get a semantic key which is readable by the users of our application. 271 | 272 | 273 | 274 |
 
275 |  
276 | METHOD CalculateInventoryID.
277 | 
278 |   "Ensure idempotence
279 |     READ ENTITIES OF zi_rap_inventory_#### IN LOCAL MODE
280 |       ENTITY Inventory
281 |         FIELDS ( InventoryID )
282 |         WITH CORRESPONDING #( keys )
283 |       RESULT DATA(inventories).
284 | 
285 |     DELETE inventories WHERE InventoryID IS NOT INITIAL.
286 |     CHECK inventories IS NOT INITIAL.
287 | 
288 |     "Get max travelID
289 |     SELECT SINGLE FROM zrap_inven_#### FIELDS MAX( inventory_id ) INTO @DATA(max_inventory).
290 | 
291 |     "update involved instances
292 |     MODIFY ENTITIES OF zi_rap_inventory_#### IN LOCAL MODE
293 |       ENTITY Inventory
294 |         UPDATE FIELDS ( InventoryID )
295 |         WITH VALUE #( FOR inventory IN inventories INDEX INTO i (
296 |                            %tky      = inventory-%tky
297 |                            inventoryID  = max_inventory + i ) )
298 |     REPORTED DATA(lt_reported).
299 | 
300 |     "fill reported
301 |     reported = CORRESPONDING #( DEEP lt_reported ).
302 | 
303 | ENDMETHOD.
304 |  
305 | 
306 | 307 | 7. Replace the placeholders #### with your group number and activate your changes **(Ctrl+F3)** 308 | 309 | ![Replace the placeholders](images/0540.png) 310 | 311 | 8. Test the implementation. 312 | 313 | - Start the Fiori Elements preview and press the **Create** button. 314 | - Enter an arbritray product name 315 | - Press **Save** 316 | 317 | ![Open behavior defintion class](images/0550.png) 318 | 319 | 9. Check the numbering for your semantic key 320 | 321 | 322 | ![Open behavior defintion class](images/0570.png) 323 | 324 | 325 | 326 | ## Summary 327 | 328 | You have completed the exercise! 329 | 330 | You are now able to: 331 | - Implement Behavior Definitions to enable create, update and delete operations and make fields read-only Implement Behavior Implementations so that ABAP code in determinations is run when an object is created. 332 | - Use the Fiori Elements preview to test your service 333 | 334 | 335 | Continue with - [Exercise 2](../ex2/README.md) 336 | 337 | -------------------------------------------------------------------------------- /exercises/ex2/README.md: -------------------------------------------------------------------------------- 1 | # TOC 2 | [Home](../../README.md#exercises) 3 | # Exercise 2 4 | 5 | - [Create the service consumption model](#create-the-service-consumption-model) 6 | - [Create a console application to test the OData service](#create-a-console-application-to-test-the-odata-service) 7 | - [Create a custom entity and implement the query implementation class](#create-a-custom-entity-and-implement-the-query-implementation-class) 8 | - [Create a custom entity](#create-a-custom-entity) 9 | - [Implement the query implemenation class](#implement-the-query-implemenation-class) 10 | - [Add the custom entity as a value help](#add-the-custom-entity-as-a-value-help) 11 | - [Test the service](#test-the-service) 12 | - [Summary](#summary) 13 | - [Solution](sources) 14 | 15 | 16 | When creating a new entry with your inventory application you see that there is no value help for the field **ProductId**. 17 | Since this information resides in a SAP S/4 HANA backend we will it retrieve via OData. 18 | 19 | ![No value help](images/1010.png) 20 | 21 | In this exercise you will thus learn how to consume an OData Service from an on premise system in order to fetch business partner data. You will then learn how to expose this data as a value help for the Inventory entity. 22 | 23 | In this exercise, we will ... 24 | 25 | - Create a Service Consumption Model for the on premise OData Service 26 | - Create a console application to test the OData Service call 27 | - Create a Custom Entity and implement its custom query 28 | - Expose your Custom Entity within your existing OData Service 29 | - Add the Custom Entity as a value help for the field ProductId in your inventory application 30 | 31 | 32 | > **Please note:** 33 | 34 | > Since it must be possible to run this demo on the trial systems where no destination service is available we cannot use RFC calls to retrieve data from a backend system. We have rather to use services that are publically available in the Internet. In our demo we will thus use an OData Service that is available in the SAP Gateway Demo System ES5 and that does not require any authentication. 35 | 36 | 37 | 38 | ## Create the Service Consumption Model 39 | 40 | In this step we will generate a so called **Service Consumption Model**. This type of object takes an external interface description as its input. Currently *OData*, *SOAP* and *RFC* are supported. 41 | Based on the information found in the *$metadata* file or the *wsdl* file appropriate repository objects are generated (OData Client proxy or SOAP proxy objects). For RFC function modules the metadata file is created in the backend using the transaction *ACO_PROXY*. 42 | Using these objects you will be able to write ABAP code that lets you consume remote OData services, SOAP services or RFC function modules. 43 | 44 | We start by creating a service consumption model for an OData service that provides demo product data. This service resides on the public SAP Gateway System ES5 and does not require any authentication 45 | 46 | 1. The *$metadata* file of the OData service that we want to consume must be uploaded in file format. You have hence to download it first. 47 | 48 | - Click on the following URL https://sapes5.sapdevcenter.com/sap/opu/odata/sap/ZPDCDS_SRV/$metadata 49 | 50 | When you are asked to select a certificate or to authenticate, simply press the **Cancel** button, since this URL does not require any authentication. 51 | 52 | ![No authentication required](images/1022.png) 53 | 54 | - Download the $metadata file to your computer, you will need it later in this exercise. 55 | 56 | ![Download $metadata 1](images/1024.png) 57 | ![Download $metadata 2](images/1026.png) 58 | 59 | 2. Switch to ADT and right click on your package **ZRAP_INVENTORY_####**. Select **New > Other ABAP Repository Object**. 60 | 61 | ![New ABAP Repository Object 1](images/1020.png) 62 | 63 | 2. In the New ABAP Repository Object dialogue do the following 64 | 65 | - Start to type **`Service`** 66 | - In the list of objects select **Service Consumption Model** 67 | - Click **Next** 68 | 69 | ![New ABAP Repository Object 2](images/1030.png) 70 | 71 | 4. The **New Service Consumption Model** dialogue opens. Here enter the following data: 72 | 73 | - Name: **`ZSC_RAP_PRODUCTS_#### `** 74 | - Description: **`Products from ES5`** 75 | - Remote Consumption Model: **`OData`** (to be selected from the drop down box) 76 | 77 | 78 | > **Caution** 79 | 80 | > Be sure that you have selected **`OData`** as the **Remote Consumption Mode** from the drop down box. We will create a service consumption model for a SOAP web service in the following exercise. 81 | 82 | ![New Service Consumption Model](images/1040.png) 83 | 84 | 5. The $metadata file of the OData service that we want to consume must be uploaded in file format. If you have not yet downloaded the $metadata file you have to do this now. 85 | 86 | - Click **Browse** to select the $metadata file that you have downloaded earlier in this exercise 87 | - Prefix: **`RAP_####_`** 88 | 89 | > **Please note** 90 | 91 | > The prefix that you have entered will be added to the names of the repository objects that are generated, namely the **abstract entity(ies)**. 92 | > If you don't select a prefix and if the wizard finds out that there would be name clashes the wizard will propse unique names by adding arbitrary characters to the repository object names. In any case you will be able to change the values that will be proposed by this wizard. 93 | 94 | ![OData consumption proxy](images/1050.png) 95 | 96 | 6. Check the **ABAP Artifact Name** and click **Next**. 97 | 98 | You will notice that the name of the ABAP artifact has been set to `ZRAP_####_SEPMRA_I_PRODUCT_E` since we have provided the prefix `RAP_####_`. 99 | 100 | Press **Next**. 101 | 102 | > Additional Information 103 | 104 | > If you have not provided a prefix the ABAP Artifact Name might contain several arbritray characters that have been added to the name **ZSEPMRA_I_PRODUCT**. This can happen if other users in the same system have already imported the same $metadata file. In order to avoid name clashes the wizard then adds arbitrary characters so that a unique name for the ABAP artifact is ensured. 105 | 106 | ![Define Entity Set](images/1060.png) 107 | 108 | 7. The wizard will now list the repository objects that will be generated, namely a service definition and an abstract entity in addition to the service consumption model. 109 | 110 | - Service Definition: **ZSC_RAP_PRODUCTS_####** 111 | - Abstract Entity: **ZRAP_####_SEPMRA_I_PRODUCT_E** 112 | 113 | Click **Next**. 114 | 115 | ![ABAP Artifact Genertion List](images/1070.png) 116 | 117 | 8. Selection of transport request 118 | - Select or create a transport request 119 | - Press **Finish** 120 | 121 | ![ABAP Artifact Genertion List](images/1080.png) 122 | 123 | 9. Let us briefly investigate the service consumption model. 124 | 125 | For each operation (**Read List**, **Read**, **Create**, **Update** and **Delete**) some sample code has been created that you can use when you want to call the OData Service with one of these operations. Since we want to retrieve a list of Product-IDs, we will select the operation **Read List** and click on the button **Copy to Clipboard**. We will use this code in the following step where we create a console application to test the call to the remote OData service. 126 | 127 | ![Code sample for entity access](images/1090.png) 128 | 129 | ## Remove dimension fields from abstract entity 130 | 131 | In order to avoid an error when the custom entity is used as a value help we have to remove the dimension fields from the abstract entity. Otherwise a convesion error occurs that will lead to a dump. The root cause is being analyzed but was not solved before our session took place. 132 | 133 | 1. Remove dimensions from the abstract entity 134 | 135 | Please open the entity **`ZRAP_####_SEPMRA_I_PRODUCT_E`** (Press **Ctrl+Shift+A**) and paste the name (of course with your number `####`) and comment out following part: 136 | 137 |
138 | // @OData.property.valueControl: 'Height_vc' 
139 | // @Semantics.quantity.unitOfMeasure: 'DimensionUnit' 
140 | // Height : abap.dec( 13, 3 ) ; 
141 | // Height_vc : rap_cp_odata_value_control ; 
142 | // @OData.property.valueControl: 'Width_vc' 
143 | // @Semantics.quantity.unitOfMeasure: 'DimensionUnit' 
144 | // Width : abap.dec( 13, 3 ) ; 
145 | // Width_vc : rap_cp_odata_value_control ; 
146 | // @OData.property.valueControl: 'Depth_vc' 
147 | // @Semantics.quantity.unitOfMeasure: 'DimensionUnit' 
148 | // Depth : abap.dec( 13, 3 ) ; 
149 | // Depth_vc : rap_cp_odata_value_control ; 
150 | 
151 | 152 | ![Comment out dimensions](images/1085.png) 153 | 154 | 2. Afterwards please activate ![Activate](images/activate.png) your changes. 155 | 156 | ## Create a console application to test the OData service 157 | 158 | We can now test the service consumption model by creating a small console application **ZCL_CE_RAP_PRODUCTS_####** that implements the interface **if_oo_adt_classrun**. 159 | This is a useful additional step since this way it is easier to check whether the OData consumption works and debugging a console application is much easier than trying out your coding in the full fledged RAP business object. 160 | 161 | > **Please note** 162 | 163 | > We will use this class at a later stage also as an implementation for our custom query and we hence choose a name **ZCL_CE_RAP_PRODUCTS_####** that already contains the name of the to be created custom entity. **CE** denotes that this class will act as a query implementation for a *Custom Entity*. 164 | 165 | 1. Right click on the folder **Source Code Library** and select **New > ABAP Class**. 166 | 167 | ![New ABAP class](images/1100.png) 168 | 169 | 2. The **New ABAP class** dialogue opens. Here you have to enter the following: 170 | 171 | - Name: **`ZCL_CE_RAP_PRODUCTS_####`** 172 | - Description: **`Query implementation custom entity`** 173 | - Click **Add** 174 | 175 | The **Add ABAP Interface** dialogue opens. 176 | 177 | - Start to type **`if_oo`** 178 | - Select **`IF_OO_ADT_CLASSRUN`** from the list of matching items 179 | - Press **OK** or double-click on **IF_OO_ADT_CLASSRUN** 180 | 181 | ![New ABAP class](images/1110.png) 182 | 183 | 184 | 3. Check the input and press **Next** 185 | 186 | ![New ABAP class](images/1120.png) 187 | 188 | 4. Selection of transport request 189 | 190 | - Select or create a transport request 191 | - Click **Finish** 192 | 193 | ![Selection of transport request](images/1130.png) 194 | ZRAP_CE 195 | 196 | 5. Check the source code template 197 | 198 | You will notice that the wizard has automatically added an implementation for the method **IF_OO_ADT_CLASSRUN~MAIN**. 199 | 200 | ![Selection of transport request](images/1135.png) 201 | 202 | ## CLASS zcl_ce_rap_products_#### - Implementation 203 | 204 | 1. Let's start with the implementation of our test class. 205 | 206 | In the public section we add two **TYPES** definitions. **t_product_range** is used to provide filter conditions for ProductIDs in form of SELECT-OPTIONS to the method **get_products( )**. 207 | The second type **t_business_data** is used to retrieve the business data returned by our remote OData service. 208 | The **get_products( )** method takes filter conditions in form of SELECT-OPTIONS via the importing parameter **it_filter_cond**. In addition it is possible to provide values for **top** and **skip** to leverage client side paging. 209 | 210 | So the **DEFINITION** section of your class should now look like follows: 211 | 212 |
213 | CLASS zcl_ce_rap_products_#### DEFINITION
214 |   PUBLIC
215 |   FINAL
216 |   CREATE PUBLIC .
217 | 
218 |   PUBLIC SECTION.
219 | 
220 |     INTERFACES if_oo_adt_classrun .
221 | 
222 |     TYPES t_product_range TYPE RANGE OF zrap_####_sepmra_i_product_e-product.
223 |     TYPES t_business_data TYPE TABLE OF zrap_####_sepmra_i_product_e.
224 | 
225 |     METHODS get_products
226 |       IMPORTING
227 |         it_filter_cond   TYPE if_rap_query_filter=>tt_name_range_pairs   OPTIONAL
228 |         top              TYPE i OPTIONAL
229 |         skip             TYPE i OPTIONAL
230 |       EXPORTING
231 |         et_business_data TYPE  t_business_data
232 |       RAISING
233 |         /iwbep/cx_cp_remote
234 |         /iwbep/cx_gateway
235 |         cx_web_http_client_error
236 |         cx_http_dest_provider_error
237 |       .
238 | 
239 |   PROTECTED SECTION.
240 |   PRIVATE SECTION.
241 | ENDCLASS.
242 | 
243 | 244 | You will get a warning that the method **get_products( )** has not been implemented yet. Press **Ctrl+1** to start the quick fix to add an implementation for **get_products( )**. 245 | 246 | ![Add implementation](images/1137.png) 247 | 248 | 6. Now we will add code in the **IMPLEMENTATION** section of the method **get_products( )**. 249 | 250 | The public method **get_products( )** is used to retrieve the data from the remote OData service. Since it is not possible to leverage the destination service in the trial systems, we will use the method **cl_http_destination_provider=>create_by_url** which allows us to create a http destination object based on the target URL. As the target URL we choose the root URL https://sapes5.sapdevcenter.com of the ES5 system since the relative URL that points to the OData service will be added when creating the OData client proxy. 251 | 252 | > **Caution:** 253 | > Do not forget to replace the placeholder **'####'** with your unique number. 254 | 255 | > Please note 256 | 257 | > In a normal SAP Cloud Platform, ABAP Environment system one would leverage the destination service of the underlying Cloud Foundry Environment and one would use the statement **cl_http_destination_provider=>create_by_cloud_destination** to generate a http destination in the ABAP Environment system based on these settings. 258 | 259 | ![Add implementation2](images/1139.png) 260 | 261 |
262 | METHOD get_products.
263 | 
264 |     DATA: filter_factory   TYPE REF TO /iwbep/if_cp_filter_factory,
265 |           filter_node      TYPE REF TO /iwbep/if_cp_filter_node,
266 |           root_filter_node TYPE REF TO /iwbep/if_cp_filter_node.
267 | 
268 |     DATA: http_client        TYPE REF TO if_web_http_client,
269 |           odata_client_proxy TYPE REF TO /iwbep/if_cp_client_proxy,
270 |           read_list_request  TYPE REF TO /iwbep/if_cp_request_read_list,
271 |           read_list_response TYPE REF TO /iwbep/if_cp_response_read_lst.
272 | 
273 |     DATA(http_destination) = cl_http_destination_provider=>create_by_url( i_url = 'https://sapes5.sapdevcenter.com' ).
274 |     http_client = cl_web_http_client_manager=>create_by_http_destination( i_destination = http_destination ).
275 | 
276 |     odata_client_proxy = cl_web_odata_client_factory=>create_v2_remote_proxy(
277 |       EXPORTING
278 |         iv_service_definition_name = 'ZSC_RAP_PRODUCTS_####'
279 |         io_http_client             = http_client
280 |         iv_relative_service_root   = '/sap/opu/odata/sap/ZPDCDS_SRV/' ).
281 | 
282 |     " Navigate to the resource and create a request for the read operation
283 |     read_list_request = odata_client_proxy->create_resource_for_entity_set( 'SEPMRA_I_PRODUCT_E' )->create_request_for_read( ).
284 | 
285 |     " Create the filter tree
286 |     filter_factory = read_list_request->create_filter_factory( ).
287 |     LOOP AT  it_filter_cond  INTO DATA(filter_condition).
288 |       filter_node  = filter_factory->create_by_range( iv_property_path     = filter_condition-name
289 |                                                               it_range     = filter_condition-range ).
290 |       IF root_filter_node IS INITIAL.
291 |         root_filter_node = filter_node.
292 |       ELSE.
293 |         root_filter_node = root_filter_node->and( filter_node ).
294 |       ENDIF.
295 |     ENDLOOP.
296 | 
297 |     IF root_filter_node IS NOT INITIAL.
298 |       read_list_request->set_filter( root_filter_node ).
299 |     ENDIF.
300 | 
301 |     IF top > 0 .
302 |       read_list_request->set_top( top ).
303 |     ENDIF.
304 | 
305 |     read_list_request->set_skip( skip ).
306 | 
307 |     " Execute the request and retrieve the business data
308 |     read_list_response = read_list_request->execute( ).
309 |     read_list_response->get_business_data( IMPORTING et_business_data = et_business_data ).
310 | 
311 |   ENDMETHOD.
312 | 
313 | 314 | 8. Finally we add the following code into the **IMPLEMENTATION** section of your **main** method 315 | 316 | The main method creates a simple filter for products with a name greater or equal **HT-1200**. At the same time we use client side paging to skip the first result and limit the response to 3 products. 317 | 318 |
319 |   METHOD if_oo_adt_classrun~main.
320 | 
321 |     DATA business_data TYPE TABLE OF zrap_####_sepmra_i_product_e.
322 |     DATA filter_conditions  TYPE if_rap_query_filter=>tt_name_range_pairs .
323 |     DATA ranges_table TYPE if_rap_query_filter=>tt_range_option .
324 |     ranges_table = VALUE #( (  sign = 'I' option = 'GE' low = 'HT-1200' ) ).
325 |     filter_conditions = VALUE #( ( name = 'PRODUCT'  range = ranges_table ) ).
326 | 
327 |     TRY.
328 |         get_products(
329 |           EXPORTING
330 |             it_filter_cond    = filter_conditions
331 |             top               =  3
332 |             skip              =  1
333 |           IMPORTING
334 |             et_business_data  = business_data
335 |           ) .
336 |         out->write( business_data ).
337 |       CATCH cx_root INTO DATA(exception).
338 |         out->write( cl_message_helper=>get_latest_t100_exception( exception )->if_message~get_longtext( ) ).
339 |     ENDTRY.
340 | 
341 |   ENDMETHOD.
342 | 
343 | 344 | 345 | 9. The code should now look as follows 346 | 347 | [Source code zcl_ce_rap_products_####](sources/ex2_CLAS_zcl_ce_rap_products_%23%23%23%23_step_1.txt) 348 | 349 | 10. You can now run the console application by pressing **F9**. 350 | 351 | 352 | ![Selection of transport request](images/1170.png) 353 | 354 | 355 | ## Create a custom entity and implement the query implementation class 356 | 357 | Since we want to use the results of the remote OData service in our managed inventory app we will create a custom entity. 358 | The syntax of a custom entity differs from the one used in normal CDS views but is very similar to the syntax of an abstract entity and we can thus reuse most of the DDL source code of the abstract entity that has been generated when the service consumption model was created. 359 | 360 | In order to leverage the remote OData service in our application we have to perform two steps. 361 | 362 | 1. We have to create a custom entity. 363 | 2. We have to create a class that implements the query for the custom entity. (Here we will reuse the class that we have created earlier and that we have used to test the remote OData service). 364 | 365 | ### Create a custom entity 366 | 367 | In constrast to "normal" CDS views that read data from the database from tables or other CDS views the so called custom entities act as a wrapper for a code based implementation that provides the data instead of a database table or a CDS view. 368 | 369 | The custom entity has to be created manually and it uses a similar syntax as the abstract entity that has been created when we have created our service consumption model. 370 | 371 | In order to be able to retrieve the data from the remote OData service we have to built a class that implements the interface **if_rap_query_provider**. We will reuse the class that we have created earlier and add this interface to it. 372 | 373 | The interface **if_rap_query_provider interface** only offers one method which is called **select**. Within this select method we will call the public **get_products( )** method. The select method also expects that the incoming requests provide certain OData specific query parameters. These we will set in our coding as well. 374 | 375 | 1. Right-click on the folder **Data Definition** and select **New Data Definition.** 376 | 377 | ![New data definition 1](images/1200.png) 378 | 379 | 380 | 1. Let’s start with creating a new data definition `ZCE_RAP_PRODUCTS_####` using the template for a custom entity. 381 | 382 | 2. The **New Data Defintion** dialogue opens 383 | - Name: **`ZCE_RAP_PRODUCTS_####`** 384 | - Description: **`Custom entity for products from ES5`** 385 | 386 | Press **Next** 387 | 388 | ![New data definition 2](images/1210.png) 389 | 390 | 3. Selection of a transport request 391 | - Select or create a transport request. 392 | - **!!! ONLY !!!** Press *Next*. Do **NOT** press *Finish*. 393 | 394 | > Caution 395 | 396 | > If you were to press **Finish** instead of **Next**, the wizard would use the template that was used the last time when this wizard was used by the developer. 397 | 398 | > In order to be sure that the correct template is selected, we **MUST** press **Next** and not **Finish** which would skip the step of template selection. 399 | 400 | ![New data definition 2](images/1220.png) 401 | 402 | 4. Select Template 403 | 404 | - Use the scroll bar to navigate down the list 405 | - Select the template **Define custom entity with parameters** 406 | - Press **Finish** 407 | 408 | > **Please note** 409 | 410 | > There is only a template for a custom entity with parameters. But this doesn’t matter. We use this template and remove the statement `with parameters parameter_name : parameter_type`. 411 | 412 | ![New data definition 2](images/1230.png) 413 | 414 | 5. Edit the source code of the custom entity 415 | 416 | - Remove the statement
with parameters parameter_name : parameter_type
417 | 418 | ![New data definition 2](images/1240.png) 419 | 420 | - Copy the field list from the abstract entity `ZRAP_####_SEPMRA_I_PRODUCT_E` 421 | 422 | ![Copy field list from the abstract entity](images/1250.png) 423 | 424 | 425 | - and paste it between the curly brackets as the new field list of our custom entity. 426 | 427 | ![Copy field list into the custom entity](images/1260.png) 428 | 429 | 6. Now add the annoation `@ObjectModel.query.implementedBy: 'ABAP:ZCL_CE_RAP_PRODUCTS_####'` 430 | 431 | ![Error message annotation required](images/1280.png) 432 | 433 | 7. Activate your changes ![Activate](images/activate.png) 434 | 435 | ![Error message class must implement IF_RAP_QUERY_PROVIDER](images/1290.png) 436 | 437 | 9. The DDL source code should now look like follows 438 | 439 | [Source code ZCE_RAP_PRODUCTS_####](sources/ex2_DDLS_ZCE_RAP_PRODUCTS_%23%23%23%23.txt) 440 | 441 | **Please note: You have to adapt the number of decimals for the property Price** 442 | 443 | 10. Change the number of decimals for the property `Price`. 444 | 445 | Change the number of decimals for the property `Price` from **3** to **2**, so that it now reads as follows: 446 |
 Price                   : abap.curr( 16, 2 ); 
447 | 448 | ![Change decimals for the property Price](images/1295.png) 449 | 450 | ### Implement the query implemenation class 451 | 452 | After having created the custom entity `ZRAP_CE_PRODUCTS_####` we now have to enhance the query implementation class `ZCL_CE_RAP_PRODUCTS_####`that we have created earlier in this exercise. 453 | 454 | 455 | 1. Add interface **`IF_RAP_QUERY_PROVIDER`** to the query implementation class **ZCL_CE_RAP_PRODUCTS_####** 456 | 457 | - You can use the quick fix `Ctrl+1` to add the implementation for the method `if_rap_query_provider~select` 458 | 459 |
460 |   INTERFACES if_rap_query_provider.
461 |   
462 | 463 | ![Add interface IF_RAP_QUERY_PROVIDER](images/1300.png) 464 | 465 | 466 | 467 | 2. Implement the method `if_rap_query_provider~select` 468 | 469 | Within the `select()` method we can retrieve the details of the incoming OData call using the object `io_request`. Using the method `get_paging()` we can find out whether client side paging was requested with the incoming OData call. Using the method `get_filter()` we can retrieve the filter that was used by the incoming OData request as ranges. This comes in handy so we can provide this data when calling the method `get_products()`. 470 | 471 | **Please note:** 472 | It is mandatory that the response not only contains the retrieved data via the method `set_data()` but also the number of entities being returned via the method `set_total_number_of_records()`. 473 | 474 |
475 | 
476 |   METHOD if_rap_query_provider~select.
477 |     DATA business_data TYPE TABLE OF zrap_####_sepmra_i_product_e.
478 |     DATA(top)     = io_request->get_paging( )->get_page_size( ).
479 |     DATA(skip)    = io_request->get_paging( )->get_offset( ).
480 |     DATA(requested_fields)  = io_request->get_requested_elements( ).
481 |     DATA(sort_order)    = io_request->get_sort_elements( ).
482 | 
483 |     TRY.
484 |         DATA(filter_condition) = io_request->get_filter( )->get_as_ranges( ).
485 | 
486 |         get_products(
487 |                  EXPORTING
488 |                    it_filter_cond    = filter_condition
489 |                    top               = CONV i( top )
490 |                    skip              = CONV i( skip )
491 |                  IMPORTING
492 |                    et_business_data  = business_data
493 |                  ) .
494 | 
495 |         io_response->set_total_number_of_records( lines( business_data ) ).
496 |         io_response->set_data( business_data ).
497 | 
498 |       CATCH cx_root INTO DATA(exception).
499 |         DATA(exception_message) = cl_message_helper=>get_latest_t100_exception( exception )->if_message~get_longtext( ).
500 |     ENDTRY.
501 |   ENDMETHOD.
502 | 
503 |  
504 |  
505 | 506 | 3. Activate your changes 507 | 508 | 4. Your ABAP source code should now look like follows 509 | 510 | [Source code ZCL_CE_RAP_PRODUCTS_####](sources/ex2_CLAS_zcl_ce_rap_products_%23%23%23%23_final.txt) 511 | 512 | ## Add the custom entity to your service definition 513 | 514 | 1. Open the Service Definition `ZRAP_INVENTORY_####` 515 | 516 | - add the statement 517 |
expose ZCE_RAP_PRODUCTS_#### as Products;
518 | so that the custom entity is added to the OData service. 519 | - Activate your changes ![Activate](images/activate.png) 520 | 521 | ![Add custom entity to service definition](images/1320.png) 522 | 523 | ## Add the custom entity as a value help 524 | 525 | 1. Open the projection view for your inventory data `ZC_RAP_INVENTORY_####` 526 | 527 | - Add the annotation `@Consumption.valueHelpDefinition` to the field `ProductID` 528 | 529 |
530 |   @Consumption.valueHelpDefinition: [{ entity : {name: 'ZCE_RAP_PRODUCTS_####', element: 'Product'  } }]
531 |   ProductID,
532 |   
533 | 534 | This will add the custom entity `ZCE_RAP_PRODUCTS_####` as a value help for the field `ProductId`. 535 | 536 | 537 | ## Test the service 538 | 539 | 1. Open the service binding `ZUI_RAP_INVENTORY_####_02` 540 | 541 | - You will notice that now two entities are visible. `Products` and `Inventory` 542 | 543 | ![Service binding with custom entity](images/1340.png) 544 | 545 | > Caution: 546 | > At this point you might receive an error message such as 547 | > **Amount field PRICE with currency decimals not equal to two is not supported.** 548 | > If this is the case go back to your custom entity **ZCE_RAP_PRODUCTS_####** 549 | > And change the number of decimals for the property price from 3 to 2, so that it now reads as follows: 550 | >
 Price                   : abap.curr( 16, 2 ); 
551 | 552 | ![Error message number of decimals](images/1355.png) 553 | 554 | 555 | 2. Start the Fiori Elements preview 556 | 557 | - Create a new inventory 558 | - Click on the value help icon 559 | 560 | ![Field ProductID with value help](images/1350.png) 561 | 562 | 563 | 3. The search results are on the buttom of the window. So you have to scroll down using the scroll bar on the right hand side. 564 | 565 | ![Navigate in the value help](images/1360.png) 566 | 567 | 4. Select a product e.g. HT-1000 568 | 569 | ![Select a product](images/1370.png) 570 | 571 | 572 | 5. Check the result on the object page 573 | 574 | ![Product selected in object page](images/1380.png) 575 | 576 | 577 | ## Summary 578 | 579 | You are now able to: 580 | · Explore an existing application with the Fiori Elements preview 581 | · Consume external OData Service using the Service Consumption Model 582 | · Create and expose Custom Entites 583 | · Implement Custom Queries for Custom Entities 584 | · Define value helps for OData entities 585 | 586 | 587 | Continue to - [Exercise 3 - Excercise 3 ](../ex3/README.md) 588 | --------------------------------------------------------------------------------