Working on a transactional SAP RAP app? Adding draft capability can significantly improve user experience, allowing users to pause, resume, or discard changes before committing.
In this post, we’ll walk through the steps to enable draft in our Billing Document RAP-managed app.
What is Draft in SAP RAP?
Draft is a framework in RAP that lets users temporarily store changes without immediately saving them to the database. This is especially useful in multi-step forms or complex object creation scenarios.
What is Concurrency Control?
When multiple users access the same data, RAP uses ETag-based locking to ensure consistency. With drafts, this ensures only one user modifies a draft version at a time.
Prerequisite
We assume you’ve already built the base RAP app:
-
Billing Document Header only: Build here
-
Extended with child entity (Item): Extend here
Steps to Enable Draft
1. Create Draft Tables
For each entity (Header and Item), define a corresponding draft table:
-
ZSAC_D_BILL_HEAD
for Header -
ZSAC_D_BILL_ITEM
for Item
Use the quick fix option to auto-generate these tables after assigning them in the behavior definition.
2. Update the Behavior Definition
In your behavior definition (ZSAC_I_BILL_HEADER
), update the following:
managed implementation in class zbp_sac_i_bill_header unique;
strict ( 2 );
with draft;
define behavior for ZSAC_I_BILL_HEADER
persistent table zsac_bill_header
draft table zsac_d_bill_head
lock master total etag BillID
authorization master ( instance )
{
create;
update;
delete;
draft action Edit;
draft action Resume;
draft action Activate optimized;
draft action Discard;
draft determine action Prepare;
field ( readonly : update, mandatory : create ) BillId;
association _item { create; with draft; }
mapping for zsac_bill_header
{
BillId = bill_id;
BillType = bill_type;
BillDate = bill_date;
CustomerId = customer_id;
NetAmount = net_amount;
Currency = currency;
SalesOrg = sales_org;
}
}
define behavior for zsac_i_bill_item
persistent table zsac_bill_item
draft table zsac_d_bill_item
lock dependent by _header
authorization dependent by _header
{
update;
delete;
field ( readonly : update, mandatory : create ) BillId, ItemNo;
association _header { with draft; }
mapping for zsac_bill_item
{
BillId = bill_id;
ItemNo = item_no;
MaterialId = material_id;
Description = description;
ItemAmount = item_amount;
Currency = currency;
Quantity = quantity;
Uom = uom;
}
}
3. Update the Behavior Projection
In your behavior projection (ZSAC_C_BILL_HEADER
), update the following:
projection;
strict ( 2 );
use draft;
define behavior for zsac_c_bill_header
{
use create;
use update;
use delete;
use action Edit;
use action Resume;
use action Activate;
use action Discard;
use action Prepare;
use association _item { create; with draft; }
}
define behavior for zsac_c_bill_item
{
use update;
use delete;
use association _header { with draft; }
}
That’s It.
Since this is a managed RAP application, no changes are needed in the implementation class.
Once you've activated the objects, you’ll notice the draft flow working seamlessly, enabling users to create, modify, and discard drafts for both header and item entities.
Why Enable Draft in a RAP Application?
Enabling draft in a RAP-managed application isn’t just about saving intermediate changes, it’s a foundational feature that enhances both data integrity and user experience, especially in transactional Fiori apps.
Here are some specific advantages:
-
Safe Multi-step Entry: Users can save partial input during multi-step form entries without prematurely committing data.
-
Reliable Error Recovery: In case of session timeout, browser crash, or accidental closure, the in-progress draft is preserved and recoverable.
-
Concurrent Editing Management: The system ensures that multiple users don't unknowingly edit the same record at the same time by using draft locks and ETag validation.
-
Optimized Data Handling: Data remains in draft tables until explicitly activated, preventing invalid or incomplete entries from reaching main tables.
-
Cleaner UX for Transactional Apps: Fiori automatically provides visual indicators for draft records, guiding users through activation and discard flows.
Want to Go Deeper?
Explore the official SAP documentation on draft-enabled RAP apps to understand the full mechanism:
π SAP Help: Draft in RAP
If you're curious about how draft behaves (especially in OData V4 scenarios), here are some community threads worth reading:
-
Unable to edit draft RAP RESTful ABAP Programming (Embedded)
-
Create/Edit Actions are not available in OData V4 without Draft
These threads dive into real-world challenges, odd behaviors, and solutions shared by the SAP developer community.
If you enjoyed this walkthrough and want to explore more SAP RAP scenarios, from simple CRUD apps to real-world enhancements and API integrations, check out the full blog series:
π Explore the SAP RAP Series
Each post is crafted to be beginner-friendly yet practical enough for working professionals trying to get hands-on with ABAP RAP.
Thanks for reading βΊοΈ