Appearance
Lesson 17 Practice — Draft-Enable the Support Issue Application
Your Support Issue application already has:
text
managed persistence
RAP behavior
validations
messages
actions
feature control
authorization
projection
OData V4 UI serviceNow add:
text
persistent draft editingTarget architecture:
text
Fiori Elements
↓
OData V4
↓
ZC_ISSUE_###
↓
Draft-enabled ZR_ISSUE_###
┌───────────────┐
↓ ↓
ZISSUE_### ZDISSUE_###
Active DraftPractice information
| Time | About 3 hours |
| Prerequisite | Lesson 17 teacher-led work |
| Base BO | ZR_ISSUE_### |
| Active table | ZISSUE_### |
| Draft table | ZDISSUE_### |
| Projection | ZC_ISSUE_### |
| Service | Existing Lesson 16 OData V4 UI service |
1. Verify prerequisites
Confirm these activate:
text
ZISSUE_###
ZR_ISSUE_###
base DCL
base BDEF
ZBP_R_ISSUE_###
ZC_ISSUE_###
projection DCL
projection BDEF
ZUI_ISSUE_###
OData V4 UI bindingRepair Lesson 16 defects first.
2. Keep draft separate from Issue Status
Issue business status remains:
text
O = Open
I = In Progress
C = ClosedDo not add:
text
D = DraftRAP Draft is not a business status.
3. Harden ResponsibleUser
Change:
text
ResponsibleUserfrom:
text
read-only on updateto:
text
fully read-onlyThe BO will assign ownership automatically.
4. Add owner determination
Create:
text
setResponsibleUserRequirements:
text
on modify
trigger = create
current technical user
only fill when ResponsibleUser is initial
provider-side local-mode EMLDo not let the external UI type the technical owner.
5. Verify existing initial Status determination
You should already have:
text
setInitialStatusRule:
text
new Issue
→ Status = OBoth determinations should now run during new-draft creation:
text
Status = O
ResponsibleUser = current user6. Add with draft
Open the base Issue BDEF.
Add:
abap
with draft;in the BDEF header.
7. Declare draft table
Use:
text
ZDISSUE_###as the draft-table name.
Add it to the root entity's behavior definition after the active persistence table.
8. Generate draft table
Place the cursor on:
text
ZDISSUE_###Use:
text
Ctrl+1Generate the draft table.
Do not manually build its technical draft administration.
Activate it.
9. Choose total ETag field
Use the field equivalent to:
text
LastChangedAtthat is semantically the active instance's last-change timestamp.
Add it as:
text
total etagafter the lock-master declaration.
Keep:
text
LocalLastChangedAtas the existing ETag master.
10. Explain both ETags
Complete:
text
Local ETag field:
____________________
Purpose:
____________________
Total ETag field:
____________________
Purpose:
____________________11. Add draft actions
Declare:
text
Edit
Activate optimized
Discard
Resume
PrepareUse actual RAP draft-action syntax.
12. Connect validations to Prepare
Your Issue BO already has:
text
validateTitle
validateReportedOn
validateCostAssign all three to:
text
draft determine action PrepareDo not create duplicate draft-specific validation methods.
13. Prepare target
Your source should contain a block equivalent to:
abap
draft determine action Prepare
{
validation validateTitle;
validation validateReportedOn;
validation validateCost;
}14. Preserve business actions
Keep:
text
startProcessing
closeThey remain business actions.
Do not confuse them with:
text
Edit
Activate
Discard
Resume
Prepare15. Adapt global authorization
Your Lesson 15 global authorization must now recognize update-style draft requests.
Treat:
text
%update
%action-Editaccording to the same training global update permission.
Fill only requested components in the global result structure. Keep the existing %create and %delete handling.
Prepare is a draft determine action. It has no independently generated authorization component, so do not check or populate authorization fields for it.
Do not use feature-control constants.
16. Adapt instance authorization
Your owner-based instance authorization must consider:
text
%update
%action-Editas requiring the same ownership check.
Rule remains:
text
ResponsibleUser = current user
→ authorizedReturn auth-unauthorized when the owner does not match. Keep the existing Lesson 15 %delete classroom cleanup policy.
get_instance_authorizations returns a result table. For each instance read through local-mode EML, append a row with its full %tky, then fill the requested components on that row. Do not assign components directly on the table as if it were the global result structure.
17. Explain Activate authorization
Why does the practice not invent:
text
a new independent "Activate privilege"?
Your answer must refer to:
text
underlying create/update
active persistence18. Draft-enable the projection BDEF
Open:
text
ZC_ISSUE_###projection behavior.
Add:
abap
use draft;after:
text
projection
strict ( 2 )19. Reuse all draft actions
Add:
text
use action Edit
use action Activate
use action Discard
use action Resume
use action PrepareKeep:
text
use action startProcessing
use action close20. Projection behavior target
Equivalent shape:
abap
projection;
strict ( 2 );
use draft;
define behavior for ZC_Issue_### alias Issue
use etag
{
use create;
use update;
use delete;
use action Edit;
use action Activate;
use action Discard;
use action Resume;
use action Prepare;
use action startProcessing;
use action close;
}21. Service artifacts
Do not create a second:
text
Service Definition
Service BindingReuse the Lesson 16 OData V4 UI service.
Activate changed artifacts.
Refresh/reopen the Fiori Elements preview.
Test A — New Draft
22. Create a new Issue in Fiori preview
Choose:
text
CreateEnter values equivalent to:
text
IssueNo = 99110001
Title = Draft issue test
Description = New draft lifecycle
RequesterEmail = draft.issue@example.com
Priority = H
ReportedOn = today
EstimatedCost = 250.00
CurrencyCode = EURDo not enter:
text
Status
ResponsibleUser
Uuid
admin fields23. Do not Save yet
Remain in draft editing.
Expected derived values:
text
Status = O
ResponsibleUser = current user24. Inspect active table
Open:
text
ZISSUE_###Use Table Data Preview.
Expected for:
text
99110001text
no active row yet25. Inspect draft table
Open:
text
ZDISSUE_###Expected:
text
draft row for 99110001 existsInspect but do not modify the technical draft columns.
26. Save
Return to the UI.
Choose:
text
SaveExpected lifecycle:
text
Prepare
→ validations
→ Activate
→ active CREATE
→ draft removed27. Verify activation
Expected:
text
ZISSUE_###
→ 99110001 exists
ZDISSUE_###
→ corresponding draft removedTest B — Edit and Discard
28. Edit active Issue
Open:
text
99110001Choose:
text
EditChange:
text
Descriptionto:
text
This change will be discardedDo not Save.
29. Compare active and draft
Active table:
text
old DescriptionDraft table:
text
new unsaved DescriptionRecord both values.
30. Discard
Choose:
text
Cancel / DiscardExpected:
text
draft removed
active Description unchangedTest C — Validation Blocks Activation
31. Edit again
Set:
text
ReportedOn = tomorrowThis violates your Lesson 13 validation.
32. Save invalid draft
Choose:
text
SaveExpected:
text
Prepare invokes validateReportedOn
error message returned
Activate does not complete
draft remains
active row unchanged33. Correct the draft
Set:
text
ReportedOn = todaySave again.
Expected:
text
activation succeeds
draft removed
active row updatedTest D — Business Actions Remain Separate
34. Check current business Status
After activation:
text
Status = OBusiness action:
text
startProcessingis conceptually separate from:
text
Edit / Activate35. Execute business action
Use the service UI to execute:
text
startProcessingExpected:
text
O → IVerify the active business Status changed.
36. Explain the distinction
Complete:
text
Activate means:
____________________
startProcessing means:
____________________The answers must not be the same.
Draft Reasoning
37. New draft vs edit draft
Complete:
| Question | New Draft | Edit Draft |
|---|---|---|
| Active row already exists? | ||
| How is it started? | ||
| What does Activate do? | ||
| What does Discard do? |
38. Active vs draft table
Explain:
text
Why can a draft row contain values
that the active table does not yet contain?Use:
text
work in progress
activationin your answer.
39. Why invalid draft data can exist
A user may temporarily type:
text
invalid ReportedOnwhile editing.
Why is that acceptable in the draft table but not in the active table?
40. Why Prepare exists
Explain why:
text
on-save validation
+
draft Prepareare connected.
What would be the risk if the relevant validations were never assigned to Prepare?
41. Why total ETag matters
Explain this scenario:
text
draft created from active version A
active data changes to version B
user later tries to resume/save old draftWhat must RAP detect?
42. Why Resume exists
Explain:
text
durable draft
vs
short-lived exclusive database lockDo not wait for a real timeout.
Repair Exercises
43. Repair — no draft table
Remove or break the draft-table declaration temporarily.
Use syntax check.
Restore it and explain why Draft needs separate persistence.
44. Repair — no total ETag
Temporarily remove:
text
total etagRun syntax check.
Restore it.
Explain why local ETag alone is not the complete draft concurrency model.
45. Repair — missing Prepare validation
Temporarily omit:
text
validateReportedOnfrom Prepare.
Explain why this weakens pre-activation checking.
Restore it.
46. Repair — no use draft
Imagine the base BO is draft-enabled but the projection BDEF is not.
Explain why the OData UI projection would not expose the intended draft lifecycle.
Restore:
text
use draft47. Repair — missing use action Edit
Remove it temporarily in strict projection behavior.
Run syntax check.
Restore it.
48. Repair — owner not derived
Imagine ResponsibleUser remains blank on a new draft.
Explain potential problems with:
text
DCL
instance authorization
UI continuityRestore the owner determination.
49. Repair — draft authorization not updated
Imagine Lesson 15 authorization handles:
text
%updatebut ignores:
text
%action-EditExplain why Edit can be denied unexpectedly, then adapt both authorization handlers to apply the update-style policy to Edit.
Explain why adding authorization fields for Prepare would cause a syntax error: it is a draft determine action, and those components do not exist in the generated authorization structures.
Check that the instance handler appends result rows keyed by %tky and fills only requested components on each row.
50. Repair — direct SQL draft manipulation
Do not execute this:
text
DELETE FROM ZDISSUE_###Explain why draft persistence must be owned by the RAP runtime.
Certification-Style Mini Task
51. Draft repair challenge
Without looking at the guided Reservation BDEF, repair a deliberately incomplete draft setup with:
text
with draft present
draft table missing
total ETag missing
Prepare empty
projection lacks use draftRequired outcome:
text
draft table generated
total ETag correct
validations assigned to Prepare
projection draft enabled
draft actions explicitly reused
UI Create/Edit/Save works52. State audit
Complete from actual runtime tests:
| Stage | Active row? | Draft row? | Business Status |
|---|---|---|---|
| New draft before Save | |||
| New draft after Save | |||
| Edit draft before Discard | |||
| After Discard | |||
| Invalid edit after failed Save | |||
| Corrected edit after Save |
53. Draft-action audit
| Draft action | Purpose |
|---|---|
| Edit | |
| Activate | |
| Discard | |
| Resume | |
| Prepare |
54. Submission checklist
55. End-of-practice explanation
Explain without notes:
text
A RAP draft is persisted work in progress.
The active table stores active business data.
The draft table stores intermediate editing state.
Edit creates an edit draft.
Create in the draft UI creates a new draft.
Prepare runs the validations needed before activation.
Activate transfers valid draft state to active persistence.
Discard removes draft work without deleting the active object.
Resume continues a durable draft after lock expiry.
Total ETag protects the relationship between
a longer-lived draft and its active version.
Draft state is not business Status.If you can prove each statement through your Issue service and tables, you are ready for Lesson 18 compositions.