Skip to content

Commit 8099043

Browse files
committed
docs(draft): add end-to-end example with standard SAP draft BO via EML
1 parent f89552e commit 8099043

1 file changed

Lines changed: 206 additions & 1 deletion

File tree

docs/development/specific/draft.md

Lines changed: 206 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,211 @@ MODIFY ENTITIES OF i_salesordertp
5353
COMMIT ENTITIES.
5454
```
5555

56+
#### Editing a Standard SAP Draft BO
57+
On S/4HANA or BTP ABAP Environment (Steampunk), many business objects already ship as draft-enabled BOs (e.g. `I_SalesOrderTP`). You don't build a BO and you don't create a draft table — SAP provides both. Your abap2UI5 app just calls the standard BO via EML, which sidesteps the whole lock-during-think-time problem.
58+
59+
The session can stay **stateless**: the draft survives between roundtrips in SAP's draft-shadow table, and the lock is held by the BO framework as long as the draft exists. Closing the browser without activating or discarding leaves the draft for the same user to resume later — no `set_session_stateful( )`, no `ENQUEUE_*`, no custom Z table.
60+
61+
The user flow:
62+
```
63+
on_init -> Edit (create or resume the draft)
64+
"Save Draft" pressed -> UPDATE (writes the draft only, VBAK stays as-is)
65+
"Activate" pressed -> Activate (now VBAK is written through)
66+
"Discard" pressed -> Discard (drops the draft, releases lock)
67+
```
68+
69+
A complete example based on `I_SalesOrderTP`:
70+
```abap
71+
CLASS z2ui5_cl_sample_draft DEFINITION PUBLIC.
72+
73+
PUBLIC SECTION.
74+
INTERFACES z2ui5_if_app.
75+
76+
DATA sales_order TYPE c LENGTH 10 VALUE `0000004711`.
77+
DATA sales_order_type TYPE c LENGTH 4.
78+
DATA draft_open TYPE abap_bool.
79+
DATA status_text TYPE string.
80+
81+
PROTECTED SECTION.
82+
DATA client TYPE REF TO z2ui5_if_client.
83+
84+
METHODS on_init.
85+
METHODS on_event_save_draft.
86+
METHODS on_event_activate.
87+
METHODS on_event_discard.
88+
METHODS draft_acquire.
89+
METHODS draft_read.
90+
METHODS view_display.
91+
92+
ENDCLASS.
93+
94+
95+
CLASS z2ui5_cl_sample_draft IMPLEMENTATION.
96+
97+
METHOD z2ui5_if_app~main.
98+
99+
me->client = client.
100+
101+
IF client->check_on_init( ).
102+
on_init( ).
103+
ELSEIF client->check_on_event( `SAVE_DRAFT` ).
104+
on_event_save_draft( ).
105+
ELSEIF client->check_on_event( `ACTIVATE` ).
106+
on_event_activate( ).
107+
ELSEIF client->check_on_event( `DISCARD` ).
108+
on_event_discard( ).
109+
ENDIF.
110+
111+
ENDMETHOD.
112+
113+
METHOD on_init.
114+
draft_acquire( ).
115+
draft_read( ).
116+
view_display( ).
117+
ENDMETHOD.
118+
119+
METHOD draft_acquire.
120+
121+
" Edit is idempotent: if a draft already exists, SAP returns it.
122+
MODIFY ENTITIES OF i_salesordertp
123+
ENTITY SalesOrder
124+
EXECUTE Edit
125+
FROM VALUE #( ( %key-SalesOrder = sales_order
126+
%param-PreserveChanges = abap_true ) )
127+
FAILED DATA(failed)
128+
REPORTED DATA(reported).
129+
130+
IF failed IS NOT INITIAL.
131+
draft_open = abap_false.
132+
status_text = `Could not open draft — locked by another user, or no authorization.`.
133+
RETURN.
134+
ENDIF.
135+
136+
COMMIT ENTITIES.
137+
138+
draft_open = abap_true.
139+
status_text = `Draft open — changes are saved as a draft until you press Activate.`.
140+
141+
ENDMETHOD.
142+
143+
METHOD draft_read.
144+
145+
IF draft_open = abap_false.
146+
RETURN.
147+
ENDIF.
148+
149+
READ ENTITIES OF i_salesordertp
150+
ENTITY SalesOrder
151+
FIELDS ( SalesOrderType )
152+
WITH VALUE #( ( %key-SalesOrder = sales_order
153+
%key-IsActiveEntity = abap_false ) )
154+
RESULT DATA(drafts).
155+
156+
IF drafts IS NOT INITIAL.
157+
sales_order_type = drafts[ 1 ]-SalesOrderType.
158+
ENDIF.
159+
160+
ENDMETHOD.
161+
162+
METHOD on_event_save_draft.
163+
164+
MODIFY ENTITIES OF i_salesordertp
165+
ENTITY SalesOrder
166+
UPDATE FIELDS ( SalesOrderType )
167+
WITH VALUE #( ( %tky-SalesOrder = sales_order
168+
%tky-IsActiveEntity = abap_false
169+
SalesOrderType = sales_order_type
170+
%control-SalesOrderType = if_abap_behv=>mk-on ) )
171+
FAILED DATA(failed)
172+
REPORTED DATA(reported).
173+
174+
IF failed IS NOT INITIAL.
175+
client->message_box_display( `Draft update failed.` ).
176+
RETURN.
177+
ENDIF.
178+
179+
COMMIT ENTITIES.
180+
client->message_toast_display( `Draft saved.` ).
181+
182+
ENDMETHOD.
183+
184+
METHOD on_event_activate.
185+
186+
MODIFY ENTITIES OF i_salesordertp
187+
ENTITY SalesOrder
188+
EXECUTE Activate
189+
FROM VALUE #( ( %key-SalesOrder = sales_order
190+
%key-IsActiveEntity = abap_false ) )
191+
FAILED DATA(failed)
192+
REPORTED DATA(reported).
193+
194+
IF failed IS NOT INITIAL.
195+
client->message_box_display( `Activation failed — see application log.` ).
196+
RETURN.
197+
ENDIF.
198+
199+
COMMIT ENTITIES.
200+
client->message_toast_display( `Sales order activated.` ).
201+
client->nav_app_leave( ).
202+
203+
ENDMETHOD.
204+
205+
METHOD on_event_discard.
206+
207+
MODIFY ENTITIES OF i_salesordertp
208+
ENTITY SalesOrder
209+
EXECUTE Discard
210+
FROM VALUE #( ( %key-SalesOrder = sales_order
211+
%key-IsActiveEntity = abap_false ) )
212+
FAILED DATA(failed)
213+
REPORTED DATA(reported).
214+
215+
COMMIT ENTITIES.
216+
client->nav_app_leave( ).
217+
218+
ENDMETHOD.
219+
220+
METHOD view_display.
221+
222+
DATA(view) = z2ui5_cl_xml_view=>factory( ).
223+
view->shell(
224+
)->page(
225+
title = `Edit Sales Order — Standard BO Draft via EML`
226+
shownavbutton = client->check_app_prev_stack( )
227+
navbuttonpress = client->_event( `DISCARD` )
228+
)->simple_form(
229+
title = `Header (draft)`
230+
editable = draft_open
231+
)->content( `form`
232+
)->label( `Sales Order`
233+
)->input(
234+
value = sales_order
235+
enabled = abap_false
236+
)->label( `Type`
237+
)->input( client->_bind_edit( sales_order_type )
238+
)->label( `Status`
239+
)->input(
240+
value = status_text
241+
enabled = abap_false
242+
)->button(
243+
text = `Save Draft`
244+
press = client->_event( `SAVE_DRAFT` )
245+
enabled = draft_open
246+
)->button(
247+
text = `Activate`
248+
type = `Emphasized`
249+
press = client->_event( `ACTIVATE` )
250+
enabled = draft_open
251+
)->button(
252+
text = `Discard`
253+
press = client->_event( `DISCARD` ) ).
254+
client->view_display( view->stringify( ) ).
255+
256+
ENDMETHOD.
257+
258+
ENDCLASS.
259+
```
260+
56261
::: tip
57-
A draft-enabled BO holds an exclusive lock for its owner as long as the draft exists, so the app can stay stateless and the user can resume work later. If you need additional locks for non-draft objects, see [Locks](./locks.md).
262+
The field names (`SalesOrder`, `SalesOrderType`) match the released `I_SalesOrderTP` on current S/4HANA — on older releases the BO name or fields may differ. If no standard BO covers your object, define your own draft-enabled RAP BO (with its own `draft table z…_d`, `lock master`, etc.) and consume it the same way; see the [SAP RAP draft documentation](https://help.sap.com/docs/abap-cloud/abap-rap/draft). If you need locks for non-draft objects, see [Locks](./locks.md).
58263
:::

0 commit comments

Comments
 (0)