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
3. select table and click on select generate repository objects
4.
5.Delivery class must be C
6. Data maintenance should be allowed
7.Also we need to have a data element( domain )
8. Provide package
9. We have business service definition and binding
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
12. we can be able to see the classes
13. we have scenario option
14 Transport selection :
15. activate the service binding
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
22. OUTPUT
23.
24. Double click on singleton entity
25. here the edit button is disabled –because no access to the tbale
26.
27. Click on edit
We will get the option to create
28.
29.Entry will be created
30. As soon as you click on save we will get an error
As we have not specified any customizing transport
31.
32. now we data is getting stored but not displaying because of CDS authorization
Select not allowed
33. now we can be able to see the data
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
35. deprecate selected entry and invalidate entry
36. Deprcate action
<< now I shall select an entry and click on deprecate button
37.
38.
39. Again if you select the depricated entries . The action buttons will not be shown
<< Invalidate entry
40. Click on save and open the entry
Thnaks and Regards —
Pradeep Ishwar devadiga
In this blog I have explained creating of an RAP Singleton entity with multiline edit functionalities , and also coevered below topics 1.copy action2. Depricate actions3.invalidating entries4.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 3. select table and click on select generate repository objects4. 5.Delivery class must be C 6. Data maintenance should be allowed7.Also we need to have a data element( domain )8. Provide package9. We have business service definition and binding 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 12. we can be able to see the classes 13. we have scenario option 14 Transport selection : 15. activate the service binding16. 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 definitionmanaged 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 binding22. OUTPUT23. 24. Double click on singleton entity 25. here the edit button is disabled –because no access to the tbale26. 27. Click on edit We will get the option to create 28.29.Entry will be created30. As soon as you click on save we will get an error As we have not specified any customizing transport 31. 32. now we data is getting stored but not displaying because of CDS authorization Select not allowed 33. now we can be able to see the data34. << 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 35. deprecate selected entry and invalidate entry 36. Deprcate action << now I shall select an entry and click on deprecate button 37. 38. 39. Again if you select the depricated entries . The action buttons will not be shown << Invalidate entry 40. Click on save and open the entry Thnaks and Regards –Pradeep Ishwar devadiga Read More Technology Blog Posts by Members articles
#SAP
#SAPTechnologyblog