Factory action (copy records) in RAP
A factory action in RAP:
- Creates a new instance (record) based on logic you define.
- Can take input parameters if needed.
- Returns the created entity (
result [1] $self
).
This is perfect for:
- Copying an existing record with some fields duplicated.
- Initializing a draft for editing.
Aspect | Instance-Bound Factory Action | Static Factory Action |
---|---|---|
Binding | Bound to an existing BO instance | Not bound to any instance |
Purpose | Copy existing instance(s) | Create new instance(s) with default values |
Triggering Context | Triggered from a selected instance | Triggered from BO list page or toolbar |
Annotation Syntax | factory action |
static factory action |
Example Declaration | factory action copy_instance result [*] MyBO; |
static factory action new_instance result [1] MyBO; |
Result Cardinality | Often returns multiple instances ([*] ) |
Usually returns single instance ([1] ) |
Use Case Example | Copying a Sales Order | Creating a blank Sales Order |
Availability in UI | Only visible when an instance is selected | Always available (toolbar button) |
Refer - Working with Large objects(LOB) in RAP
Refer - Download the file into local machine.
Refer - File type validations in RAP
Steps to implement factory actions.
Step 1: Create a Header table with following fields.
@EndUserText.label : 'Student Header table'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table ztl_ab_hdr_stu13 {
key client : abap.clnt not null;
key stu_id : sysuuid_x16 not null;
stu_name : abap.char(25);
stu_age : abap.numc(2);
stu_course : abap.char(30);
stu_cour_dur : abap.numc(2);
stu_status : abap_boolean;
stu_gender : abap.char(1);
stu_dob : abap.dats;
last_ch_time : timestampl;
last_ch_date : timestampl;
}
* Check and activate.
Step 2: Create an item table with following fields.
@EndUserText.label : 'Student Item table'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table ztl_ab_itm_stu13 {
key client : abap.clnt not null;
key attch_id : abap.char(32) not null;
stu_id : sysuuid_x16 not null;
comments : abap.char(30);
attchment : zattach;
mimetype : abap.char(128);
filename : abap.char(128);
}
* Check and activate.
Step 3: Create Interface view for header table.
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Interface entity view for student header'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define root view entity ZIV_AB_HDR_STU13
as select from ztl_ab_hdr_stu13
composition [1..*] of ZIV_AB_ITM_STU13 as _attach
{
key stu_id as StuId,
stu_name as StuName,
stu_age as StuAge,
stu_course as StuCourse,
stu_cour_dur as StuCourDur,
stu_status as StuStatus,
stu_gender as StuGender,
stu_dob as StuDob,
last_ch_time as LastChTime,
last_ch_date as LastChDate,
_attach
}
Step 4: Create Interface view for item table.
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Interface entity view for student item'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define view entity ZIV_AB_ITM_STU13 as select from ztl_ab_itm_stu13
association to parent ZIV_AB_HDR_STU13 as _Student
on $projection.StuId = _Student.StuId
{
key attch_id as AttchId,
stu_id as StuId,
comments as Comments,
attchment as Attchment,
mimetype as Mimetype,
filename as Filename,
_Student
}
Step 5: Create projection/consumption view for above header view.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Consumption view for Header'
@Metadata.ignorePropagatedAnnotations: true
define root view entity zcv_ab_hdr_stu13
provider contract transactional_query
as projection on ZIV_AB_HDR_STU13
{
@UI.facet:
[{
id : 'Student',
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: 'Student',
position: 10
},
{
id : 'attach',
purpose: #STANDARD,
type: #LINEITEM_REFERENCE,
label: 'Attachments',
position: 20,
targetElement: '_attach'
}
]
@UI:
{
lineItem: [{ position : 1 , label : 'Student ID' },
{ position: 10 ,
type : #FOR_ACTION,
dataAction: 'CopyStudent',
label: 'CopyStudent' }],
identification: [{ position: 10 , label : 'Student ID' }],
selectionField: [{ position: 10 }]
}
key StuId,
@UI:
{
lineItem: [{ position: 20 , label : 'Student Name'}],
identification: [{ position: 20 , label : 'Student Name' }],
selectionField: [{ position: 20 }]
}
StuName,
@UI:
{
lineItem: [{ position: 30 , label : 'Student Age'}],
identification: [{ position: 30 , label : 'Student Age' }]
}
StuAge,
@UI:
{
lineItem: [{ position: 40 , label : 'Student Course'}],
identification: [{ position: 40 , label : 'Student Course' }]
}
StuCourse,
@UI:
{
lineItem: [{ position: 50 , label : 'Student Course Duration'}],
identification: [{ position: 50 , label : 'Student Course Duration' }]
}
StuCourDur,
@UI:
{
lineItem: [{ position: 60 , label : 'Student Status'}],
identification: [{ position: 60 , label : 'Student Status' }]
}
StuStatus,
@UI:
{
lineItem: [{ position: 70 , label : 'Student Gender'}],
identification: [{ position: 70 , label : 'Student Gender' }]
}
StuGender,
@UI:
{
lineItem: [{ position: 80 , label : 'Student DOB'}],
identification: [{ position: 80 , label : 'Student DOB' }]
}
StuDob,
LastChTime,
LastChDate,
/* Associations */
_attach : redirected to composition child zcv_ab_itm_stu13
}
Step 6: Create projection/consumption view for above item view.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Consumption view for Item'
@Metadata.ignorePropagatedAnnotations: true
define view entity zcv_ab_itm_stu13 as projection on ZIV_AB_ITM_STU13
{
@UI.facet:
[{
id : 'attach',
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: 'Attchment Information',
position: 10
}]
@UI:
{
lineItem: [{ position: 10 , label : 'Attachment ID'}],
identification: [{ position: 10 , label : 'Attachment ID' }]
}
key AttchId,
@UI:
{
lineItem: [{ position: 20 , label : 'Student ID'}],
identification: [{ position: 20 , label : 'Student ID' }]
}
StuId,
@UI:
{
lineItem: [{ position: 30 , label : 'Comments'}],
identification: [{ position: 30 , label : 'Comments' }]
}
Comments,
@Semantics.largeObject:{
mimeType: 'Mimetype',
fileName: 'Filename',
contentDispositionPreference: #ATTACHMENT,
acceptableMimeTypes: [ 'application/pdf' ]
}
@UI:
{
lineItem: [{ position: 40 , label : 'Attachment'}],
identification: [{ position: 40 , label : 'Attachment' }]
}
Attchment,
Mimetype,
Filename,
/* Associations */
_Student : redirected to parent zcv_ab_hdr_stu13
}
Step 7: Create behavior definition for interface view header.
managed implementation in class zbp_iv_ab_hdr_stu13 unique;
strict ( 2 );
with draft;
define behavior for ZIV_AB_HDR_STU13 alias Student
persistent table ztl_ab_hdr_stu13
draft table ztl_ab_hdr_dra13
lock master
total etag LastChDate
authorization master ( instance )
etag master LastChDate
{
create ( authorization : global );
update;
delete;
field ( numbering : managed, readonly ) StuId;
association _attach { create; with draft; }
draft action Activate;
draft action Discard;
draft action Edit;
draft action Resume;
draft determine action Prepare;
factory action CopyStudent[1];
mapping for ztl_ab_hdr_stu13
{
StuId = stu_id;
StuName = stu_name;
StuAge = stu_age;
StuCourse = stu_course;
StuCourDur = stu_cour_dur;
StuStatus = stu_status;
StuGender = stu_gender;
StuDob = stu_dob;
LastChDate = last_ch_date;
LastChTime = last_ch_time;
}
}
define behavior for ZIV_AB_ITM_STU13 alias attach
persistent table ztl_ab_itm_stu13
draft table ztl_ab_itm_dra13
lock dependent by _Student
authorization dependent by _Student
//etag master <field_name>
{
update;
delete;
field ( readonly ) StuId;
association _Student { with draft; }
mapping for ztl_ab_itm_stu13
{
AttchId = attch_id;
StuId = stu_id;
Comments = comments;
Attchment = attchment;
Mimetype = mimetype;
Filename = filename;
}
}
CLASS lhc_ZIV_AB_HDR_STU13 DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
IMPORTING keys REQUEST requested_authorizations FOR ziv_ab_hdr_stu13 RESULT result.
METHODS get_global_authorizations FOR GLOBAL AUTHORIZATION
IMPORTING REQUEST requested_authorizations FOR ziv_ab_hdr_stu13 RESULT result.
METHODS copystudent FOR MODIFY
IMPORTING keys FOR ACTION student~copystudent.
ENDCLASS.
CLASS lhc_ZIV_AB_HDR_STU13 IMPLEMENTATION.
METHOD get_instance_authorizations.
ENDMETHOD.
METHOD get_global_authorizations.
ENDMETHOD.
METHOD CopyStudent.
" Copy records assigned to internal table.
DATA: lt_students TYPE TABLE FOR CREATE ziv_ab_hdr_stu13 .
READ ENTITIES OF ziv_ab_hdr_stu13 IN LOCAL MODE
ENTITY Student
ALL FIELDS WITH CORRESPONDING #( keys )
RESULT DATA(lt_students1)
FAILED failed.
LOOP AT lt_students1 ASSIGNING FIELD-SYMBOL(<ls_students1>).
APPEND VALUE #( %cid = keys[ KEY entity %key = <ls_students1>-%key ]-%cid
"%is_draft = keys[ KEY entity %key = <ls_students1>-%key ]-%param-%is_draft
%data = CORRESPONDING #( <ls_students1> EXCEPT StuId )
) TO lt_students ASSIGNING FIELD-SYMBOL(<ls_students>).
ENDLOOP.
"Create BO instance by copy.
MODIFY ENTITIES OF ziv_ab_hdr_stu13 IN LOCAL MODE
ENTITY Student
CREATE FIELDS ( StuName StuAge StuCourse StuCourDur StuStatus StuGender StuDob )
WITH lt_students
MAPPED DATA(mapped_create).
" Set values to front end.
mapped-student = mapped_create-student.
ENDMETHOD.
ENDCLASS.
* Check and activate.
Step 9: Create behavior definition for consumption view header.
projection;
strict ( 2 );
use draft;
define behavior for zcv_ab_hdr_stu13 alias Student
{
use create;
use update;
use delete;
use action Activate;
use action Discard;
use action Edit;
use action Resume;
use action Prepare;
use action CopyStudent;
use association _attach { create; with draft; }
}
define behavior for zcv_ab_itm_stu13 alias attach
{
use update;
use delete;
use association _Student{ with draft; }
}
* Check and activate.
Step 10: Create service definition for consumption view.
@EndUserText.label: 'Service definition for Student'
define service Zsd_ab_rap_stu13 {
expose zcv_ab_hdr_stu13;
expose zcv_ab_itm_stu13;
}
* Check and activate.
Step 11: Create service binding for consumption view.
Testing
* Preview the application.
* Create entry.
* Select one entry and click on copy student then new entry will be created automatically.
* If you uncomment the sentence, it will create and editable in object page when you select data and click on copy student.
"%is_draft = keys[ KEY entity %key = <ls_students1>-%key ]-%param-%is_draft
* If click on create. Entry will be created otherwise saved as draft.
********************************Thank you*****************************
Comments
Post a Comment