Adding virtual elements in RAP.
Virtual elements in RAP are calculated fields — they don't exist in the database table, but you want to show or use them in the UI or response (like Fiori app). These are computed at runtime, for example:
* A field that shows the status description based on a code.
* A field that displays a calculated total (price * quantity
).
* A field with custom logic that depends on other fields or external data.
Steps to implement virtual elements
Refer - Sample example for managed scenario in RAP
Step 1: Create a table with following fields.
@EndUserText.label : 'Employee Table'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table ztl_ab_empl {
key client : abap.clnt not null;
key empl_id : abap.int8 not null;
empl_name : abap.char(30);
empl_age : abap.int2;
empl_role : abap.char(2);
empl_roledec : abap.char(20);
empl_sal : abap.int8;
}
* Check and activate.
Step 2: Create Interface view for the above table.
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Interface entity view for EMPLOYEE'
@Metadata.ignorePropagatedAnnotations: true
@Metadata.allowExtensions: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define root view entity ZIV_AB_EMPL
as select from ztl_ab_empl
{
key empl_id as EmplId,
empl_name as EmplName,
empl_age as EmplAge,
empl_role as EmplRole,
empl_roledec as EmplRoledec,
empl_sal as EmplSal
}
Step 3: Create consumption view for the above interface view.
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Consumption view for Employee'
@Metadata.ignorePropagatedAnnotations: true
@Metadata.allowExtensions: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define root view entity ZCV_AB_EMPL
as projection on ZIV_AB_EMPL as employee
{
key EmplId,
EmplName,
EmplAge,
EmplRole,
EmplRoledec,
EmplSal,
@ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_CLASAL'
@EndUserText.label: 'Total pay'
virtual bonus :abap.int4
}
* Check and activate.
Step 4: Create a class and implement the logic.
CLASS zcl_clasal DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_sadl_exit_calc_element_read.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_clasal IMPLEMENTATION.
METHOD if_sadl_exit_calc_element_read~calculate.
DATA: lt_empl TYPE STANDARD TABLE OF zcv_ab_empl WITH DEFAULT KEY.
lt_empl = CORRESPONDING #( it_original_data ).
LOOP AT lt_empl ASSIGNING FIELD-SYMBOL(<ls_empl>).
CASE <ls_empl>-EmplRole.
WHEN 'L1'.
<ls_empl>-bonus = <ls_empl>-EmplSal + 10000.
WHEN 'L2'.
<ls_empl>-bonus = <ls_empl>-EmplSal + 5000.
WHEN 'L3'.
<ls_empl>-bonus = <ls_empl>-EmplSal + 3000.
WHEN OTHERS.
<ls_empl>-bonus = <ls_empl>-EmplSal + 1000.
ENDCASE.
ENDLOOP.
ct_calculated_data = CORRESPONDING #( lt_empl ).
ENDMETHOD.
METHOD if_sadl_exit_calc_element_read~get_calculation_info.
ENDMETHOD.
ENDCLASS.
* Check and activate.
Step 5: A Create meta data extension for consumption view.
@Metadata.layer: #CORE
@UI: {
headerInfo:
{
typeName: 'Employee',
typeNamePlural: 'Employee',
title: {
type: #STANDARD,
label: 'Employee',
value: 'EmplId'
}
}
}
annotate view ZCV_AB_EMPL with
{
@UI.facet:
[{
id : 'Employee',
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: 'Employee',
position: 10
}]
@UI:
{
lineItem: [{ position: 10 , label : 'Employee ID'}],
identification: [{ position: 10 , label : 'Employee ID' }],
selectionField: [{ position: 10 }]
}
EmplId;
@UI:
{
lineItem: [{ position: 20 , label : 'Employee Name'}],
identification: [{ position: 20 , label : 'Employee Name' }],
selectionField: [{ position: 20 }]
}
EmplName;
@UI:
{
lineItem: [{ position: 30 , label : 'Employee Age'}],
identification: [{ position: 30 , label : 'Employee Age' }]
}
EmplAge;
@UI:
{
lineItem: [{ position: 40 , label : 'Employee Role'}],
identification: [{ position: 40 , label : 'Employee Role' }]
}
EmplRole;
@UI:
{
lineItem: [{ position: 50 , label : 'Employee Role Desc'}],
identification: [{ position: 50 , label : 'Employee Role Desc' }]
}
EmplRoledec;
@UI:
{
lineItem: [{ position: 60 , label : 'Employee Sal'}],
identification: [{ position: 60 , label : 'Employee Sal' }]
}
EmplSal;
@UI:
{
lineItem: [{ position: 70 , label : 'Employee Bonus'}],
identification: [{ position: 70 , label : 'Employee Bonus' }]
}
bonus;
}
* Check and activate.
Step 6: Create behavior definition for interface view.
managed implementation in class zbp_iv_ab_empl unique;
strict ( 2 );
define behavior for ZIV_AB_EMPL //alias <alias_name>
persistent table ztl_ab_empl
lock master
authorization master ( instance )
//etag master <field_name>
{
create ( authorization : global );
update;
delete;
// field ( readonly ) EmplId;
mapping for ztl_ab_empl
{
EmplId = empl_id;
EmplName = empl_name;
EmplAge = empl_age;
EmplRole = empl_role;
EmplRoledec = empl_roledec;
EmplSal = empl_sal;
}
}
* Implement the class and activate the class -zbp_iv_ab_empl.
* Check and activate.
Step 7: Create behavior definition for Consumption view.
projection;
strict ( 2 );
define behavior for ZCV_AB_EMPL //alias <alias_name>
{
use create;
use update;
use delete;
}
* Check and activate.
Step 8: Create service definition for Consumption view.
@EndUserText.label: 'Service definition for Employee'
define service ZSD_AB_EMPL {
expose ZCV_AB_EMPL;
}
* Check and activate.
Step 9: Create service Binding for above service definition.
* Check and activate.
Step 10: Check all objects are activated or not.
Testing
Step 1: Click on preview.
Step 2: Create Record.
Step 3: Click on create and refresh.
********************************Thank you*****************************
Comments
Post a Comment