Skip to content

Commit d8623b0

Browse files
authored
Merge pull request #55 from abap2UI5/claude/add-draft-locks-pages-BHj30
Claude/add draft locks pages b hj30
2 parents d97a4b1 + ae039ed commit d8623b0

3 files changed

Lines changed: 425 additions & 0 deletions

File tree

docs/.vitepress/config.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ export default defineConfig({
159159
{ text: "Logging", link: "/development/specific/logging" },
160160
{ text: "Camera", link: "/development/specific/camera" },
161161
{ text: "CDS, EML", link: "/development/specific/cds" },
162+
{ text: "Draft Handling", link: "/development/specific/draft" },
163+
{ text: "Locks", link: "/development/specific/locks" },
162164
{ text: "Timer", link: "/development/specific/timer" },
163165
{ text: "Drag & Drop", link: "/development/specific/drag" },
164166
{

docs/development/specific/draft.md

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
---
2+
outline: [2, 4]
3+
---
4+
# Draft Handling
5+
6+
Draft handling lets users save unfinished work — for example a half-filled form — without writing through to the active database state. In abap2UI5 apps you drive RAP draft-enabled business objects directly through EML, just like any other entity (see also [CDS, EML](./cds.md)).
7+
8+
#### Create a Draft
9+
Use `MODIFY ENTITIES` with `%is_draft = if_abap_behv=>mk-on` to create a new draft instance:
10+
```abap
11+
METHOD z2ui5_if_app~main.
12+
13+
MODIFY ENTITIES OF i_salesordertp
14+
ENTITY salesorder
15+
CREATE
16+
FIELDS ( salesordertype salesorganization )
17+
WITH VALUE #( ( %cid = `0001`
18+
%is_draft = if_abap_behv=>mk-on
19+
%data = VALUE #(
20+
SalesOrderType = `TA`
21+
SalesOrganization = `1010` ) ) )
22+
MAPPED DATA(ls_mapped)
23+
FAILED DATA(ls_failed)
24+
REPORTED DATA(ls_reported).
25+
26+
COMMIT ENTITIES.
27+
28+
ENDMETHOD.
29+
```
30+
31+
#### Read a Draft
32+
Set `%key-IsActiveEntity = abap_false` to read the draft instead of the active record:
33+
```abap
34+
READ ENTITIES OF i_salesordertp
35+
ENTITY SalesOrder
36+
FIELDS ( SalesOrderType )
37+
WITH VALUE #( ( %key-SalesOrder = `0000004711`
38+
%key-IsActiveEntity = abap_false ) )
39+
RESULT DATA(lt_drafts).
40+
```
41+
42+
#### Activate or Discard
43+
Promote the draft to the active state with the `Activate` action, or throw it away with `Discard`:
44+
```abap
45+
MODIFY ENTITIES OF i_salesordertp
46+
ENTITY SalesOrder
47+
EXECUTE Activate
48+
FROM VALUE #( ( %key-SalesOrder = `0000004711`
49+
%key-IsActiveEntity = abap_false ) )
50+
FAILED DATA(ls_failed)
51+
REPORTED DATA(ls_reported).
52+
53+
COMMIT ENTITIES.
54+
```
55+
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+
261+
::: tip
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).
263+
:::

0 commit comments

Comments
 (0)