Singleton Entities in RAP Design, Multi Line Edit, and Best Practices
Share

[[{“value”:”

In  this blog I have explained creating of an RAP Singleton entity  with multiline edit  functionalities , and also coevered below topics 
1.copy action

2. Depricate actions

3.invalidating entries

4.transport organizer 

  • Add Copy Action : Helps to create new entries in object page 

In case we have  lot of fields and we  need to refer existing entries –> and based on that if we want to create new entries we can make use of this action 

  • Add Deprecate Action :  If we want to deprecate some entries ( make it invalid )  

We can make use of this action  

Select to include a deprecate and invalidate action in the generated app 

Pre requisite : the table must have  a field CONFIGDEPRECATIONCODE with data element CONFIG_DEPRECATION_CODE  

  • Data Consistency Check : select this option to include a validation for the prepare draft action in the generated app which checks the consistency  of the input fields with  

Domain with fixed values 

Foreign keys where @abapCatalog.foreign key.screenCheck : true 

 If we have foreign key relationship / data element / domain 

( suppose we have gender field in the employee table –> we need to maintain it in the 

Domain level ) 

We can make use of  this field. 

<< 

Enable Transport Selection selected  

  • The transport request selection action displayed in edit mode 
  • The transport request information is displayed in the header toolbar 
  • If the save action is executed without  selected transport request and the transport is mandatory , the action to select a transport request is triggered automatically . 
  • After  selecting  a transport request , the save action continues  

 

If the action is not selected , a transport selection is made possible using an action button . This option is selected by default    

 

< Manual :   

 Select manual to include the action select transport  in the generated app 

With this action , you can select an existing customizing transport request before saving the configuration changes  

< Manual with pre selection  

To include the action select transport in the generated app .  

With this action , you can select an existing customizing transport request before saving the configuration changes. When the edit action is performed , a customizing transport request is determined automatically 

< No transport : Select No transport for an app without a transport suitable  fro configurations that are to be adjusted in the productive system 

 

 T1. take a custom table say employee 

@EndUserText.label : 'employee table' 
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE 
@AbapCatalog.tableCategory : #TRANSPARENT 
@AbapCatalog.deliveryClass : #C 
@AbapCatalog.dataMaintenance : #ALLOWED 
define table zpd_dt_em { 

key client : abap.clnt not null; 
key employee_id : zpd_de_emp not null; 
@EndUserText.label : 'First Name' 
first_name : abap.char(50); 
@EndUserText.label : 'Last Name' 
last_name : abap.char(50); 
@EndUserText.label : 'Department' 
department : abap.char(20); 
@EndUserText.label : 'Joining Date' 
joining_date : abap.dats; 
@EndUserText.label : 'Active Employee' 
is_active : abap.char(1); 
@EndUserText.label : 'Changed By' 
changed_by : abap.char(12); 
configdeprecationcode : config_deprecation_code; 
local_last_changed_at : abp_locinst_lastchange_tstmpl; 
changed_at : abp_lastchange_tstmpl; 

} 

2. Create a LANGUAGE TABLE : 

Here we need one  entry – so we have selected I_Language and put into the  

Where condition so that we get one entry to achieve singleton  

Pradeep555_0-1754910289470.png

3.  select table and click on select generate repository objects

Pradeep555_1-1754910322004.png

4. 

Pradeep555_2-1754910344865.png

5.Delivery class must be C 

Pradeep555_3-1754910436742.png

6. Data maintenance should be allowed

Pradeep555_4-1754910467221.png

7.Also we need to have a data element( domain )

Pradeep555_5-1754910582094.png

8. Provide package

Pradeep555_6-1754910671588.png

9. We have business service definition and binding 

Pradeep555_7-1754910705685.png

Pradeep555_8-1754910858334.png

10. 

.Also, we have singleton entity details 

  • Singleton entity name ( EmployeeTableAll) 
  • Interface view ( Zi_EmployeeTable_S) 
  • Projection view  ( Zi_EmployeeTable_S) 
  • Key field (SinlgetonID) 
  • Draft table (zpd_dt_empl_d_s) 

11. Table details 

Pradeep555_9-1754910919195.png

12. we can be able to see the classes 

Pradeep555_10-1754910953226.png

 

Pradeep555_11-1754910978734.png

13. we have scenario option 

Pradeep555_12-1754911008131.png

 

 

 

14 Transport selection : 

Pradeep555_0-1754911133421.png

 

 

Pradeep555_1-1754911186709.png

15. activate the service binding

Pradeep555_2-1754911230766.png

16. All the atrifacts will be generated 

intreface view:

@EndUserText.label: ’employee table’
@AccessControl.authorizationCheck: #MANDATORY
@Metadata.allowExtensions: true

define view entity ZI_EmployeeTable1
as select from ZPD_DT_EM
association to parent ZI_EmployeeTable_S1 as _EmployeeTableAll on $projection.SingletonID = _EmployeeTableAll.SingletonID
association [0..*] to I_ConfignDeprecationCodeText as _ConfignDeprecationCodeText on $projection.ConfigDeprecationCode = _ConfignDeprecationCodeText.ConfigurationDeprecationCode

{

key EMPLOYEE_ID as EmployeeId,
FIRST_NAME as FirstName,
LAST_NAME as LastName,
DEPARTMENT as Department,
JOINING_DATE as JoiningDate,
IS_ACTIVE as IsActive,
CHANGED_BY as ChangedBy,
@ObjectModel.text.association: ‘_ConfignDeprecationCodeText’
@Consumption.valueHelpDefinition: [ {

entity: {

name: ‘I_ConfignDeprecationCode’,
element: ‘ConfigurationDeprecationCode’

}

} ]

CONFIGDEPRECATIONCODE as ConfigDeprecationCode,
@Semantics.systemDateTime.localInstanceLastChangedAt: true
@Consumption.hidden: true
LOCAL_LAST_CHANGED_AT as LocalLastChangedAt,
@Semantics.systemDateTime.lastChangedAt: true
CHANGED_AT as ChangedAt,
@Consumption.hidden: true
1 as SingletonID,
_EmployeeTableAll,
case when CONFIGDEPRECATIONCODE = ‘W’ then 2 when CONFIGDEPRECATIONCODE = ‘E’ then 1 else 3 end as ConfigDeprecationCode_Critlty,
_ConfignDeprecationCodeText

}

17.

parent entity for interface  

Here we have made joined I_language  with employee table because  

We want Etag field from the table so that we can get lastchangedat field 

<< one more association is created related to transport – because we need to capture the entries in transport ( I_abap_transportrequesttext) 

@EndUserText.label: ’employee table Singleton’
@AccessControl.authorizationCheck: #NOT_REQUIRED
@ObjectModel.semanticKey: [ ‘SingletonID’ ]
@UI: {

headerInfo: {
typeName: ‘EmployeeTableAll’

}

}

define root view entity ZI_EmployeeTable_S1

as select from I_Language
left outer join ZPD_DT_EM on 0 = 0
association [0..*] to I_ABAPTransportRequestText as _ABAPTransportRequestText on $projection.TransportRequestID = _ABAPTransportRequestText.TransportRequestID
composition [0..*] of ZI_EmployeeTable1 as _EmployeeTable

{

@UI.facet: [ {

id: ‘ZI_EmployeeTable1’,
purpose: #STANDARD,
type: #LINEITEM_REFERENCE,
label: ’employee table’,
position: 1 ,
targetElement: ‘_EmployeeTable’

} ]

@UI.lineItem: [ {
position: 1

} ]

key 1 as SingletonID,
_EmployeeTable,
@UI.hidden: true
max( ZPD_DT_EM.CHANGED_AT ) as LastChangedAtMax,
@ObjectModel.text.association: ‘_ABAPTransportRequestText’
@UI.identification: [ {

position: 2 ,
type: #WITH_INTENT_BASED_NAVIGATION,
semanticObjectAction: ‘manage’

} ]

@Consumption.semanticObject: ‘CustomizingTransport’
cast( ” as SXCO_TRANSPORT) as TransportRequestID,
_ABAPTransportRequestText

}

where I_Language.Language = $session.system_language

18. child entity holds the singleton filed including  all other fields

@EndUserText.label: ’employee table’
@AccessControl.authorizationCheck: #MANDATORY
@Metadata.allowExtensions: true
define view entity ZI_EmployeeTable1

as select from ZPD_DT_EM
association to parent ZI_EmployeeTable_S1 as _EmployeeTableAll on $projection.SingletonID = _EmployeeTableAll.SingletonID
association [0..*] to I_ConfignDeprecationCodeText as _ConfignDeprecationCodeText on $projection.ConfigDeprecationCode = _ConfignDeprecationCodeText.ConfigurationDeprecationCode

{

key EMPLOYEE_ID as EmployeeId,
FIRST_NAME as FirstName,
LAST_NAME as LastName,
DEPARTMENT as Department,
JOINING_DATE as JoiningDate,
IS_ACTIVE as IsActive,
CHANGED_BY as ChangedBy,
@ObjectModel.text.association: ‘_ConfignDeprecationCodeText’
@Consumption.valueHelpDefinition: [ {

entity: {
name: ‘I_ConfignDeprecationCode’,
element: ‘ConfigurationDeprecationCode’

}

} ]

CONFIGDEPRECATIONCODE as ConfigDeprecationCode,
@Semantics.systemDateTime.localInstanceLastChangedAt: true
@Consumption.hidden: true
LOCAL_LAST_CHANGED_AT as LocalLastChangedAt,
@Semantics.systemDateTime.lastChangedAt: true
CHANGED_AT as ChangedAt,
@Consumption.hidden: true
1 as SingletonID,
_EmployeeTableAll,

case when CONFIGDEPRECATIONCODE = ‘W’ then 2 when CONFIGDEPRECATIONCODE = ‘E’ then 1 else 3 end as ConfigDeprecationCode_Critlty,

_ConfignDeprecationCodeText

}

19.behaviour definition

managed with additional save implementation in class ZBP_I_EMPLOYEETABLE_S1 unique;
strict;
with draft;
define behavior for ZI_EmployeeTable_S1 alias EmployeeTableAll

draft table ZPD_DT_EM_D_S1
with unmanaged save
lock master total etag LastChangedAtMax
authorization master( global )

{

field ( readonly )
SingletonID;
field ( features : instance )
TransportRequestID;
field ( notrigger )
SingletonID,
LastChangedAtMax;

update;
internal create;
internal delete;

draft action ( features : instance ) Edit with additional implementation;
draft action Activate optimized;
draft action Discard;
draft action Resume;
draft determine action Prepare;

action ( features : instance ) SelectCustomizingTransptReq parameter D_SelectCustomizingTransptReqP result [1] $self;

association _EmployeeTable { create ( features : instance ); with draft; }
validation ValidateTransportRequest on save ##NOT_ASSIGNED_TO_DETACT { create; update; }

side effects {
action SelectCustomizingTransptReq affects $self;

}

}

define behavior for ZI_EmployeeTable1 alias EmployeeTable ##UNMAPPED_FIELD

persistent table ZPD_DT_EM
draft table ZPD_DT_EM_D
etag master LocalLastChangedAt
lock dependent by _EmployeeTableAll
authorization dependent by _EmployeeTableAll

{

field ( mandatory : create )

EmployeeId;
field ( readonly )
SingletonID,
LocalLastChangedAt,
ChangedAt,
ConfigDeprecationCode,
ConfigDeprecationCode_Critlty;
field ( readonly : update )
EmployeeId;

field ( notrigger )
SingletonID,
LocalLastChangedAt,
ChangedAt;

update( features : global );
delete( features : instance );

action ( features : instance ) Deprecate result [1] $self;
action ( features : instance ) Invalidate result [1] $self;

mapping for ZPD_DT_EM

{

EmployeeId = EMPLOYEE_ID;
FirstName = FIRST_NAME;
LastName = LAST_NAME;
Department = DEPARTMENT;
JoiningDate = JOINING_DATE;
IsActive = IS_ACTIVE;
ChangedBy = CHANGED_BY;
ConfigDeprecationCode = CONFIGDEPRECATIONCODE;
LocalLastChangedAt = LOCAL_LAST_CHANGED_AT;
ChangedAt = CHANGED_AT;

}
association _EmployeeTableAll { with draft; }

validation ValidateTransportRequest on save ##NOT_ASSIGNED_TO_DETACT { create; update; delete; }

}

20. service definition

@ObjectModel.leadingEntity.name: 'ZI_EmployeeTable_S' 
define service ZUI_EMPLOYEETABLE { 
expose ZI_EMPLOYEETABLE_S as EmployeeTableAll; 
expose ZI_EMPLOYEETABLE as EmployeeTable; 

} 

21. service binding

Pradeep555_3-1754912117572.png

22. OUTPUT

Pradeep555_4-1754912157323.png

23. 

Pradeep555_6-1754912208665.png

24. Double click on singleton entity 

Pradeep555_7-1754912236441.png

25. here the edit button  is disabled –because no access to the tbale

Pradeep555_8-1754912271300.png

26.  

Pradeep555_9-1754912306511.png

27. Click on edit 

We will get the option to create 

Pradeep555_10-1754912355432.png

28.

Pradeep555_11-1754912380944.png

29.Entry will be created

Pradeep555_12-1754912438361.png

30. As soon as you click on save we will get an error 

As we have not specified any  customizing transport 

Pradeep555_13-1754912472735.png

31. 

Pradeep555_14-1754912504103.png

32. now we data is getting stored but not displaying because of CDS authorization  

Select not allowed 

Pradeep555_15-1754912540990.png

33.  now we can be able to see the data

Pradeep555_16-1754912565514.png

34. 

<< Copy Action 

I  will select the entry ( id 3) 

And click on copy action ..entry will be copied and we  need to assign new Id 

And also we can make changes in the perticular entry 

Pradeep555_17-1754912617841.png

35. deprecate selected entry and invalidate entry  

Pradeep555_18-1754912646740.png

36. Deprcate action 

<< now  I shall select an entry and click on deprecate button 

Pradeep555_19-1754912680433.png

37. 

Pradeep555_20-1754912707661.png

38. 

Pradeep555_21-1754912731691.png

39. Again if you select the depricated entries . The action buttons will not be shown 

 << Invalidate entry

Pradeep555_22-1754912782613.png

 

 40. Click on save and open the entry 

Pradeep555_23-1754912809471.png

 

Thnaks and Regards —

Pradeep Ishwar devadiga

 

 

“}]] 

  Read More Technology Blog Posts by Members articles 

#abap

By ali