This blog explains hoe Collaborative Draft works in RAP Managed Scenario with a Sales Order Application.
A Collaborative Draft allows multiple users to work on the draft instance of a business object before it is finally activated. This is very useful in scenarios like Sales Order Processing etc. where different user such as sales excutives, managers, or finance team may update different parts pf document.
A Draft is a temporary version of business data that allows users to edit records without immediately saving them to the active database table.
Draft ensures:
Data is saved temporarily
Other users cannot overwrite active data
Changes can be reviewed before activation
In RAP, draft functionality is enabled using:
with draft
Collaborative Draft allows multiple users to work on the same draft instance simultaneously.
Instead of locking the document for a single user, RAP enables controlled collaboration where users can:
with collaborative draft
Edit different sections of the same document
Save draft changes
Activate the final version
This improves productivity and avoids duplicate documents.
RAP Architecture for Sales Order
The RAP model contains:
Database Tables ->Â
1)zdb_so_hdr
@EndUserText.label : ‘Sales Order Header Table’
@AbapCatalog.enhancement.category : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_so_hdr {
key client : abap.clnt not null;
key soid : sysuuid_x16 not null;
sorder : abap.numc(10);
partner : abap.numc(10);
status : abap.char(1);
@Semantics.amount.currencyCode : ‘zdb_so_hdr.cuky’
price : abap.curr(10,2);
cuky : abap.cuky;
created_by : syuname;
created_at : timestampl;
last_changed_by : syuname;
last_changed_at : timestampl;
}
2)zdb_product
@EndUserText.label : ‘Products’
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_product {
key client : abap.clnt not null;
key prod : abap.char(20) not null;
descr : abap.char(40);
@Semantics.amount.currencyCode : ‘zdb_product.cuky’
price : abap.curr(10,2);
cuky : abap.cuky;
}
3)Draft Table->zdb_so_hdr01
@EndUserText.label : ‘Draft table for entity ZI_SO_HDR’
@AbapCatalog.enhancement.category : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_so_hdr01 {
key client : abap.clnt not null;
key soid : sysuuid_x16 not null;
sorder : abap.numc(10);
partner : abap.numc(10);
status : abap.char(1);
@Semantics.amount.currencyCode : ‘zdb_so_hdr01.cuky’
price : abap.curr(10,2);
cuky : abap.cuky;
createdby : syuname;
createdat : timestampl;
lastchangedby : syuname;
lastchangedat : timestampl;
“%admin” : include sych_bdl_draft_admin_inc;
}
4)zdb_status
@EndUserText.label : ‘Status’
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_status {
key client : abap.clnt not null;
key status : abap.char(1) not null;
text : abap.char(40);
}
5)zdb_partner
@EndUserText.label : ‘Partner’
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_partner {
key client : abap.clnt not null;
key partner : abap.numc(10) not null;
name : abap.char(40);
type : abap.char(1);
}
5)zdb_currency
@EndUserText.label : ‘CURRENCY’
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_currency {
key client : abap.clnt not null;
key cuky : abap.cuky not null;
}
2. CDS Views (Interface + Projection)
1)Sales Order Interface View->ZI_SO_HDR
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Sales Order Interface View’
@Metadata.ignorePropagatedAnnotations: true
define root view entity ZI_SO_HDR as select from zdb_so_hdr
association [0..1] to ZDD_PARTNER as _Partner on $projection.Partner = _Partner.Partner
association [0..1] to ZDD_Status as _Status on $projection.Status = _Status.Status
association [0..1] to ZDD_CURRENCY as _Currency on $projection.Cuky = _Currency.PriceUnit
{
key soid as Soid,
sorder as Sorder,
partner as Partner,
status as Status,
@Semantics.amount.currencyCode: ‘cuky’
price as Price,
cuky as Cuky,
@Semantics.user.createdBy: true
created_by as CreatedBy,
@Semantics.systemDateTime.createdAt: true
created_at as CreatedAt,
@Semantics.user.lastChangedBy: true
last_changed_by as LastChangedBy,
@Semantics.systemDateTime.lastChangedAt: true
last_changed_at as LastChangedAt,
_Partner,
_Status,
_Currency
}
2)Consumtion View -> ZC_SO_HDR
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Consumtion View’
@Metadata.ignorePropagatedAnnotations: true
@Search.searchable: true
@UI: {
headerInfo: { typeName: ‘Order’, typeNamePlural: ‘Orders’,
title: { type: #STANDARD, value: ‘SOrderNo’, label: ‘Order:’ } } }
define root view entity ZC_SO_HDR
as projection on ZI_SO_HDR
{
@ui.facet: [ { id: ‘Order’,
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: ‘Order’,
position: 10 } ]
@ui.hidden: true
key Soid,
@ui: {
lineItem: [ { position: 10, importance: #HIGH } ],
identification: [ { position: 10, label: ‘Order No.’ } ] }
@search.defaultSearchElement: true
Sorder as SOrderNo,
@ui: {
lineItem: [ { position: 20, importance: #HIGH } ],
identification: [ { position: 20, label: ‘Customer’ } ],
selectionField: [ { position: 20 } ] }
@Consumption.valueHelpDefinition: [{ entity : {name: ‘ZDD_PARTNER’, element: ‘Partner’ } }]
@ObjectModel.text.element: [‘Name’]
@search.defaultSearchElement: true
Partner as Customer,
_Partner.Name,
@ui: {
lineItem: [ { position: 30, importance: #HIGH } ],
identification: [ { position: 30, label: ‘Status’ } ] }
@Consumption.valueHelpDefinition: [{ entity : {name: ‘ZDD_STATUS’, element: ‘Status’ } }]
@ObjectModel.text.element: [‘Text’]
Status as Status,
_Status.Text as Text,
@ui: {
lineItem: [ { position: 40, importance: #HIGH } ],
identification: [ { position: 40, label: ‘Total Price’ } ] }
@Semantics.amount.currencyCode: ‘Currency’
Price,
@Consumption.valueHelpDefinition: [{entity: {name: ‘ZDD_CURRENCY’, element: ‘PriceUnit’ }}]
Cuky as Currency,
@ui: {
lineItem: [ { position: 50, importance: #MEDIUM } ],
identification: [ { position: 50, label: ‘Created By’ } ] }
CreatedBy,
@ui.hidden: true
CreatedAt,
@ui.hidden: true
LastChangedBy,
@ui.hidden: true
LastChangedAt,
/* Associations */
_Currency,
_Partner,
_Status
}
3) ZDD_Status
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Status’
@Metadata.ignorePropagatedAnnotations: true
@Search.searchable: true
define view entity ZDD_Status
as select from zdb_status
{
@search.defaultSearchElement: true
@ObjectModel.text.element: [ ‘Text’ ]
key status as Status,
@search.defaultSearchElement: true
@search.fuzzinessThreshold: 0.8
@Semantics.text: true
text as Text
}
4)ZDD_PARTNER
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘partner View’
@Metadata.ignorePropagatedAnnotations: true
@Search.searchable: true
define view entity ZDD_PARTNER as select from zdb_partner
{
@Search.defaultSearchElement: true
key partner as Partner,
@search.defaultSearchElement: true
@search.fuzzinessThreshold: 0.8
@Semantics.text: true
name as Name,
type as Type
}
5)ZDD_CURRENCY
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Currency View’
@Metadata.ignorePropagatedAnnotations: true
@Search.searchable: true
define view entity ZDD_CURRENCY
as select from zdb_currency
{
@search.defaultSearchElement: true
key cuky as PriceUnit
}
6)ZDD_QUERRY_01
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Query draft’
@Metadata.ignorePropagatedAnnotations: true
define view entity ZDD_QUERRY_01
as select from zdb_so_hdr01
{
key soid as Soid,
sorder as Sorder,
partner as Partner,
status as Status,
@Semantics.amount.currencyCode: ‘Cuky’
price as Price,
cuky as Cuky,
createdby,
createdat,
lastchangedby,
lastchangedat,
draftentitycreationdatetime as Draftentitycreationdatetime,
draftentitylastchangedatetime as Draftentitylastchangedatetime,
draftadministrativedatauuid as Draftadministrativedatauuid,
draftentityoperationcode as Draftentityoperationcode,
hasactiveentity as Hasactiveentity,
draftfieldchanges as Draftfieldchanges
}
3. Behavior Definition
managed implementation in class zbp_i_so_hdr unique;
strict ( 2 );
with collaborative draft;
extensible;
define behavior for ZI_SO_HDR alias SalesHeader
persistent table zdb_so_hdr
extensible
draft table zdb_so_hdr01 query ZDD_QUERRY_01
etag master LastChangedAt
lock master total etag LastChangedAt
authorization master ( instance )
{
field ( readonly, numbering : managed ) Soid;
field ( readonly ) Sorder, CreatedBy, CreatedAt, LastChangedBy, LastChangedAt;
field ( mandatory ) Partner, Status, Cuky;
create;
update;
delete;
draft action Activate optimized;
draft action Discard;
draft action Edit;
draft action Resume;
draft determine action Prepare;
draft action Share;
determination GenerateOrderNumber on save { create; }
}projection implementation in class zbp_i_so_hdr unique;
strict ( 2 );
extensible;
use collaborative draft;
use side effects;
define behavior for ZC_SO_HDR alias SalesHeader
extensible
{
use create;
use update;
use delete;
use action Edit;
use action Activate;
use action Discard;
use action Resume;
use action Prepare;
use action Share;
}
4. Behavior Implementation class
CLASS zcl_psh_helper DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: if_oo_adt_classrun.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_psh_helper IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA: lt_currency TYPE TABLE OF zdb_currency.
lt_currency = VALUE #(
( cuky = ‘EUR’ )
( cuky = ‘USD’ )
( cuky = ‘INR’ )
).
DATA: lt_partner TYPE TABLE OF zdb_partner.
lt_partner = VALUE #(
( partner = ‘1000011111’ name = ‘New World IT’ type = ‘C’ )
( partner = ‘1000011112’ name = ‘North IT’ type = ‘C’ )
( partner = ‘1000011113’ name = ‘Global IT’ type = ‘K’ )
( partner = ‘1000011114’ name = ‘Central IT’ type = ‘K’ )
).
DATA: lt_product TYPE TABLE OF zdb_product.
lt_product = VALUE #(
( prod = ‘Cloud_Package’ descr = ‘Cloud Package’ price = ‘100’ cuky = ‘INR’ )
( prod = ‘Cloud_Office’ descr = ‘Cloud Office’ price = ’99’ cuky = ‘EUR’ )
( prod = ‘Cloud_Trail’ descr = ‘Cloud Trial’ price = ‘100’ cuky = ‘USD’ )
).
DATA: lt_status TYPE TABLE OF zdb_status.
lt_status = VALUE #(
( status = ‘O’ text = ‘Open’ )
( status = ‘I’ text = ‘InProcess’ )
( status = ‘C’ text = ‘Completed’ )
( status = ‘R’ text = ‘Rejected’ )
( status = ‘B’ text = ‘Blocked’ )
).
“Clear existing data
DELETE FROM zdb_currency.
DELETE FROM zdb_partner.
DELETE FROM zdb_product.
DELETE FROM zdb_status.
“Insert fresh test data
INSERT zdb_currency FROM TABLE @LT_currency.
INSERT zdb_partner FROM TABLE @LT_partner.
INSERT zdb_product FROM TABLE @LT_product.
INSERT zdb_status FROM TABLE @LT_status.
ENDMETHOD.
ENDCLASS.CLASS lhc_SalesHeader DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
IMPORTING keys REQUEST requested_authorizations FOR SalesHeader RESULT result.
METHODS GenerateOrderNumber FOR DETERMINE ON SAVE
IMPORTING keys FOR SalesHeader~GenerateOrderNumber.
ENDCLASS.
CLASS lhc_SalesHeader IMPLEMENTATION.
METHOD get_instance_authorizations.
ENDMETHOD.
METHOD GenerateOrderNumber.
READ ENTITIES OF zi_so_hdr IN LOCAL MODE ENTITY SalesHeader
FIELDS ( Sorder ) WITH CORRESPONDING #( keys )
RESULT DATA(lt_sorder).
DELETE lt_sorder WHERE sorder IS NOT INITIAL.
IF lt_sorder IS NOT INITIAL.
SELECT SINGLE FROM zdb_so_hdr FIELDS MAX( sorder ) INTO @DATA(lv_sorder_max).
MODIFY ENTITIES OF zi_so_hdr IN LOCAL MODE ENTITY SalesHeader
UPDATE FIELDS ( Sorder )
WITH VALUE #( FOR Ls_sorder IN lt_sorder INDEX INTO i ( %key = ls_sorder-%key
Sorder = lv_sorder_max + i ) )
REPORTED DATA(lt_reported).
ENDIF.
ENDMETHOD.
ENDCLASS.
5. Service Definition
@EndUserText.label: ‘Sales Order’
define service ZSD_SalesORDER {
expose ZC_SO_HDR as SalesOrder;
}
6. Service Binding
Conclusion
Collaborative Draft in SAP RAP Managed Scenario enables multiple users to work efficiently on the same business document without data conflicts.
Using Sales Order as an example, we saw how RAP allows draft creation, collaboration, and activation using CDS views and behavior definitions.
Â
â This blog explains hoe Collaborative Draft works in RAP Managed Scenario with a Sales Order Application.A Collaborative Draft allows multiple users to work on the draft instance of a business object before it is finally activated. This is very useful in scenarios like Sales Order Processing etc. where different user such as sales excutives, managers, or finance team may update different parts pf document.A Draft is a temporary version of business data that allows users to edit records without immediately saving them to the active database table.Draft ensures:Data is saved temporarilyOther users cannot overwrite active dataChanges can be reviewed before activationIn RAP, draft functionality is enabled using:with draftCollaborative Draft allows multiple users to work on the same draft instance simultaneously.Instead of locking the document for a single user, RAP enables controlled collaboration where users can:with collaborative draftEdit different sections of the same documentSave draft changesActivate the final versionThis improves productivity and avoids duplicate documents.RAP Architecture for Sales OrderThe RAP model contains:Database Tables -> 1)zdb_so_hdr
@EndUserText.label : ‘Sales Order Header Table’
@AbapCatalog.enhancement.category : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_so_hdr {
key client : abap.clnt not null;
key soid : sysuuid_x16 not null;
sorder : abap.numc(10);
partner : abap.numc(10);
status : abap.char(1);
@Semantics.amount.currencyCode : ‘zdb_so_hdr.cuky’
price : abap.curr(10,2);
cuky : abap.cuky;
created_by : syuname;
created_at : timestampl;
last_changed_by : syuname;
last_changed_at : timestampl;
}
2)zdb_product
@EndUserText.label : ‘Products’
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_product {
key client : abap.clnt not null;
key prod : abap.char(20) not null;
descr : abap.char(40);
@Semantics.amount.currencyCode : ‘zdb_product.cuky’
price : abap.curr(10,2);
cuky : abap.cuky;
}
3)Draft Table->zdb_so_hdr01
@EndUserText.label : ‘Draft table for entity ZI_SO_HDR’
@AbapCatalog.enhancement.category : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_so_hdr01 {
key client : abap.clnt not null;
key soid : sysuuid_x16 not null;
sorder : abap.numc(10);
partner : abap.numc(10);
status : abap.char(1);
@Semantics.amount.currencyCode : ‘zdb_so_hdr01.cuky’
price : abap.curr(10,2);
cuky : abap.cuky;
createdby : syuname;
createdat : timestampl;
lastchangedby : syuname;
lastchangedat : timestampl;
“%admin” : include sych_bdl_draft_admin_inc;
}
4)zdb_status
@EndUserText.label : ‘Status’
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_status {
key client : abap.clnt not null;
key status : abap.char(1) not null;
text : abap.char(40);
}
5)zdb_partner
@EndUserText.label : ‘Partner’
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_partner {
key client : abap.clnt not null;
key partner : abap.numc(10) not null;
name : abap.char(40);
type : abap.char(1);
}
5)zdb_currency
@EndUserText.label : ‘CURRENCY’
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdb_currency {
key client : abap.clnt not null;
key cuky : abap.cuky not null;
}2. CDS Views (Interface + Projection)1)Sales Order Interface View->ZI_SO_HDR
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Sales Order Interface View’
@Metadata.ignorePropagatedAnnotations: true
define root view entity ZI_SO_HDR as select from zdb_so_hdr
association [0..1] to ZDD_PARTNER as _Partner on $projection.Partner = _Partner.Partner
association [0..1] to ZDD_Status as _Status on $projection.Status = _Status.Status
association [0..1] to ZDD_CURRENCY as _Currency on $projection.Cuky = _Currency.PriceUnit
{
key soid as Soid,
sorder as Sorder,
partner as Partner,
status as Status,
@Semantics.amount.currencyCode: ‘cuky’
price as Price,
cuky as Cuky,
@Semantics.user.createdBy: true
created_by as CreatedBy,
@Semantics.systemDateTime.createdAt: true
created_at as CreatedAt,
@Semantics.user.lastChangedBy: true
last_changed_by as LastChangedBy,
@Semantics.systemDateTime.lastChangedAt: true
last_changed_at as LastChangedAt,
_Partner,
_Status,
_Currency
}
2)Consumtion View -> ZC_SO_HDR
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Consumtion View’
@Metadata.ignorePropagatedAnnotations: true
@Search.searchable: true
@UI: {
headerInfo: { typeName: ‘Order’, typeNamePlural: ‘Orders’,
title: { type: #STANDARD, value: ‘SOrderNo’, label: ‘Order:’ } } }
define root view entity ZC_SO_HDR
as projection on ZI_SO_HDR
{
@ui.facet: [ { id: ‘Order’,
purpose: #STANDARD,
type: #IDENTIFICATION_REFERENCE,
label: ‘Order’,
position: 10 } ]
@ui.hidden: true
key Soid,
@ui: {
lineItem: [ { position: 10, importance: #HIGH } ],
identification: [ { position: 10, label: ‘Order No.’ } ] }
@search.defaultSearchElement: true
Sorder as SOrderNo,
@ui: {
lineItem: [ { position: 20, importance: #HIGH } ],
identification: [ { position: 20, label: ‘Customer’ } ],
selectionField: [ { position: 20 } ] }
@Consumption.valueHelpDefinition: [{ entity : {name: ‘ZDD_PARTNER’, element: ‘Partner’ } }]
@ObjectModel.text.element: [‘Name’]
@search.defaultSearchElement: true
Partner as Customer,
_Partner.Name,
@ui: {
lineItem: [ { position: 30, importance: #HIGH } ],
identification: [ { position: 30, label: ‘Status’ } ] }
@Consumption.valueHelpDefinition: [{ entity : {name: ‘ZDD_STATUS’, element: ‘Status’ } }]
@ObjectModel.text.element: [‘Text’]
Status as Status,
_Status.Text as Text,
@ui: {
lineItem: [ { position: 40, importance: #HIGH } ],
identification: [ { position: 40, label: ‘Total Price’ } ] }
@Semantics.amount.currencyCode: ‘Currency’
Price,
@Consumption.valueHelpDefinition: [{entity: {name: ‘ZDD_CURRENCY’, element: ‘PriceUnit’ }}]
Cuky as Currency,
@ui: {
lineItem: [ { position: 50, importance: #MEDIUM } ],
identification: [ { position: 50, label: ‘Created By’ } ] }
CreatedBy,
@ui.hidden: true
CreatedAt,
@ui.hidden: true
LastChangedBy,
@ui.hidden: true
LastChangedAt,
/* Associations */
_Currency,
_Partner,
_Status
}
3) ZDD_Status
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Status’
@Metadata.ignorePropagatedAnnotations: true
@Search.searchable: true
define view entity ZDD_Status
as select from zdb_status
{
@search.defaultSearchElement: true
@ObjectModel.text.element: [ ‘Text’ ]
key status as Status,
@search.defaultSearchElement: true
@search.fuzzinessThreshold: 0.8
@Semantics.text: true
text as Text
}
4)ZDD_PARTNER
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘partner View’
@Metadata.ignorePropagatedAnnotations: true
@Search.searchable: true
define view entity ZDD_PARTNER as select from zdb_partner
{
@Search.defaultSearchElement: true
key partner as Partner,
@search.defaultSearchElement: true
@search.fuzzinessThreshold: 0.8
@Semantics.text: true
name as Name,
type as Type
}
5)ZDD_CURRENCY
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Currency View’
@Metadata.ignorePropagatedAnnotations: true
@Search.searchable: true
define view entity ZDD_CURRENCY
as select from zdb_currency
{
@search.defaultSearchElement: true
key cuky as PriceUnit
}
6)ZDD_QUERRY_01
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: ‘Query draft’
@Metadata.ignorePropagatedAnnotations: true
define view entity ZDD_QUERRY_01
as select from zdb_so_hdr01
{
key soid as Soid,
sorder as Sorder,
partner as Partner,
status as Status,
@Semantics.amount.currencyCode: ‘Cuky’
price as Price,
cuky as Cuky,
createdby,
createdat,
lastchangedby,
lastchangedat,
draftentitycreationdatetime as Draftentitycreationdatetime,
draftentitylastchangedatetime as Draftentitylastchangedatetime,
draftadministrativedatauuid as Draftadministrativedatauuid,
draftentityoperationcode as Draftentityoperationcode,
hasactiveentity as Hasactiveentity,
draftfieldchanges as Draftfieldchanges
}3. Behavior Definitionmanaged implementation in class zbp_i_so_hdr unique;
strict ( 2 );
with collaborative draft;
extensible;
define behavior for ZI_SO_HDR alias SalesHeader
persistent table zdb_so_hdr
extensible
draft table zdb_so_hdr01 query ZDD_QUERRY_01
etag master LastChangedAt
lock master total etag LastChangedAt
authorization master ( instance )
{
field ( readonly, numbering : managed ) Soid;
field ( readonly ) Sorder, CreatedBy, CreatedAt, LastChangedBy, LastChangedAt;
field ( mandatory ) Partner, Status, Cuky;
create;
update;
delete;
draft action Activate optimized;
draft action Discard;
draft action Edit;
draft action Resume;
draft determine action Prepare;
draft action Share;
determination GenerateOrderNumber on save { create; }
}projection implementation in class zbp_i_so_hdr unique;
strict ( 2 );
extensible;
use collaborative draft;
use side effects;
define behavior for ZC_SO_HDR alias SalesHeader
extensible
{
use create;
use update;
use delete;
use action Edit;
use action Activate;
use action Discard;
use action Resume;
use action Prepare;
use action Share;
}4. Behavior Implementation classCLASS zcl_psh_helper DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: if_oo_adt_classrun.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_psh_helper IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA: lt_currency TYPE TABLE OF zdb_currency.
lt_currency = VALUE #(
( cuky = ‘EUR’ )
( cuky = ‘USD’ )
( cuky = ‘INR’ )
).
DATA: lt_partner TYPE TABLE OF zdb_partner.
lt_partner = VALUE #(
( partner = ‘1000011111’ name = ‘New World IT’ type = ‘C’ )
( partner = ‘1000011112’ name = ‘North IT’ type = ‘C’ )
( partner = ‘1000011113’ name = ‘Global IT’ type = ‘K’ )
( partner = ‘1000011114’ name = ‘Central IT’ type = ‘K’ )
).
DATA: lt_product TYPE TABLE OF zdb_product.
lt_product = VALUE #(
( prod = ‘Cloud_Package’ descr = ‘Cloud Package’ price = ‘100’ cuky = ‘INR’ )
( prod = ‘Cloud_Office’ descr = ‘Cloud Office’ price = ’99’ cuky = ‘EUR’ )
( prod = ‘Cloud_Trail’ descr = ‘Cloud Trial’ price = ‘100’ cuky = ‘USD’ )
).
DATA: lt_status TYPE TABLE OF zdb_status.
lt_status = VALUE #(
( status = ‘O’ text = ‘Open’ )
( status = ‘I’ text = ‘InProcess’ )
( status = ‘C’ text = ‘Completed’ )
( status = ‘R’ text = ‘Rejected’ )
( status = ‘B’ text = ‘Blocked’ )
).
“Clear existing data
DELETE FROM zdb_currency.
DELETE FROM zdb_partner.
DELETE FROM zdb_product.
DELETE FROM zdb_status.
“Insert fresh test data
INSERT zdb_currency FROM TABLE @LT_currency.
INSERT zdb_partner FROM TABLE @LT_partner.
INSERT zdb_product FROM TABLE @LT_product.
INSERT zdb_status FROM TABLE @LT_status.
ENDMETHOD.
ENDCLASS.CLASS lhc_SalesHeader DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
IMPORTING keys REQUEST requested_authorizations FOR SalesHeader RESULT result.
METHODS GenerateOrderNumber FOR DETERMINE ON SAVE
IMPORTING keys FOR SalesHeader~GenerateOrderNumber.
ENDCLASS.
CLASS lhc_SalesHeader IMPLEMENTATION.
METHOD get_instance_authorizations.
ENDMETHOD.
METHOD GenerateOrderNumber.
READ ENTITIES OF zi_so_hdr IN LOCAL MODE ENTITY SalesHeader
FIELDS ( Sorder ) WITH CORRESPONDING #( keys )
RESULT DATA(lt_sorder).
DELETE lt_sorder WHERE sorder IS NOT INITIAL.
IF lt_sorder IS NOT INITIAL.
SELECT SINGLE FROM zdb_so_hdr FIELDS MAX( sorder ) INTO @DATA(lv_sorder_max).
MODIFY ENTITIES OF zi_so_hdr IN LOCAL MODE ENTITY SalesHeader
UPDATE FIELDS ( Sorder )
WITH VALUE #( FOR Ls_sorder IN lt_sorder INDEX INTO i ( %key = ls_sorder-%key
Sorder = lv_sorder_max + i ) )
REPORTED DATA(lt_reported).
ENDIF.
ENDMETHOD.
ENDCLASS.5. Service Definition@EndUserText.label: ‘Sales Order’
define service ZSD_SalesORDER {
expose ZC_SO_HDR as SalesOrder;
}6. Service BindingConclusionCollaborative Draft in SAP RAP Managed Scenario enables multiple users to work efficiently on the same business document without data conflicts.Using Sales Order as an example, we saw how RAP allows draft creation, collaboration, and activation using CDS views and behavior definitions.   Read More Technology Blog Posts by Members articlesÂ
#SAP
#SAPTechnologyblog