Application Development and Automation Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
Dadapeer
Explorer
881

Introduction 

This blog provides a step-by-step guide on creating a Product Management App  using RAP in an unmanaged scenario. It explains how to create a function group and a function module using ABAP in Eclipse and integrate them into the RAP framework to perform CRUD (Create, Read, Update, Delete) operations on product data. The app will allow users to manage product details, including fields such as Product ID, Product Name, Quantity, and Unit Price.

Procedure: 

Created one database table 'ZDP_DT_UTCL_PDT

@EndUserText.label : 'utcl products' 
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE 
@AbapCatalog.tableCategory : #TRANSPARENT 
@AbapCatalog.deliveryClass : #A 
@AbapCatalog.dataMaintenance : #RESTRICTED 
define table zdp_dt_utcl_pdt { 
key product_id : zdp_de_pdt_id not null; 
product_name : zdp_de_product_name; 
product_qty : zdp_de_pdt_quantity; 
product_unit_price : zdp_de_unit_price_pdt; 
} 

Now we need to create interface view on top of DB table.

@AbapCatalog.viewEnhancementCategory:[#NONE] 
@AccessControl.authorizationCheck:#NOT_REQUIRED 
@EndUserText.label:'utcl prdt interface view' 
@Metadata.ignorePropagatedAnnotations:true 
@ObjectModel.usageType:{ 
serviceQuality:#X, 
sizeCategory:#S, 
dataClass:#MIXED 
} 
definerootviewentityzdp_I_cds_utcl_prdt 
asselectfromZDP_DT_UTCL_PDT 
{ 
keyproduct_idasProductId, 
product_nameasProductName, 
product_qtyasProductQty, 
product_unit_priceasProductUnitPrice 
} 

Now we need to create a projection view on top of Interface view. 

@AccessControl.authorizationCheck: #NOT_REQUIRED 
@EndUserText.label: 'projection view on utcl prdt' 
@Metadata.ignorePropagatedAnnotations: true 
@Metadata.allowExtensions: true 
define root view entity zdp_P_cds_utcl_prdt  
provider contract transactional_query 
as projection on zdp_I_cds_utcl_prdt 
{ 
key ProductId, 
ProductName, 
ProductQty, 
ProductUnitPrice 
} 

Now we need to create the behavior definition on top of interface view.

I selected the unmanaged scenario in the behavior definition because, in my case, the CRUD operations are performed using a function module. If I had chosen the managed scenario, the RAP framework would have handled the CRUD operations automatically, but since my logic is custom and implemented through a function module, 

ABAP in Eclipse Create Function Group and Function Module.

Type func in the search box and select ABAP Function Group from the suggestions. Click Next. Give the package name, function group name and description.

 type function and select Abap function module. Click Next. Provide Name, description and function group name. We get an empty function module.

In this function module, we need to code the import, exporting, changing or exceptions parameters as required.

 Code of Behavior Definition of Interface: 

unmanaged implementation in class zbp_dp_i_cds_utcl_prdt unique; 
strict ( 2 ); 
define behavior for zdp_I_cds_utcl_prdt alias utcl_prdt 
//late numbering 
lock master 
authorization master ( instance ) 
//etag master <field_name> 
{ 
create; 
update; 
delete; 
field ( readonly ) ProductId; 
mapping for Zdp_dt_utcl_pdt control zdp_s_prdt_c 
{ 
ProductId = product_id; 
ProductName = product_name; 
ProductQty = product_qty; 
ProductUnitPrice = product_unit_price; 
} 
} 

Now create a behavior definition on top of consumption view:   

Code of Behavior Definition of Projection:   

projection; 
strict ( 2 );  
define behavior for zdp_P_cds_utcl_prdt alias utcl_prdt 
{ 
use create; 
use update; 
use delete; 
} 

 Behavior implementation.

CLASS lhc_zdp_I_cds_utcl_prdt DEFINITION INHERITING FROM cl_abap_behavior_handler. 

PRIVATE SECTION. 
METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION 

IMPORTING keys REQUEST requested_authorizations FOR zdp_I_cds_utcl_prdt RESULT result. 

METHODS create FOR MODIFY 
IMPORTING entities FOR CREATE utcl_prdt. 

METHODS update FOR MODIFY 
IMPORTING entities FOR UPDATE zdp_I_cds_utcl_prdt. 

 

METHODS delete FOR MODIFY 
IMPORTING keys FOR DELETE zdp_I_cds_utcl_prdt. 

METHODS read FOR READ 
IMPORTING keys FOR READ zdp_I_cds_utcl_prdt RESULT result. 

METHODS lock FOR LOCK 
IMPORTING keys FOR LOCK zdp_I_cds_utcl_prdt. 

TYPES: tt_failed TYPE TABLE FOR FAILED EARLY zdp_I_cds_utcl_prdt\\utcl_prdt, 

tt_reported TYPE TABLE FOR REPORTED EARLY zdp_I_cds_utcl_prdt\\utcl_prdt. 
TYPES tt_prdt_failed TYPE TABLE FOR FAILED zdp_I_cds_utcl_prdt. 
TYPES tt_prdt_reported TYPE TABLE FOR REPORTED zdp_I_cds_utcl_prdt. 
TYPES : tt_read TYPE TABLE FOR READ RESULT zdp_I_cds_utcl_prdt\\utcl_prdt. 
DATA : gs_prdt TYPE zdp_dt_utcl_pdt, 
gt_prdt TYPE TABLE OF zdp_dt_utcl_pdt. 
CLASS-DATA : gt_tab TYPE zdp_dt_utcl_pdt. 
METHODS map_messages 
IMPORTING 
cid TYPE abp_behv_cid OPTIONAL 
product_id TYPE zdp_de_pdt_id OPTIONAL 
messages TYPE char5 
EXPORTING 
failed_added TYPE abap_boolean 
CHANGING 
failed TYPE tt_failed 
reported TYPE tt_reported. 
ENDCLASS. 
CLASS lhc_zdp_I_cds_utcl_prdt IMPLEMENTATION. 
METHOD get_instance_authorizations. 
ENDMETHOD. 

METHOD create. 
DATA lv_msg TYPE char5. 
DATA : ls_tab1 TYPE zdp_dt_utcl_pdt. 
LOOP AT entities INTO DATA(ls_e). 
ls_tab1 = CORRESPONDING #( ls_e MAPPING FROM ENTITY USING CONTROL ). 
* LS_TAB1 = CORRESPONDING #( LT_PRODUCT[ 1 ] ). 
CALL FUNCTION 'ZDP_FM_PRDT_CREATE' 
EXPORTING 
ls_tab = ls_tab1 
IMPORTING 
msg = lv_msg. 
me->map_messages( 
EXPORTING 
cid = ls_e-%cid 
product_id = ls_tab1-product_id 
messages = lv_msg 
* IMPORTING 
* failed_added = 
CHANGING 
failed = failed-utcl_prdt 
reported = reported-utcl_prdt 
). 
ENDLOOP. 
ENDMETHOD. 

METHOD update. 
DATA : ls_update TYPE zdp_dt_utcl_pdt, 
ls_c TYPE zdp_s_prdt_c, 
lv_msg TYPE char20. 
LOOP AT entities ASSIGNING FIELD-SYMBOL(<fs_u>). 
ls_update = CORRESPONDING #( <fs_u> MAPPING FROM ENTITY ). 
ls_c = CORRESPONDING #( <fs_u> MAPPING FROM ENTITY ). 
CALL FUNCTION 'ZDP_FM_PRDT_UPDATE' 
EXPORTING 
ls_prd = ls_update 
ls_ctr = ls_c 
IMPORTING 
ls_prd_n = gs_prdt 
msg = lv_msg.  
* ENDLOOP. 
ENDMETHOD. 

METHOD delete. 
DATA(lv_id) = keys[ 1 ]-ProductId. 
CALL FUNCTION 'ZDP_FM_PRDT_DELETE' 
EXPORTING 
lv_prd_id = lv_id. 
ENDMETHOD. 
METHOD read. 
LOOP AT keys ASSIGNING FIELD-SYMBOL(<fs_e>) GROUP BY <fs_e>-%key. 
CALL FUNCTION 'ZDP_FM_PRDT_READ1' 
EXPORTING 
lv_pid = <fs_e>-ProductId 
IMPORTING 
lt_tab = gs_prdt. 
INSERT CORRESPONDING #( gs_prdt MAPPING TO ENTITY ) INTO TABLE result. 
ENDLOOP. 
ENDMETHOD. 
METHOD lock. 
ENDMETHOD. 
METHOD map_messages. 
IF messages IS NOT INITIAL. 
reported = VALUE #( ( %cid = cid 
ProductId = product_id 
%msg = new_message( 
id = 'Zdp_message_class' 
number = '001' 
severity = if_abap_behv_message=>severity-error 
v1 = product_id 
) ) ). 
ENDIF. 
ENDMETHOD. 
ENDCLASS. 
CLASS lsc_ZDP_I_CDS_UTCL_PRDT DEFINITION INHERITING FROM cl_abap_behavior_saver. 
PROTECTED SECTION. 
METHODS finalize REDEFINITION. 
METHODS check_before_save REDEFINITION. 
METHODS save REDEFINITION. 
METHODS cleanup REDEFINITION. 
METHODS cleanup_finalize REDEFINITION. 
ENDCLASS. 
CLASS lsc_ZDP_I_CDS_UTCL_PRDT IMPLEMENTATION. 
METHOD finalize. 
ENDMETHOD. 
METHOD check_before_save. 
ENDMETHOD. 
METHOD save. 
CALL FUNCTION 'ZDP_FM_SAVE_1'. 
ENDMETHOD. 
METHOD cleanup. 
ENDMETHOD. 
METHOD cleanup_finalize. 
ENDMETHOD. 
ENDCLASS. 

 create operation.

METHOD create. 

DATA lv_msg TYPE char5. 
DATA : ls_tab1 TYPE zdp_dt_utcl_pdt. 
LOOP AT entities INTO DATA(ls_e). 
ls_tab1 = CORRESPONDING #( ls_e MAPPING FROM ENTITY USING CONTROL ). 
* LS_TAB1 = CORRESPONDING #( LT_PRODUCT[ 1 ] ). 
CALL FUNCTION 'ZDP_FM_PRDT_CREATE' 
EXPORTING 
ls_tab = ls_tab1 
IMPORTING 
msg = lv_msg. 
me->map_messages( 
EXPORTING 
cid = ls_e-%cid 
product_id = ls_tab1-product_id 
messages = lv_msg 
CHANGING
failed = failed-utcl_prdt 
reported = reported-utcl_prdt ). 
ENDLOOP. 
ENDMETHOD. 

Function module product create. 

FUNCTION zdp_fm_prdt_create 
IMPORTING 
ls_tab TYPE zdp_dt_utcl_pdt 
EXPORTING 
msg TYPE char5. 

DATA(ls_tab1) = lS_tab. 
SELECT MAX( product_id ) FROM zdp_dt_utcl_pdt 
INTO (lv_pid). 

IF sy-subrc EQ 0. 
lv_pid += 1. 
zcl_dp_utcl_prdt_um_helper=>gt_tab = ls_tab1. 
ENDIF. 
ENDFUNCTION. 

Here gt_tab is a global internal table which I have created in global class. 

Update operation logic. 

METHOD update.  
DATA : ls_update TYPE zdp_dt_utcl_pdt, 
ls_c TYPE zdp_s_prdt_c, 
lv_msg TYPE char20. 
LOOP AT entities ASSIGNING FIELD-SYMBOL(<fs_u>). 
  ls_update = CORRESPONDING #( <fs_u> MAPPING FROM ENTITY ). 
  ls_c = CORRESPONDING #( <fs_u> MAPPING FROM ENTITY ). 
CALL FUNCTION 'ZDP_FM_PRDT_UPDATE' 
EXPORTING 
   ls_prd = ls_update 
   ls_ctr = ls_c 
IMPORTING 
   ls_prd_n = gs_prdt 
   msg = lv_msg. 
ENDLOOP. 
ENDMETHOD. 

Update function module logic. 

FUNCTION zdp_fm_prdt_update 
IMPORTING 
ls_prd TYPE zdp_dt_utcl_pdt 
ls_ctr TYPE zdp_s_prdt_c 
EXPORTING 
ls_prd_n TYPE zdp_dt_utcl_pdt 
msg TYPE char20. 
SELECT SINGLE FROM zdp_dt_utcl_pdt 
FIELDS * WHERE product_id = _prd-product_id INTO (ls_p_old). 

ls_prd_n-product_id = ls_prd-product_id.
ls_prd_n-product_name = COND #( WHEN ls_ctr-product_name IS NOT INITIAL 
      THEN ls_prd-product_name 
      ELSE ls_p_old-product_name 
). 
ls_prd_n-product_qty = COND #( WHEN ls_ctr-product_qty IS NOT INITIAL 
     THEN ls_prd-product_qty 
     ELSE ls_p_old-product_qty 
). 
ls_prd_n-product_unit_price = COND #( WHEN ls_ctr-product_unit_price IS NOT INITIAL 
   THEN ls_prd-product_unit_price 
   ELSE ls_p_old-product_unit_price 
). 
IF ls_prd_n IS NOT INITIAL. 
zcl_dp_utcl_prdt_um_helper=>gs_tab_u = ls_prd_n. 
msg = 'Sucessfully Updated'. 
ENDIF. 
ENDFUNCTION. 

 Delete operation logic. 

METHOD delete. 
DATA(lv_id) = keys[ 1 ]-ProductId.
CALL FUNCTION 'ZDP_FM_PRDT_DELETE' 
EXPORTING 
  lv_prd_id = lv_id. 
ENDMETHOD. 

 Delete function module logic. 

FUNCTION zdp_fm_prdt_delete 
IMPORTING 
lv_prd_id TYPE zdp_de_pdt_id. 
   zcl_dp_utcl_prdt_um_helper=>prt_id = lv_prd_id. 
ENDFUNCTION. 

Read operation logic. 

METHOD read. 
LOOP AT keys ASSIGNING FIELD-SYMBOL(<fs_e>) GROUP BY <fs_e>-%key. 
CALL FUNCTION 'ZDP_FM_PRDT_READ1' 
EXPORTING 
lv_pid = <fs_e>-ProductId 
IMPORTING 
lt_tab = gs_prdt. 
INSERT CORRESPONDING #( gs_prdt MAPPING TO ENTITY ) INTO TABLE result. 
ENDLOOP. 
ENDMETHOD. 

 Read function module logic. 

FUNCTION zdp_fm_prdt_read1 
IMPORTING 
  lv_pid TYPE zdp_de_product_id 
EXPORTING 
  lt_tab TYPE zdp_dt_utcl_pdt. 
SELECT SINGLE FROM zdp_dt_utcl_pdt FIELDS product_id, product_name,product_qty, product_unit_price 
WHERE product_id = _pid 
INTO _tab.
ENDFUNCTION. 

 save operation logic. 

METHOD save. 
  CALL FUNCTION 'ZDP_FM_SAVE_1'. 
ENDMETHOD. 

Save function module logic.  

FUNCTION zdp_fm_save_1.
IF zcl_dp_utcl_prdt_um_helper=>gt_tab IS NOT INITIAL. 
  INSERT zdp_dt_utcl_pdt FROM @zcl_dp_utcl_prdt_um_helper=>gt_tab. 
ENDIF. 
if zcl_dp_utcl_prdt_um_helper=>gs_tab_u is NOT INITIAL. 
 UPDATE zdp_dt_utcl_pdt FROM @zcl_dp_utcl_prdt_um_helper=>gs_tab_u. 
ENDIF. 
if zcl_dp_utcl_prdt_um_helper=>prt_id is not initial. 
 DELETE FROM zdp_dt_utcl_pdt 
 WHERE product_id = @zcl_dp_utcl_prdt_um_helper=>prt_id. 
ENDIF. 
ENDFUNCTION. 

Output: 

 Go to front-end

Dadapeer_0-1744356506451.png

Here I will create one new record: 

Dadapeer_0-1744356709313.png

Delete product 

Dadapeer_0-1744356869698.png

Here we are delete super cement

Dadapeer_0-1744356991909.png

Update gold cement product quantity.

Dadapeer_1-1744357034108.png

 

 

 

 

2 Comments
Labels in this area