Skip to content

Commit fccc744

Browse files
authored
Document Scenario 7 for SAP BO draft handling
Added detailed explanation for Scenario 7 regarding standard SAP BO draft handling via EML, including user flow and considerations for using draft-enabled business objects.
1 parent cffff28 commit fccc744

1 file changed

Lines changed: 267 additions & 0 deletions

File tree

docs/development/specific/draft.md

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,270 @@ For more on EML in abap2UI5 apps, see [CDS, EML](./cds.md).
4646
::: tip
4747
Draft tables hold exclusive locks for the draft owner. Combine draft handling with [Locks](./locks.md) only when you also need backend lock objects outside of RAP.
4848
:::
49+
50+
## 8. Scenario 7 — Standard SAP BO draft via EML
51+
52+
**Source:** [`scenarios/z2ui5_test_lock_07.clas.abap`](scenarios/z2ui5_test_lock_07.clas.abap)
53+
54+
If you are on **S/4HANA** or **BTP ABAP Environment (Steampunk)** and the business object you want to edit is already shipped by SAP as a draft-enabled BO (e.g. `I_SalesOrderTP`), you do not build your own BO and you do not create a draft table. SAP ships both. Your abap2UI5 app simply calls the standard BO via EML.
55+
56+
This sidesteps the whole lock-during-think-time problem.
57+
58+
The flow the user sees in the demo class:
59+
60+
```
61+
on_init -> Edit (create or resume the draft)
62+
"Save Draft" pressed -> UPDATE (writes the draft only, VBAK stays as-is)
63+
"Save Draft" again -> UPDATE (still draft)
64+
...
65+
"Activate" pressed -> Activate (now VBAK is written through)
66+
"Discard" pressed -> Discard (drops the draft, releases lock)
67+
```
68+
69+
**When to use this:**
70+
- The business object you need is already a released, draft-enabled SAP BO
71+
- You want classic Fiori-style "edit a draft, activate later" UX in an abap2UI5 app
72+
73+
**Key idea:** the session can stay **stateless**. The draft survives between roundtrips in SAP's own draft-shadow table. The lock is held by the BO framework as long as the draft exists — closing the browser without activating or discarding leaves the draft so the same user can resume it on the next visit. No `set_session_stateful( )`, no `ENQUEUE_*`, no custom Z table — SAP does all of that.
74+
75+
**Caveat:** field names (`SalesOrder`, `SalesOrderType`) match the released `I_SalesOrderTP` on current S/4HANA. On older releases the BO name or fields may differ — check the released-objects list in your system.
76+
77+
**If no standard BO exists** for your object — for instance because you are editing a custom Z business object — you would have to define your own draft-enabled RAP BO (with its own `draft table z…_d`, `lock master`, etc.) and consume that via EML in the same way. That is a separate topic; see the official [SAP RAP draft documentation](https://help.sap.com/docs/abap-cloud/abap-rap/draft).
78+
79+
---
80+
81+
### example
82+
83+
```abap
84+
* Scenario 7 — Consume a standard SAP draft-enabled BO via EML
85+
*
86+
* You are on S/4HANA or BTP ABAP Environment. The sales order is
87+
* already exposed by SAP as a draft-enabled BO (I_SalesOrderTP). You
88+
* do NOT build your own BO and you do NOT create a draft table — SAP
89+
* ships both.
90+
*
91+
* The flow the user sees:
92+
* on_init -> Edit (create or resume the draft)
93+
* "Save Draft" pressed -> UPDATE (writes the draft only)
94+
* "Save Draft" again -> UPDATE (still draft, VBAK untouched)
95+
* ...
96+
* "Activate" pressed -> Activate (now VBAK is written)
97+
* "Discard" pressed -> Discard (drops the draft, releases lock)
98+
*
99+
* The session stays stateless. The draft survives in SAP's own
100+
* draft-shadow table between roundtrips. The lock is held by the BO
101+
* framework as long as the draft exists; closing the browser without
102+
* discarding leaves the draft so the same user can resume it later.
103+
*
104+
* Field names below (SalesOrder, SalesOrderType) match the released
105+
* CDS view I_SalesOrderTP on current S/4HANA. On older releases the
106+
* BO name or fields may differ — check the released-objects list in
107+
* your system.
108+
109+
CLASS z2ui5_test_lock_07 DEFINITION PUBLIC.
110+
111+
PUBLIC SECTION.
112+
INTERFACES z2ui5_if_app.
113+
114+
DATA sales_order TYPE c LENGTH 10 VALUE `0000004711`.
115+
DATA sales_order_type TYPE c LENGTH 4.
116+
DATA draft_open TYPE abap_bool.
117+
DATA status_text TYPE string.
118+
119+
PROTECTED SECTION.
120+
DATA client TYPE REF TO z2ui5_if_client.
121+
122+
METHODS on_init.
123+
METHODS on_event_save_draft.
124+
METHODS on_event_activate.
125+
METHODS on_event_discard.
126+
METHODS draft_acquire.
127+
METHODS draft_read.
128+
METHODS view_display.
129+
130+
PRIVATE SECTION.
131+
ENDCLASS.
132+
133+
134+
CLASS z2ui5_test_lock_07 IMPLEMENTATION.
135+
136+
METHOD z2ui5_if_app~main.
137+
138+
me->client = client.
139+
140+
IF client->check_on_init( ).
141+
on_init( ).
142+
ELSEIF client->check_on_event( `SAVE_DRAFT` ).
143+
on_event_save_draft( ).
144+
ELSEIF client->check_on_event( `ACTIVATE` ).
145+
on_event_activate( ).
146+
ELSEIF client->check_on_event( `DISCARD` ).
147+
on_event_discard( ).
148+
ENDIF.
149+
150+
ENDMETHOD.
151+
152+
153+
METHOD on_init.
154+
155+
draft_acquire( ).
156+
draft_read( ).
157+
view_display( ).
158+
159+
ENDMETHOD.
160+
161+
162+
METHOD draft_acquire.
163+
164+
" Edit is idempotent: if the user already has a draft for this
165+
" sales order, SAP returns it instead of failing.
166+
167+
MODIFY ENTITIES OF i_salesordertp
168+
ENTITY SalesOrder
169+
EXECUTE Edit
170+
FROM VALUE #( ( %key-SalesOrder = sales_order
171+
%param-PreserveChanges = abap_true ) )
172+
FAILED DATA(failed)
173+
REPORTED DATA(reported).
174+
175+
IF failed IS NOT INITIAL.
176+
draft_open = abap_false.
177+
status_text = `Could not open draft — locked by another user, or no authorization.`.
178+
RETURN.
179+
ENDIF.
180+
181+
COMMIT ENTITIES.
182+
183+
draft_open = abap_true.
184+
status_text = `Draft open — changes are saved as a draft until you press Activate.`.
185+
186+
ENDMETHOD.
187+
188+
189+
METHOD draft_read.
190+
191+
IF draft_open = abap_false.
192+
RETURN.
193+
ENDIF.
194+
195+
READ ENTITIES OF i_salesordertp
196+
ENTITY SalesOrder
197+
FIELDS ( SalesOrderType )
198+
WITH VALUE #( ( %key-SalesOrder = sales_order
199+
%key-IsActiveEntity = abap_false ) )
200+
RESULT DATA(drafts).
201+
202+
IF drafts IS NOT INITIAL.
203+
sales_order_type = drafts[ 1 ]-SalesOrderType.
204+
ENDIF.
205+
206+
ENDMETHOD.
207+
208+
209+
METHOD on_event_save_draft.
210+
211+
" Persists progress to the draft only. VBAK is NOT touched.
212+
" The user can press Save Draft many times across many roundtrips.
213+
214+
MODIFY ENTITIES OF i_salesordertp
215+
ENTITY SalesOrder
216+
UPDATE FIELDS ( SalesOrderType )
217+
WITH VALUE #( ( %tky-SalesOrder = sales_order
218+
%tky-IsActiveEntity = abap_false
219+
SalesOrderType = sales_order_type
220+
%control-SalesOrderType = if_abap_behv=>mk-on ) )
221+
FAILED DATA(failed)
222+
REPORTED DATA(reported).
223+
224+
IF failed IS NOT INITIAL.
225+
client->message_box_display( `Draft update failed.` ).
226+
RETURN.
227+
ENDIF.
228+
229+
COMMIT ENTITIES.
230+
client->message_toast_display( `Draft saved.` ).
231+
232+
ENDMETHOD.
233+
234+
235+
METHOD on_event_activate.
236+
237+
" Writes the draft through to the active sales order (VBAK) and
238+
" deletes the draft. Lock is released by the framework.
239+
240+
MODIFY ENTITIES OF i_salesordertp
241+
ENTITY SalesOrder
242+
EXECUTE Activate
243+
FROM VALUE #( ( %key-SalesOrder = sales_order
244+
%key-IsActiveEntity = abap_false ) )
245+
FAILED DATA(failed)
246+
REPORTED DATA(reported).
247+
248+
IF failed IS NOT INITIAL.
249+
client->message_box_display( `Activation failed — see application log.` ).
250+
RETURN.
251+
ENDIF.
252+
253+
COMMIT ENTITIES.
254+
client->message_toast_display( `Sales order activated.` ).
255+
client->nav_app_leave( ).
256+
257+
ENDMETHOD.
258+
259+
260+
METHOD on_event_discard.
261+
262+
MODIFY ENTITIES OF i_salesordertp
263+
ENTITY SalesOrder
264+
EXECUTE Discard
265+
FROM VALUE #( ( %key-SalesOrder = sales_order
266+
%key-IsActiveEntity = abap_false ) )
267+
FAILED DATA(failed)
268+
REPORTED DATA(reported).
269+
270+
COMMIT ENTITIES.
271+
client->nav_app_leave( ).
272+
273+
ENDMETHOD.
274+
275+
276+
METHOD view_display.
277+
278+
DATA(view) = z2ui5_cl_xml_view=>factory( ).
279+
view->shell(
280+
)->page(
281+
title = `Edit Sales Order — Standard BO Draft via EML`
282+
shownavbutton = client->check_app_prev_stack( )
283+
navbuttonpress = client->_event( `DISCARD` )
284+
)->simple_form(
285+
title = `Header (draft)`
286+
editable = draft_open
287+
)->content( `form`
288+
)->label( `Sales Order`
289+
)->input(
290+
value = sales_order
291+
enabled = abap_false
292+
)->label( `Type`
293+
)->input( client->_bind_edit( sales_order_type )
294+
)->label( `Status`
295+
)->input(
296+
value = status_text
297+
enabled = abap_false
298+
)->button(
299+
text = `Save Draft`
300+
press = client->_event( `SAVE_DRAFT` )
301+
enabled = draft_open
302+
)->button(
303+
text = `Activate`
304+
type = `Emphasized`
305+
press = client->_event( `ACTIVATE` )
306+
enabled = draft_open
307+
)->button(
308+
text = `Discard`
309+
press = client->_event( `DISCARD` ) ).
310+
client->view_display( view->stringify( ) ).
311+
312+
ENDMETHOD.
313+
314+
ENDCLASS.
315+
```abap

0 commit comments

Comments
 (0)