upload current sources
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
# RAP handover — Arena change-approval BO (stage 1, 2026-09-15)
|
||||
|
||||
Target: development tenant `my431353` (ADT destination `0M7DEJI`), package `ZARENA_PLM`
|
||||
(sub-package of `ZLOCAL`, no transport). The ADT MCP Server can create objects and activate
|
||||
them but cannot write source (PRD V-4), so every file in this folder is a **ready-to-paste
|
||||
source** for the VS Code ADT editor. Each file header names the target object, its
|
||||
`abap:` URI and says "replace entire content".
|
||||
|
||||
Every SAP behavioral claim in these files carries a `[source: … , verified 2026-09-15]`
|
||||
tag; the sources are `abap-docs` (ABAP Cloud keyword docs + SAP samples), `sap-docs`
|
||||
(SAP Help) and `sap-released-objects` (release states).
|
||||
|
||||
## What exists in the tenant right now
|
||||
|
||||
Generated by `x-ui-service` (all **active**, ATC 0 findings on 12 objects, 2026-09-15):
|
||||
|
||||
| Object | Type | Notes |
|
||||
|---|---|---|
|
||||
| `ZZCHNGPPROVAL000` | TABL | persistent table (generator naming) |
|
||||
| `ZZR_CHANGEAPPROVAL000` | DDLS / BDEF / DCLS | root view entity, managed BDEF, access control |
|
||||
| `ZZBP_R_CHANGEAPPROVAL000` | CLAS | behavior pool of the base BDEF |
|
||||
| `ZZC_CHANGEAPPROVAL000` | DDLS / BDEF / DDLX / DCLS | UI projection view, projection BDEF, metadata extension, access control |
|
||||
| `ZZBP_C_CHANGEAPPROVAL000` | CLAS | projection behavior pool — **delete it** (step 9) |
|
||||
| `ZZUI_ARENA_CHANGE_APPRVL000_O4` | SRVD + SRVB | service definition and OData V4 **UI** binding (same name), **unpublished** |
|
||||
| `ZZARENA_CHANGE_APPROVAL000` | RONT + NONT | SAP object type / node type |
|
||||
|
||||
Created empty via `create_object` (exist, **no source, inactive**):
|
||||
|
||||
| Object | Type | Purpose |
|
||||
|---|---|---|
|
||||
| `ZD_CHANGEAPPROVAL_REJECTP` | DDLS | abstract entity — `reject` parameter (`RejectReason`) |
|
||||
| `ZD_CHANGEAPPROVAL_SYNCEDP` | DDLS | abstract entity — `markSynced` parameter (`SapChangeNumber`) |
|
||||
| `ZD_CHANGEAPPROVAL_FAILEDP` | DDLS | abstract entity — `markFailed` parameter (`ErrorMessage`) |
|
||||
| `ZC_CHANGEAPPROVAL_A2X` | DDLS + DCLS | A2X projection view (worker) and its access control |
|
||||
| `ZAPI_ARENA_CHANGE_APPROVAL` | SRVD | Web API service definition (worker) |
|
||||
|
||||
Not yet creatable (the MCP validation refuses until the referenced objects are active):
|
||||
|
||||
| Object | Type | Blocker seen 2026-09-15 |
|
||||
|---|---|---|
|
||||
| `ZC_CHANGEAPPROVAL_A2X` | BDEF (projection) | "The referenced STOB object ZC_CHANGEAPPROVAL_A2X does not exist" |
|
||||
| `ZAPI_ARENA_CHANGE_APPROVAL_A2X` | SRVB (OData V4 - Web API) | "An active version of the Service Definition ZAPI_ARENA_CHANGE_APPROVAL does not exist" |
|
||||
|
||||
## Paste-and-activate sequence
|
||||
|
||||
Open each object in the VS Code ADT editor (or ADT Eclipse), replace the whole source with
|
||||
the file content, save, activate. Activation order matters — dependencies are top-down.
|
||||
|
||||
1. `zzchngpproval000.tabl.asddls` → table `ZZCHNGPPROVAL000`. (File name uses the
|
||||
abap-file-formats extension by analogy with `.ddls.asddls`; the tenant object is the
|
||||
same regardless.)
|
||||
2. `zd_changeapproval_rejectp.ddls.asddls`, `zd_changeapproval_syncedp.ddls.asddls`,
|
||||
`zd_changeapproval_failedp.ddls.asddls` → the three abstract entities.
|
||||
3. `zzr_changeapproval000.ddls.asddls` → root view entity.
|
||||
4. `zzr_changeapproval000.bdef.asbdef` → base BDEF.
|
||||
Watch for a message about the unmapped elements `StatusText`, `StatusCriticality`,
|
||||
`IsApprovable`, `IsRetriable` (CDS-calculated, deliberately not in the mapping). A
|
||||
warning is acceptable; an **error** means the fallback in the file header applies.
|
||||
5. `zzbp_r_changeapproval000.clas.abap` (global class) and
|
||||
`zzbp_r_changeapproval000.clas.locals_imp.abap` (Local Types tab) → behavior pool.
|
||||
6. `zzc_changeapproval000.ddls.asddls` and `zc_changeapproval_a2x.ddls.asddls` → both
|
||||
projection views.
|
||||
7. `zzc_changeapproval000.bdef.asbdef` → UI projection BDEF.
|
||||
8. Create the A2X projection BDEF (now possible): ADT *New Behavior Definition* on
|
||||
`ZC_CHANGEAPPROVAL_A2X`, implementation type *Projection* — or via MCP:
|
||||
`abap_creation-run_validation` + `create_object` with objectType `BDEF/BDO` and
|
||||
`{"behaviorDefinitionType":"definition","packageName":"ZARENA_PLM","rootEntity":"ZC_CHANGEAPPROVAL_A2X","name":"ZC_CHANGEAPPROVAL_A2X","description":"Arena change approval: A2X projection behavior","implementationType":"Projection"}`,
|
||||
transport `""`. Then paste `zc_changeapproval_a2x.bdef.asbdef`, activate.
|
||||
9. Delete the generated class `ZZBP_C_CHANGEAPPROVAL000` (no longer referenced by the
|
||||
projection BDEF; a projection needs a behavior pool only for new actions/functions
|
||||
[source: abap-docs /abap-docs-cloud/ABENBDL_BDEF_PROJECTION_HEADER, verified 2026-09-15]).
|
||||
10. `zzr_changeapproval000.dcls.asdcls`, then `zzc_changeapproval000.dcls.asdcls` and
|
||||
`zc_changeapproval_a2x.dcls.asdcls` → access controls.
|
||||
11. `zzc_changeapproval000.ddlx.asddlx` → metadata extension.
|
||||
12. `zzui_arena_change_apprvl000_o4.srvd.srvdsrv` and
|
||||
`zapi_arena_change_approval.srvd.srvdsrv` → service definitions.
|
||||
13. Create the Web API binding (now possible): ADT *New Service Binding* on
|
||||
`ZAPI_ARENA_CHANGE_APPROVAL`, binding type *OData V4 - Web API*, name
|
||||
`ZAPI_ARENA_CHANGE_APPROVAL_A2X` — or via MCP `create_object` with objectType
|
||||
`SRVB/SVB` and
|
||||
`{"packageName":"ZARENA_PLM","name":"ZAPI_ARENA_CHANGE_APPROVAL_A2X","description":"Arena change approval: OData V4 Web API binding (worker)","bindingType":"OData V4 - Web API","serviceDefinition":"ZAPI_ARENA_CHANGE_APPROVAL"}`.
|
||||
Activate. **Do not publish** either binding (publishing is a later brief, together
|
||||
with the IAM app / communication scenario).
|
||||
|
||||
## Activation URIs for `abap_activate_objects` (after pasting)
|
||||
|
||||
Pattern learned live 2026-09-15: `abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/<folder>/<NAME>/<name>.<ext>`
|
||||
with these folders/extensions (all verified by a successful activation):
|
||||
|
||||
| Type | Folder | Extension |
|
||||
|---|---|---|
|
||||
| TABL | `Dictionary/Database%20Tables` | `.tabl.json` |
|
||||
| DDLS | `Core%20Data%20Services/Data%20Definitions` | `.ddls.acds` |
|
||||
| BDEF | `Core%20Data%20Services/Behavior%20Definitions` | `.bdef.json` (`.bdef.acds`, `.bdef.asbdef`, `.bdef.abap` all fail with "array element 0 is null") |
|
||||
| DDLX | `Core%20Data%20Services/Metadata%20Extensions` | `.ddlx.acds` |
|
||||
| DCLS | `Core%20Data%20Services/Access%20Controls` | `.dcls.acds` |
|
||||
| CLAS | `Source%20Code%20Library/Classes` | `.clas.abap` |
|
||||
| SRVD | `Business%20Services/Service%20Definitions` | `.srvd.acds` |
|
||||
| SRVB | `Business%20Services/Service%20Bindings` | `.srvb.json` |
|
||||
| RONT | `Business%20Services/SAP%20Object%20Types` | `.ront.json` |
|
||||
| NONT | `Business%20Services/SAP%20Object%20Node%20Types` | `.nont.json` |
|
||||
|
||||
In sequence order (`B` = `abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM`):
|
||||
|
||||
```
|
||||
B/Dictionary/Database%20Tables/ZZCHNGPPROVAL000/zzchngpproval000.tabl.json
|
||||
B/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_REJECTP/zd_changeapproval_rejectp.ddls.acds
|
||||
B/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_SYNCEDP/zd_changeapproval_syncedp.ddls.acds
|
||||
B/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_FAILEDP/zd_changeapproval_failedp.ddls.acds
|
||||
B/Core%20Data%20Services/Data%20Definitions/ZZR_CHANGEAPPROVAL000/zzr_changeapproval000.ddls.acds
|
||||
B/Core%20Data%20Services/Behavior%20Definitions/ZZR_CHANGEAPPROVAL000/zzr_changeapproval000.bdef.json
|
||||
B/Source%20Code%20Library/Classes/ZZBP_R_CHANGEAPPROVAL000/zzbp_r_changeapproval000.clas.abap
|
||||
B/Core%20Data%20Services/Data%20Definitions/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.ddls.acds
|
||||
B/Core%20Data%20Services/Data%20Definitions/ZC_CHANGEAPPROVAL_A2X/zc_changeapproval_a2x.ddls.acds
|
||||
B/Core%20Data%20Services/Behavior%20Definitions/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.bdef.json
|
||||
B/Core%20Data%20Services/Behavior%20Definitions/ZC_CHANGEAPPROVAL_A2X/zc_changeapproval_a2x.bdef.json
|
||||
B/Core%20Data%20Services/Access%20Controls/ZZR_CHANGEAPPROVAL000/zzr_changeapproval000.dcls.acds
|
||||
B/Core%20Data%20Services/Access%20Controls/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.dcls.acds
|
||||
B/Core%20Data%20Services/Access%20Controls/ZC_CHANGEAPPROVAL_A2X/zc_changeapproval_a2x.dcls.acds
|
||||
B/Core%20Data%20Services/Metadata%20Extensions/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.ddlx.acds
|
||||
B/Business%20Services/Service%20Definitions/ZZUI_ARENA_CHANGE_APPRVL000_O4/zzui_arena_change_apprvl000_o4.srvd.acds
|
||||
B/Business%20Services/Service%20Definitions/ZAPI_ARENA_CHANGE_APPROVAL/zapi_arena_change_approval.srvd.acds
|
||||
B/Business%20Services/Service%20Bindings/ZZUI_ARENA_CHANGE_APPRVL000_O4/zzui_arena_change_apprvl000_o4.srvb.json
|
||||
B/Business%20Services/Service%20Bindings/ZAPI_ARENA_CHANGE_APPROVAL_A2X/zapi_arena_change_approval_a2x.srvb.json
|
||||
```
|
||||
|
||||
Then re-run ATC on the package objects (`abap_atc_run`; omit RONT/NONT — the ATC API
|
||||
answers "No valid data model exists for object type RONT/ROT") and
|
||||
`abap_business_services-fetch_services` on both bindings.
|
||||
|
||||
## Design decisions baked into the files (falsifiable, dated 2026-09-15)
|
||||
|
||||
- **Two projections, two service definitions.** The brief asked for both bindings on the
|
||||
generated service definition *and* for the UI to expose only approve/reject/retrySync
|
||||
while the worker gets create + mark*. A service definition exposes one projection, and a
|
||||
projection BDEF exposes exactly what it lists (no automatic inheritance
|
||||
[source: abap-docs /abap-docs-cloud/ABENBDL_USE_PROJECTION]). Both requirements cannot
|
||||
hold on one definition, so the A2X path got its own projection view/BDEF/definition and
|
||||
the Web API binding sits on `ZAPI_ARENA_CHANGE_APPROVAL`. The RAP-2 "read-only from the
|
||||
UI" requirement wins over the structural wording.
|
||||
- **`authorization master ( none )`** instead of the generator's `( global )`: ADR-002
|
||||
makes the IAM app / business catalog the only access control and DCL governs reads;
|
||||
`( none )` is the documented way to declare "no RAP authorization checks"
|
||||
[source: abap-docs /abap-docs-cloud/ABENBDL_AUTHORIZATION]. Flip to `( global )` plus a
|
||||
`FOR GLOBAL AUTHORIZATION` handler when a custom authorization object exists.
|
||||
- **Derived fields are computed, not persisted.** `StatusText`, `StatusCriticality`,
|
||||
`IsApprovable`, `IsRetriable` are CASE expressions in the root view; a transactional
|
||||
query projection cannot hold expressions
|
||||
[source: abap-docs /abap-docs-cloud/ABENCDS_DEFINE_VIEW_AS_PROJECTION]. They are
|
||||
`field ( readonly )` and absent from the mapping — see step 4.
|
||||
- **Action parameters are abstract entities** (`ZD_*`), one element each, because action
|
||||
input must be an abstract entity or DDIC type
|
||||
[source: abap-docs /abap-docs-cloud/ABENBDL_ACTION_INPUT_PARAM]. `markSynced` and
|
||||
`markFailed` therefore take `SapChangeNumber` / `ErrorMessage` as parameters — the only
|
||||
way an action can "set" them from the worker.
|
||||
- **`internal update`** keeps `update` out of every OData surface while the actions and
|
||||
the determination still update fields `IN LOCAL MODE`
|
||||
[source: abap-docs /abap-docs-cloud/ABENBDL_INTERNAL].
|
||||
- **RequestedBy** is the technical user of the creator (the worker's communication user in
|
||||
the A2X flow). Change to `mandatory : create` if the Arena requester should be shown.
|
||||
|
||||
## Landmines learned live (KNOWLEDGE.md candidates)
|
||||
|
||||
- [2026-09-15] `x-ui-service` generator: every field needs `semanticType` (e.g. `custom`)
|
||||
or validation fails with "Builtin type of field X is invalid"; semantic-key fields pass
|
||||
without it. The generator prepends its own `Z` to the `prefix` (`Z` → `ZZ…`) and appends
|
||||
`000` to every artifact name even with `suffix: ""`; service definition and UI binding
|
||||
get the same name (`ZZUI_ARENA_CHANGE_APPRVL000_O4`). There is no delete tool in the ADT
|
||||
MCP, so a naming mistake is permanent from the agent side.
|
||||
- [2026-09-15] `create_object` for SRVD needs `sourceType` (`"S"` worked; omitted →
|
||||
"serviceDefinitionInfo.sourceType is null"). BDEF/SRVB creation validates the referenced
|
||||
DDLS/SRVD **active** version, so source-less objects block dependent creations.
|
||||
- [2026-09-15] Activation URIs: see table above; BDEF is `.bdef.json`, table `.tabl.json`,
|
||||
SAP object types live under `Business Services`.
|
||||
- [2026-09-15] The MCP session id from `get_schema` `referenceContent` is single-use in
|
||||
practice — fetch a fresh one before each `generate_objects` attempt.
|
||||
@@ -0,0 +1,10 @@
|
||||
/* TARGET OBJECT : service definition ZAPI_ARENA_CHANGE_APPROVAL (created empty via ADT MCP 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Business%20Services/Service%20Definitions/ZAPI_ARENA_CHANGE_APPROVAL/zapi_arena_change_approval.srvd.acds
|
||||
ACTION : replace entire content, then activate (after ZC_CHANGEAPPROVAL_A2X view + BDEF).
|
||||
Sources: as ZZUI_ARENA_CHANGE_APPRVL000_O4; odata_v4_webapi is the Web API contract [ABENSRVD_PROVIDER_CONTRACT]. */
|
||||
@EndUserText.label: 'Arena change approval - Web API (worker)'
|
||||
define service ZAPI_ARENA_CHANGE_APPROVAL
|
||||
provider contracts odata_v4_webapi
|
||||
{
|
||||
expose ZC_CHANGEAPPROVAL_A2X as ChangeApproval;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// TARGET OBJECT : behavior definition ZC_CHANGEAPPROVAL_A2X (A2X projection BDEF) - DOES NOT EXIST YET.
|
||||
// The ADT MCP refused to create it while ZC_CHANGEAPPROVAL_A2X (DDLS) had no active source
|
||||
// ("The referenced STOB object ZC_CHANGEAPPROVAL_A2X does not exist", 2026-09-15).
|
||||
// Create it after the projection view is active: ADT > New Behavior Definition on ZC_CHANGEAPPROVAL_A2X,
|
||||
// implementation type Projection (or re-run abap_creation-create_object BDEF/BDO, see README), paste, activate.
|
||||
// Sources: as ZZC_CHANGEAPPROVAL000. use create lets the worker stage records (ARN-010: the staged payload is what
|
||||
// gets executed); the worker never sees approve/reject/retrySync (PRD RAP-6).
|
||||
projection;
|
||||
strict ( 2 );
|
||||
|
||||
define behavior for ZC_CHANGEAPPROVAL_A2X alias ChangeApproval
|
||||
{
|
||||
use etag;
|
||||
use create;
|
||||
|
||||
use action markExecuting;
|
||||
use action markSynced;
|
||||
use action markFailed;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/* TARGET OBJECT : access control ZC_CHANGEAPPROVAL_A2X (created empty via ADT MCP 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Access%20Controls/ZC_CHANGEAPPROVAL_A2X/zc_changeapproval_a2x.dcls.acds
|
||||
ACTION : replace entire content, then activate (after ZC_CHANGEAPPROVAL_A2X view and ZZR_CHANGEAPPROVAL000 DCL).
|
||||
Sources: as ZZC_CHANGEAPPROVAL000 DCL. */
|
||||
@EndUserText.label: 'Access control for ZC_CHANGEAPPROVAL_A2X'
|
||||
@MappingRole: true
|
||||
define role ZC_CHANGEAPPROVAL_A2X {
|
||||
grant select on ZC_CHANGEAPPROVAL_A2X
|
||||
where inheriting conditions from entity ZZR_CHANGEAPPROVAL000;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/* TARGET OBJECT : data definition ZC_CHANGEAPPROVAL_A2X (A2X projection for the worker; created empty via ADT MCP 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZC_CHANGEAPPROVAL_A2X/zc_changeapproval_a2x.ddls.acds
|
||||
ACTION : replace entire content, then activate (after ZZR_CHANGEAPPROVAL000).
|
||||
Notes: separate projection so the Web API exposes create + mark* while the UI projection stays read-only
|
||||
(PRD RAP-2 / RAP-6); same syntax sources as ZZC_CHANGEAPPROVAL000. No metadata extension here -
|
||||
a Web API binding carries no UI annotations [source: sap-docs sap-help loio 248b36b7ebce4f7e8c7670c9371adee1, verified 2026-09-15]. */
|
||||
@EndUserText.label: 'Arena change approval - A2X projection (worker)'
|
||||
@AccessControl.authorizationCheck: #CHECK
|
||||
@ObjectModel.semanticKey: ['ItemNumber', 'ChangeType', 'ArenaEcoId']
|
||||
define root view entity ZC_CHANGEAPPROVAL_A2X
|
||||
provider contract transactional_query
|
||||
as projection on ZZR_CHANGEAPPROVAL000
|
||||
{
|
||||
key ID,
|
||||
ItemNumber,
|
||||
ItemName,
|
||||
ChangeType,
|
||||
ArenaEcoId,
|
||||
@ObjectModel.text.element: ['StatusText']
|
||||
Status,
|
||||
StatusText,
|
||||
StatusCriticality,
|
||||
RequestedBy,
|
||||
RequestedOn,
|
||||
DecidedBy,
|
||||
DecidedOn,
|
||||
SapChangeNumber,
|
||||
ErrorMessage,
|
||||
RejectReason,
|
||||
SapPreview,
|
||||
IsApprovable,
|
||||
IsRetriable,
|
||||
CreatedBy,
|
||||
CreatedAt,
|
||||
LastChangedBy,
|
||||
LastChangedAt,
|
||||
LocalLastChangedAt
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/* TARGET OBJECT : data definition ZD_CHANGEAPPROVAL_FAILEDP (abstract entity = parameter of action markFailed; created empty via ADT MCP 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_FAILEDP/zd_changeapproval_failedp.ddls.acds
|
||||
ACTION : replace entire content, then activate.
|
||||
Sources: as ZD_CHANGEAPPROVAL_REJECTP. */
|
||||
@EndUserText.label: 'Arena change approval: markFailed parameter'
|
||||
define abstract entity ZD_CHANGEAPPROVAL_FAILEDP
|
||||
{
|
||||
@EndUserText.label: 'Error message'
|
||||
ErrorMessage : abap.char(255);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* TARGET OBJECT : data definition ZD_CHANGEAPPROVAL_REJECTP (abstract entity = parameter of action reject; created empty via ADT MCP 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_REJECTP/zd_changeapproval_rejectp.ddls.acds
|
||||
ACTION : replace entire content, then activate.
|
||||
Notes: action input parameters must be a CDS abstract entity or DDIC type; @EndUserText.label on the element
|
||||
gives the UI label [source: abap-docs /abap-docs-cloud/ABENBDL_ACTION_INPUT_PARAM, verified 2026-09-15];
|
||||
abstract-entity syntax [source: abap-docs /abap-docs-cloud/ABENBDL_ACTION2_ABEXA, verified 2026-09-15].
|
||||
The OData parameter name is the element name -> RejectReason, as the Fiori app expects (PRD RAP-2). */
|
||||
@EndUserText.label: 'Arena change approval: reject parameter'
|
||||
define abstract entity ZD_CHANGEAPPROVAL_REJECTP
|
||||
{
|
||||
@EndUserText.label: 'Reject reason'
|
||||
RejectReason : abap.char(255);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/* TARGET OBJECT : data definition ZD_CHANGEAPPROVAL_SYNCEDP (abstract entity = parameter of action markSynced; created empty via ADT MCP 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZD_CHANGEAPPROVAL_SYNCEDP/zd_changeapproval_syncedp.ddls.acds
|
||||
ACTION : replace entire content, then activate.
|
||||
Sources: as ZD_CHANGEAPPROVAL_REJECTP. */
|
||||
@EndUserText.label: 'Arena change approval: markSynced parameter'
|
||||
define abstract entity ZD_CHANGEAPPROVAL_SYNCEDP
|
||||
{
|
||||
@EndUserText.label: 'SAP change number'
|
||||
SapChangeNumber : abap.char(12);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
" TARGET OBJECT : class ZZBP_R_CHANGEAPPROVAL000 - GLOBAL CLASS include (behavior pool; generated 2026-09-15)
|
||||
" abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Source%20Code%20Library/Classes/ZZBP_R_CHANGEAPPROVAL000/zzbp_r_changeapproval000.clas.abap
|
||||
" ACTION : replace entire content of the global class; the handlers go into "Local Types" (locals_imp file).
|
||||
" Source: FOR BEHAVIOR OF defines the ABAP behavior pool; the global class implements nothing itself
|
||||
" [source: abap-docs /abap-docs-cloud/ABAPCLASS_FOR_BEHAVIOR_OF, ABENABAP_BEHAVIOR_POOLS, verified 2026-09-15].
|
||||
CLASS zzbp_r_changeapproval000 DEFINITION
|
||||
PUBLIC
|
||||
ABSTRACT
|
||||
FINAL
|
||||
FOR BEHAVIOR OF zzr_changeapproval000.
|
||||
ENDCLASS.
|
||||
|
||||
CLASS zzbp_r_changeapproval000 IMPLEMENTATION.
|
||||
ENDCLASS.
|
||||
@@ -0,0 +1,426 @@
|
||||
" TARGET OBJECT : class ZZBP_R_CHANGEAPPROVAL000 - LOCAL TYPES include (Local Types tab in ADT)
|
||||
" abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Source%20Code%20Library/Classes/ZZBP_R_CHANGEAPPROVAL000/zzbp_r_changeapproval000.clas.locals_imp.abap
|
||||
" ACTION : replace entire content, then activate the class (BDEF ZZR_CHANGEAPPROVAL000 must be active first).
|
||||
"
|
||||
" Sources (all verified 2026-09-15):
|
||||
" handler class inherits from CL_ABAP_BEHAVIOR_HANDLER (released) [sap-released-objects public_cloud A]
|
||||
" FOR INSTANCE FEATURES signature + result via %tky / %features-%action-<name> / if_abap_behv=>fc-o-enabled|disabled
|
||||
" [abap-docs /abap-docs-cloud/ABAPHANDLER_METH_FEATURES, ABAPDERIVED_TYPES_FEATURES, ABENBDL_ACTIONS_FC]
|
||||
" FOR MODIFY ... FOR ACTION with RESULT; %param carries the action parameter (keys) and the result ($self)
|
||||
" [abap-docs /abap-docs-cloud/ABENBDL_ACTION2_ABEXA, ABAPDERIVED_TYPES_PARAM]
|
||||
" READ ENTITIES ... IN LOCAL MODE ... FIELDS ( ) WITH CORRESPONDING #( keys ) RESULT ... FAILED failed
|
||||
" [abap-docs /abap-docs-cloud/ABENBDL_ACTIONS_FC example]
|
||||
" MODIFY ENTITIES ... IN LOCAL MODE (skips feature control and authorization) with UPDATE FIELDS
|
||||
" [abap-docs /abap-docs-cloud/ABAPMODIFY_ENTITY_ENTITIES, ABAPMODIFY_ENTITY_ENTITIES_OP, ABENBDL_AUTHORIZATION]
|
||||
" %msg = new_message_with_text( ... ) into reported [abap-docs /abap-docs-cloud/ABENBDL_ACTIONS_FC example]
|
||||
" FOR DETERMINE ON MODIFY signature [abap-docs /abap-docs-cloud/ABAPHANDLER_METH_DET]
|
||||
" utclong_current( ) [abap-docs /abap-docs-cloud/ABENUTCLONG_CURRENT]
|
||||
" cl_abap_context_info=>get_user_technical_name( ) (released class) [sap-docs sap-help loio 7be24435b3e24540a9edad9a2535175a;
|
||||
" sap-released-objects CL_ABAP_CONTEXT_INFO public_cloud A]
|
||||
" Design notes:
|
||||
" - Status transitions are enforced twice: get_instance_features disables the action (UI greys it out / EML fails
|
||||
" with an entry in failed [ABENBDL_ACTIONS_FC]) AND each action re-checks the current status so an EML caller
|
||||
" IN LOCAL MODE cannot skip the state machine.
|
||||
" - The six actions repeat the same read/check/update/read pattern on purpose: each action has its own derived
|
||||
" key type, so a generic helper would need additional derived-type plumbing that is not worth it for six methods.
|
||||
" - RequestedBy is the technical user of the creator (for the A2X flow: the worker's communication user).
|
||||
" If the Arena requester should be shown instead, make RequestedBy mandatory:create in the BDEF and drop it
|
||||
" from the determination.
|
||||
|
||||
CLASS lhc_changeapproval DEFINITION INHERITING FROM cl_abap_behavior_handler.
|
||||
PRIVATE SECTION.
|
||||
|
||||
CONSTANTS:
|
||||
BEGIN OF status,
|
||||
pending TYPE zzchngpproval000-status VALUE 'PENDING',
|
||||
approved TYPE zzchngpproval000-status VALUE 'APPROVED',
|
||||
executing TYPE zzchngpproval000-status VALUE 'EXECUTING',
|
||||
synced TYPE zzchngpproval000-status VALUE 'SYNCED',
|
||||
rejected TYPE zzchngpproval000-status VALUE 'REJECTED',
|
||||
failed TYPE zzchngpproval000-status VALUE 'FAILED',
|
||||
END OF status.
|
||||
|
||||
METHODS get_instance_features FOR INSTANCE FEATURES
|
||||
IMPORTING keys REQUEST requested_features FOR ChangeApproval RESULT result.
|
||||
|
||||
METHODS approve FOR MODIFY
|
||||
IMPORTING keys FOR ACTION ChangeApproval~approve RESULT result.
|
||||
|
||||
METHODS reject FOR MODIFY
|
||||
IMPORTING keys FOR ACTION ChangeApproval~reject RESULT result.
|
||||
|
||||
METHODS retrySync FOR MODIFY
|
||||
IMPORTING keys FOR ACTION ChangeApproval~retrySync RESULT result.
|
||||
|
||||
METHODS markExecuting FOR MODIFY
|
||||
IMPORTING keys FOR ACTION ChangeApproval~markExecuting RESULT result.
|
||||
|
||||
METHODS markSynced FOR MODIFY
|
||||
IMPORTING keys FOR ACTION ChangeApproval~markSynced RESULT result.
|
||||
|
||||
METHODS markFailed FOR MODIFY
|
||||
IMPORTING keys FOR ACTION ChangeApproval~markFailed RESULT result.
|
||||
|
||||
METHODS setInitialStatus FOR DETERMINE ON MODIFY
|
||||
IMPORTING keys FOR ChangeApproval~setInitialStatus.
|
||||
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
CLASS lhc_changeapproval IMPLEMENTATION.
|
||||
|
||||
METHOD get_instance_features.
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
FIELDS ( Status )
|
||||
WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(approvals)
|
||||
FAILED failed.
|
||||
|
||||
result = VALUE #( FOR approval IN approvals
|
||||
( %tky = approval-%tky
|
||||
%features-%action-approve = COND #( WHEN approval-Status = status-pending
|
||||
THEN if_abap_behv=>fc-o-enabled
|
||||
ELSE if_abap_behv=>fc-o-disabled )
|
||||
%features-%action-reject = COND #( WHEN approval-Status = status-pending
|
||||
THEN if_abap_behv=>fc-o-enabled
|
||||
ELSE if_abap_behv=>fc-o-disabled )
|
||||
%features-%action-retrySync = COND #( WHEN approval-Status = status-failed
|
||||
THEN if_abap_behv=>fc-o-enabled
|
||||
ELSE if_abap_behv=>fc-o-disabled )
|
||||
%features-%action-markExecuting = COND #( WHEN approval-Status = status-approved
|
||||
THEN if_abap_behv=>fc-o-enabled
|
||||
ELSE if_abap_behv=>fc-o-disabled )
|
||||
%features-%action-markSynced = COND #( WHEN approval-Status = status-executing
|
||||
THEN if_abap_behv=>fc-o-enabled
|
||||
ELSE if_abap_behv=>fc-o-disabled )
|
||||
%features-%action-markFailed = COND #( WHEN approval-Status = status-executing
|
||||
THEN if_abap_behv=>fc-o-enabled
|
||||
ELSE if_abap_behv=>fc-o-disabled ) ) ).
|
||||
ENDMETHOD.
|
||||
|
||||
|
||||
METHOD approve.
|
||||
" PENDING -> APPROVED; records the decision, never writes SapChangeNumber (PRD RAP-1)
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
FIELDS ( Status )
|
||||
WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(approvals)
|
||||
FAILED failed.
|
||||
|
||||
LOOP AT keys INTO DATA(key).
|
||||
ASSIGN approvals[ ID = key-ID ] TO FIELD-SYMBOL(<approval>).
|
||||
IF sy-subrc <> 0.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
IF <approval>-Status <> status-pending.
|
||||
APPEND VALUE #( %tky = <approval>-%tky ) TO failed-changeapproval.
|
||||
APPEND VALUE #( %tky = <approval>-%tky
|
||||
%msg = new_message_with_text(
|
||||
severity = if_abap_behv_message=>severity-error
|
||||
text = |Only PENDING records can be approved (status is { <approval>-Status })| ) )
|
||||
TO reported-changeapproval.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
MODIFY ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
UPDATE FIELDS ( Status DecidedBy DecidedOn )
|
||||
WITH VALUE #( ( %tky = <approval>-%tky
|
||||
Status = status-approved
|
||||
DecidedBy = cl_abap_context_info=>get_user_technical_name( )
|
||||
DecidedOn = utclong_current( ) ) )
|
||||
FAILED DATA(update_failed)
|
||||
REPORTED DATA(update_reported).
|
||||
ENDLOOP.
|
||||
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
ALL FIELDS WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(updated).
|
||||
|
||||
result = VALUE #( FOR row IN updated ( %tky = row-%tky %param = row ) ).
|
||||
ENDMETHOD.
|
||||
|
||||
|
||||
METHOD reject.
|
||||
" PENDING -> REJECTED with a mandatory reason (PRD RAP-2); REJECTED is terminal
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
FIELDS ( Status )
|
||||
WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(approvals)
|
||||
FAILED failed.
|
||||
|
||||
LOOP AT keys INTO DATA(key).
|
||||
ASSIGN approvals[ ID = key-ID ] TO FIELD-SYMBOL(<approval>).
|
||||
IF sy-subrc <> 0.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
IF <approval>-Status <> status-pending.
|
||||
APPEND VALUE #( %tky = <approval>-%tky ) TO failed-changeapproval.
|
||||
APPEND VALUE #( %tky = <approval>-%tky
|
||||
%msg = new_message_with_text(
|
||||
severity = if_abap_behv_message=>severity-error
|
||||
text = |Only PENDING records can be rejected (status is { <approval>-Status })| ) )
|
||||
TO reported-changeapproval.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
IF key-%param-RejectReason IS INITIAL.
|
||||
APPEND VALUE #( %tky = <approval>-%tky ) TO failed-changeapproval.
|
||||
APPEND VALUE #( %tky = <approval>-%tky
|
||||
%msg = new_message_with_text(
|
||||
severity = if_abap_behv_message=>severity-error
|
||||
text = 'A reject reason is required' ) )
|
||||
TO reported-changeapproval.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
MODIFY ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
UPDATE FIELDS ( Status RejectReason DecidedBy DecidedOn )
|
||||
WITH VALUE #( ( %tky = <approval>-%tky
|
||||
Status = status-rejected
|
||||
RejectReason = key-%param-RejectReason
|
||||
DecidedBy = cl_abap_context_info=>get_user_technical_name( )
|
||||
DecidedOn = utclong_current( ) ) )
|
||||
FAILED DATA(update_failed)
|
||||
REPORTED DATA(update_reported).
|
||||
ENDLOOP.
|
||||
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
ALL FIELDS WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(updated).
|
||||
|
||||
result = VALUE #( FOR row IN updated ( %tky = row-%tky %param = row ) ).
|
||||
ENDMETHOD.
|
||||
|
||||
|
||||
METHOD retrySync.
|
||||
" FAILED -> EXECUTING; clears the previous error so the worker re-executes the staged payload (ARN-002 amendment)
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
FIELDS ( Status )
|
||||
WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(approvals)
|
||||
FAILED failed.
|
||||
|
||||
LOOP AT keys INTO DATA(key).
|
||||
ASSIGN approvals[ ID = key-ID ] TO FIELD-SYMBOL(<approval>).
|
||||
IF sy-subrc <> 0.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
IF <approval>-Status <> status-failed.
|
||||
APPEND VALUE #( %tky = <approval>-%tky ) TO failed-changeapproval.
|
||||
APPEND VALUE #( %tky = <approval>-%tky
|
||||
%msg = new_message_with_text(
|
||||
severity = if_abap_behv_message=>severity-error
|
||||
text = |Only FAILED records can be retried (status is { <approval>-Status })| ) )
|
||||
TO reported-changeapproval.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
MODIFY ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
UPDATE FIELDS ( Status ErrorMessage )
|
||||
WITH VALUE #( ( %tky = <approval>-%tky
|
||||
Status = status-executing
|
||||
ErrorMessage = '' ) )
|
||||
FAILED DATA(update_failed)
|
||||
REPORTED DATA(update_reported).
|
||||
ENDLOOP.
|
||||
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
ALL FIELDS WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(updated).
|
||||
|
||||
result = VALUE #( FOR row IN updated ( %tky = row-%tky %param = row ) ).
|
||||
ENDMETHOD.
|
||||
|
||||
|
||||
METHOD markExecuting.
|
||||
" APPROVED -> EXECUTING (worker claims the record; the UI never offers Approve on an executing record, PRD RAP-6)
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
FIELDS ( Status )
|
||||
WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(approvals)
|
||||
FAILED failed.
|
||||
|
||||
LOOP AT keys INTO DATA(key).
|
||||
ASSIGN approvals[ ID = key-ID ] TO FIELD-SYMBOL(<approval>).
|
||||
IF sy-subrc <> 0.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
IF <approval>-Status <> status-approved.
|
||||
APPEND VALUE #( %tky = <approval>-%tky ) TO failed-changeapproval.
|
||||
APPEND VALUE #( %tky = <approval>-%tky
|
||||
%msg = new_message_with_text(
|
||||
severity = if_abap_behv_message=>severity-error
|
||||
text = |Only APPROVED records can start executing (status is { <approval>-Status })| ) )
|
||||
TO reported-changeapproval.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
MODIFY ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
UPDATE FIELDS ( Status )
|
||||
WITH VALUE #( ( %tky = <approval>-%tky
|
||||
Status = status-executing ) )
|
||||
FAILED DATA(update_failed)
|
||||
REPORTED DATA(update_reported).
|
||||
ENDLOOP.
|
||||
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
ALL FIELDS WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(updated).
|
||||
|
||||
result = VALUE #( FOR row IN updated ( %tky = row-%tky %param = row ) ).
|
||||
ENDMETHOD.
|
||||
|
||||
|
||||
METHOD markSynced.
|
||||
" EXECUTING -> SYNCED (terminal success); SAP is the ledger, the change number is the receipt (ARN-006)
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
FIELDS ( Status )
|
||||
WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(approvals)
|
||||
FAILED failed.
|
||||
|
||||
LOOP AT keys INTO DATA(key).
|
||||
ASSIGN approvals[ ID = key-ID ] TO FIELD-SYMBOL(<approval>).
|
||||
IF sy-subrc <> 0.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
IF <approval>-Status <> status-executing.
|
||||
APPEND VALUE #( %tky = <approval>-%tky ) TO failed-changeapproval.
|
||||
APPEND VALUE #( %tky = <approval>-%tky
|
||||
%msg = new_message_with_text(
|
||||
severity = if_abap_behv_message=>severity-error
|
||||
text = |Only EXECUTING records can be marked synced (status is { <approval>-Status })| ) )
|
||||
TO reported-changeapproval.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
IF key-%param-SapChangeNumber IS INITIAL.
|
||||
APPEND VALUE #( %tky = <approval>-%tky ) TO failed-changeapproval.
|
||||
APPEND VALUE #( %tky = <approval>-%tky
|
||||
%msg = new_message_with_text(
|
||||
severity = if_abap_behv_message=>severity-error
|
||||
text = 'The SAP change number is required to mark a record synced' ) )
|
||||
TO reported-changeapproval.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
MODIFY ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
UPDATE FIELDS ( Status SapChangeNumber ErrorMessage )
|
||||
WITH VALUE #( ( %tky = <approval>-%tky
|
||||
Status = status-synced
|
||||
SapChangeNumber = key-%param-SapChangeNumber
|
||||
ErrorMessage = '' ) )
|
||||
FAILED DATA(update_failed)
|
||||
REPORTED DATA(update_reported).
|
||||
ENDLOOP.
|
||||
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
ALL FIELDS WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(updated).
|
||||
|
||||
result = VALUE #( FOR row IN updated ( %tky = row-%tky %param = row ) ).
|
||||
ENDMETHOD.
|
||||
|
||||
|
||||
METHOD markFailed.
|
||||
" EXECUTING -> FAILED with the error text; distinct from REJECTED (predecessor defect, ARN-002)
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
FIELDS ( Status )
|
||||
WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(approvals)
|
||||
FAILED failed.
|
||||
|
||||
LOOP AT keys INTO DATA(key).
|
||||
ASSIGN approvals[ ID = key-ID ] TO FIELD-SYMBOL(<approval>).
|
||||
IF sy-subrc <> 0.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
IF <approval>-Status <> status-executing.
|
||||
APPEND VALUE #( %tky = <approval>-%tky ) TO failed-changeapproval.
|
||||
APPEND VALUE #( %tky = <approval>-%tky
|
||||
%msg = new_message_with_text(
|
||||
severity = if_abap_behv_message=>severity-error
|
||||
text = |Only EXECUTING records can be marked failed (status is { <approval>-Status })| ) )
|
||||
TO reported-changeapproval.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
IF key-%param-ErrorMessage IS INITIAL.
|
||||
APPEND VALUE #( %tky = <approval>-%tky ) TO failed-changeapproval.
|
||||
APPEND VALUE #( %tky = <approval>-%tky
|
||||
%msg = new_message_with_text(
|
||||
severity = if_abap_behv_message=>severity-error
|
||||
text = 'An error message is required to mark a record failed' ) )
|
||||
TO reported-changeapproval.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
|
||||
MODIFY ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
UPDATE FIELDS ( Status ErrorMessage )
|
||||
WITH VALUE #( ( %tky = <approval>-%tky
|
||||
Status = status-failed
|
||||
ErrorMessage = key-%param-ErrorMessage ) )
|
||||
FAILED DATA(update_failed)
|
||||
REPORTED DATA(update_reported).
|
||||
ENDLOOP.
|
||||
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
ALL FIELDS WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(updated).
|
||||
|
||||
result = VALUE #( FOR row IN updated ( %tky = row-%tky %param = row ) ).
|
||||
ENDMETHOD.
|
||||
|
||||
|
||||
METHOD setInitialStatus.
|
||||
" Every created record starts PENDING with the requester audit fields (ARN-002)
|
||||
READ ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
FIELDS ( Status )
|
||||
WITH CORRESPONDING #( keys )
|
||||
RESULT DATA(approvals).
|
||||
|
||||
DELETE approvals WHERE Status IS NOT INITIAL.
|
||||
IF approvals IS INITIAL.
|
||||
RETURN.
|
||||
ENDIF.
|
||||
|
||||
MODIFY ENTITIES OF zzr_changeapproval000 IN LOCAL MODE
|
||||
ENTITY ChangeApproval
|
||||
UPDATE FIELDS ( Status RequestedBy RequestedOn )
|
||||
WITH VALUE #( FOR approval IN approvals
|
||||
( %tky = approval-%tky
|
||||
Status = status-pending
|
||||
RequestedBy = cl_abap_context_info=>get_user_technical_name( )
|
||||
RequestedOn = utclong_current( ) ) )
|
||||
REPORTED DATA(update_reported).
|
||||
|
||||
reported = CORRESPONDING #( DEEP update_reported ).
|
||||
ENDMETHOD.
|
||||
|
||||
ENDCLASS.
|
||||
@@ -0,0 +1,20 @@
|
||||
// TARGET OBJECT : behavior definition ZZC_CHANGEAPPROVAL000 (UI projection BDEF; generated 2026-09-15)
|
||||
// abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Behavior%20Definitions/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.bdef.json
|
||||
// ACTION : replace entire content, then activate (after ZZR_CHANGEAPPROVAL000 BDEF + ZZC_CHANGEAPPROVAL000 view).
|
||||
// Then DELETE the generated class ZZBP_C_CHANGEAPPROVAL000 in ADT: a projection BDEF needs no behavior
|
||||
// pool unless it defines new actions/functions, and this one reuses everything
|
||||
// [source: abap-docs /abap-docs-cloud/ABENBDL_BDEF_PROJECTION_HEADER, verified 2026-09-15].
|
||||
// Sources (verified 2026-09-15): use action / use etag; no automatic inheritance - only what is listed is exposed,
|
||||
// which is how create/update/delete and the worker actions are kept out of the UI service (PRD RAP-2)
|
||||
// [abap-docs /abap-docs-cloud/ABENBDL_USE_PROJECTION]. Feature control of reused actions is passed on automatically (same source).
|
||||
projection;
|
||||
strict ( 2 );
|
||||
|
||||
define behavior for ZZC_CHANGEAPPROVAL000 alias ChangeApproval
|
||||
{
|
||||
use etag;
|
||||
|
||||
use action approve;
|
||||
use action reject;
|
||||
use action retrySync;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/* TARGET OBJECT : access control ZZC_CHANGEAPPROVAL000 (generated 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Access%20Controls/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.dcls.acds
|
||||
ACTION : replace entire content, then activate (after ZZR_CHANGEAPPROVAL000 DCL).
|
||||
A transactional query needs its own DCL, inheriting the base view's conditions - there is no implicit inheritance
|
||||
[source: abap-docs /abap-platform-rap-opensap/week2/unit7#step-5-create-cds-access-control-for-travel-bo-projection-view-and-check-the-result;
|
||||
/abap-docs-cloud/ABENCDS_DEFINE_VIEW_AS_PROJECTION (access control must be symmetric), verified 2026-09-15]. */
|
||||
@EndUserText.label: 'Access control for ZZC_CHANGEAPPROVAL000'
|
||||
@MappingRole: true
|
||||
define role ZZC_CHANGEAPPROVAL000 {
|
||||
grant select on ZZC_CHANGEAPPROVAL000
|
||||
where inheriting conditions from entity ZZR_CHANGEAPPROVAL000;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/* TARGET OBJECT : data definition ZZC_CHANGEAPPROVAL000 (UI projection, generated 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.ddls.acds
|
||||
ACTION : replace entire content, then activate (after ZZR_CHANGEAPPROVAL000).
|
||||
Notes: provider contract transactional_query [source: abap-docs /abap-docs-cloud/ABENCDS_DEFINE_VIEW_AS_PROJECTION, verified 2026-09-15];
|
||||
@ObjectModel.semanticKey (PRD RAP-8) [source: abap-docs /abap-fiori-showcase/05_object_page_header#handling-semantic-key-fields, verified 2026-09-15];
|
||||
@Metadata.allowExtensions is required for the metadata extension [source: abap-docs /abap-docs-cloud/ABENCDS_F1_ANNOTATE_VIEW, verified 2026-09-15]. */
|
||||
@EndUserText.label: 'Arena change approval - UI projection'
|
||||
@AccessControl.authorizationCheck: #CHECK
|
||||
@Metadata.allowExtensions: true
|
||||
@ObjectModel.semanticKey: ['ItemNumber', 'ChangeType', 'ArenaEcoId']
|
||||
define root view entity ZZC_CHANGEAPPROVAL000
|
||||
provider contract transactional_query
|
||||
as projection on ZZR_CHANGEAPPROVAL000
|
||||
{
|
||||
key ID,
|
||||
ItemNumber,
|
||||
ItemName,
|
||||
ChangeType,
|
||||
ArenaEcoId,
|
||||
@ObjectModel.text.element: ['StatusText']
|
||||
Status,
|
||||
StatusText,
|
||||
StatusCriticality,
|
||||
RequestedBy,
|
||||
RequestedOn,
|
||||
DecidedBy,
|
||||
DecidedOn,
|
||||
SapChangeNumber,
|
||||
ErrorMessage,
|
||||
RejectReason,
|
||||
SapPreview,
|
||||
IsApprovable,
|
||||
IsRetriable,
|
||||
LocalLastChangedAt
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/* TARGET OBJECT : metadata extension ZZC_CHANGEAPPROVAL000 (generated 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Metadata%20Extensions/ZZC_CHANGEAPPROVAL000/zzc_changeapproval000.ddlx.acds
|
||||
ACTION : replace entire content, then activate (after ZZC_CHANGEAPPROVAL000 view).
|
||||
Mirrors app/webapp/annotations/annotation.xml (line items, filter bar, header, facets, actions); the app's local
|
||||
annotations still apply on top at runtime. Labels are literals here; the app carries the i18n texts.
|
||||
Sources (all verified 2026-09-15, abap-docs /abap-fiori-showcase):
|
||||
@Metadata.layer + ANNOTATE ENTITY [abap-docs /abap-docs-cloud/ABENCDS_F1_ANNOTATE_VIEW]
|
||||
@UI.headerInfo typeName/typeNamePlural/typeImageUrl/title/description [05_object_page_header#title-and-subtitle]
|
||||
@UI.presentationVariant sortOrder + visualizations [03_list_report_content (Defining the Default Sort Order)]
|
||||
@UI.facet purpose/type/id/label/position/targetQualifier [06_object_page_content (Nested Tabs, RAPTreeview)]
|
||||
@UI.dataPoint qualifier/title/criticality + #DATAPOINT_REFERENCE header facet [05_object_page_header (Key Value, Progress)]
|
||||
@UI.identification #FOR_ACTION dataAction/label [05_object_page_header (Regular Actions)]
|
||||
@UI.lineItem position/importance/criticality [03_list_report_content (Configuring Tables); 06 (Table)]
|
||||
@UI.selectionField position [02_list_report_header#selection-fields]
|
||||
@UI.fieldGroup qualifier/position [06_object_page_content (Multi Input Field)]
|
||||
@UI.textArrangement #TEXT_ONLY [06_object_page_content#displaying-text-instead-of-id]
|
||||
@UI.multiLineText [05_object_page_header (Plain Text)]; @UI.hidden [06_object_page_content (Hiding Features)]
|
||||
Default filter Status = PENDING is NOT set here (string-literal escaping inside @UI.selectionVariant.filter is
|
||||
unverified); the app's annotation.xml SelectionVariant#Default provides it. */
|
||||
@Metadata.layer: #CUSTOMER
|
||||
@UI: {
|
||||
headerInfo: {
|
||||
typeName: 'Change Approval',
|
||||
typeNamePlural: 'Change Approvals',
|
||||
typeImageUrl: 'sap-icon://approvals',
|
||||
title: { type: #STANDARD, value: 'ItemNumber' },
|
||||
description: { type: #STANDARD, value: 'ItemName' }
|
||||
},
|
||||
presentationVariant: [ {
|
||||
sortOrder: [ { by: 'Status', direction: #ASC }, { by: 'RequestedOn', direction: #DESC } ],
|
||||
visualizations: [ { type: #AS_LINEITEM } ]
|
||||
} ]
|
||||
}
|
||||
annotate entity ZZC_CHANGEAPPROVAL000 with
|
||||
{
|
||||
@UI.facet: [
|
||||
{ id: 'StatusPoint', purpose: #HEADER, type: #DATAPOINT_REFERENCE, targetQualifier: 'StatusPoint' },
|
||||
{ id: 'Keys', purpose: #HEADER, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Keys', label: 'Reference numbers' },
|
||||
{ id: 'Change', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Change', label: 'Change', position: 10 },
|
||||
{ id: 'Payload', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Payload', label: 'Staged payload', position: 20 },
|
||||
{ id: 'Approval', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Approval', label: 'Approval', position: 30 },
|
||||
{ id: 'Execution', purpose: #STANDARD, type: #FIELDGROUP_REFERENCE, targetQualifier: 'Execution', label: 'Execution', position: 40 }
|
||||
]
|
||||
@UI.identification: [
|
||||
{ position: 10, type: #FOR_ACTION, dataAction: 'approve', label: 'Approve' },
|
||||
{ position: 20, type: #FOR_ACTION, dataAction: 'reject', label: 'Reject' },
|
||||
{ position: 30, type: #FOR_ACTION, dataAction: 'retrySync', label: 'Retry sync' }
|
||||
]
|
||||
@UI.hidden: true
|
||||
ID;
|
||||
|
||||
@UI: {
|
||||
lineItem: [ { position: 10, importance: #HIGH } ],
|
||||
selectionField: [ { position: 10 } ],
|
||||
fieldGroup: [ { qualifier: 'Change', position: 10 } ]
|
||||
}
|
||||
@EndUserText.label: 'Item number'
|
||||
ItemNumber;
|
||||
|
||||
@UI: {
|
||||
lineItem: [ { position: 20, importance: #LOW } ],
|
||||
fieldGroup: [ { qualifier: 'Change', position: 20 } ]
|
||||
}
|
||||
@EndUserText.label: 'Item name'
|
||||
ItemName;
|
||||
|
||||
@UI: {
|
||||
lineItem: [ { position: 30, importance: #HIGH } ],
|
||||
selectionField: [ { position: 30 } ],
|
||||
fieldGroup: [ { qualifier: 'Change', position: 30 } ]
|
||||
}
|
||||
@EndUserText.label: 'Change type'
|
||||
ChangeType;
|
||||
|
||||
@UI: {
|
||||
lineItem: [ { position: 60, importance: #MEDIUM } ],
|
||||
selectionField: [ { position: 40 } ],
|
||||
fieldGroup: [ { qualifier: 'Change', position: 40 }, { qualifier: 'Keys', position: 10 } ]
|
||||
}
|
||||
@EndUserText.label: 'Arena ECO'
|
||||
ArenaEcoId;
|
||||
|
||||
@UI: {
|
||||
lineItem: [ { position: 40, importance: #HIGH, criticality: 'StatusCriticality' } ],
|
||||
selectionField: [ { position: 20 } ],
|
||||
fieldGroup: [ { qualifier: 'Approval', position: 10, criticality: 'StatusCriticality' } ],
|
||||
dataPoint: { qualifier: 'StatusPoint', title: 'Status', criticality: 'StatusCriticality' },
|
||||
textArrangement: #TEXT_ONLY
|
||||
}
|
||||
@EndUserText.label: 'Status'
|
||||
Status;
|
||||
|
||||
@UI.hidden: true
|
||||
StatusText;
|
||||
|
||||
@UI.hidden: true
|
||||
StatusCriticality;
|
||||
|
||||
@UI.fieldGroup: [ { qualifier: 'Approval', position: 20 } ]
|
||||
@EndUserText.label: 'Requested by'
|
||||
RequestedBy;
|
||||
|
||||
@UI: {
|
||||
lineItem: [ { position: 50, importance: #MEDIUM } ],
|
||||
fieldGroup: [ { qualifier: 'Approval', position: 30 } ]
|
||||
}
|
||||
@EndUserText.label: 'Requested on'
|
||||
RequestedOn;
|
||||
|
||||
@UI.fieldGroup: [ { qualifier: 'Approval', position: 40 } ]
|
||||
@EndUserText.label: 'Decided by'
|
||||
DecidedBy;
|
||||
|
||||
@UI.fieldGroup: [ { qualifier: 'Approval', position: 50 } ]
|
||||
@EndUserText.label: 'Decided on'
|
||||
DecidedOn;
|
||||
|
||||
@UI.fieldGroup: [ { qualifier: 'Approval', position: 60 } ]
|
||||
@EndUserText.label: 'Reject reason'
|
||||
RejectReason;
|
||||
|
||||
@UI.fieldGroup: [ { qualifier: 'Execution', position: 10 }, { qualifier: 'Keys', position: 20 } ]
|
||||
@EndUserText.label: 'SAP change number'
|
||||
SapChangeNumber;
|
||||
|
||||
@UI.fieldGroup: [ { qualifier: 'Execution', position: 20 } ]
|
||||
@EndUserText.label: 'Error message'
|
||||
ErrorMessage;
|
||||
|
||||
@UI: {
|
||||
fieldGroup: [ { qualifier: 'Payload', position: 10 } ],
|
||||
multiLineText: true
|
||||
}
|
||||
@EndUserText.label: 'Staged payload'
|
||||
SapPreview;
|
||||
|
||||
@UI.hidden: true
|
||||
IsApprovable;
|
||||
|
||||
@UI.hidden: true
|
||||
IsRetriable;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/* TARGET OBJECT : database table ZZCHNGPPROVAL000 (generated 2026-09-15 by x-ui-service)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Dictionary/Database%20Tables/ZZCHNGPPROVAL000/zzchngpproval000.tabl.json
|
||||
ACTION : replace entire content, then activate.
|
||||
Notes: sap_preview is abap.string(0) (RAP-7; char is capped at 1333 for table fields
|
||||
[source: abap-docs /abap-docs-cloud/ABENDDIC_BUILTIN_TYPES, verified 2026-09-15];
|
||||
abap.string(0) table-field syntax [source: abap-docs /abap-docs-cloud/ABENDDICDDL_DEFINE_TABLE_COMPS, verified 2026-09-15]).
|
||||
Timestamps are abap.utclong (UTCLONG built-in type, same source). Admin fields use the released
|
||||
ABP_* data elements and SYSUUID_X16 [source: sap-released-objects public_cloud level A, verified 2026-09-15]. */
|
||||
@EndUserText.label : 'Arena change approval (staging + state machine)'
|
||||
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
|
||||
@AbapCatalog.tableCategory : #TRANSPARENT
|
||||
@AbapCatalog.deliveryClass : #A
|
||||
@AbapCatalog.dataMaintenance : #RESTRICTED
|
||||
define table zzchngpproval000 {
|
||||
key client : abap.clnt not null;
|
||||
key id : sysuuid_x16 not null;
|
||||
item_number : abap.char(18);
|
||||
item_name : abap.char(40);
|
||||
change_type : abap.char(15);
|
||||
arena_eco_id : abap.char(20);
|
||||
status : abap.char(10);
|
||||
requested_by : abap.char(12);
|
||||
requested_on : abap.utclong;
|
||||
decided_by : abap.char(12);
|
||||
decided_on : abap.utclong;
|
||||
sap_change_number : abap.char(12);
|
||||
error_message : abap.char(255);
|
||||
reject_reason : abap.char(255);
|
||||
sap_preview : abap.string(0);
|
||||
created_by : abp_creation_user;
|
||||
created_at : abp_creation_tstmpl;
|
||||
last_changed_by : abp_lastchange_user;
|
||||
last_changed_at : abp_lastchange_tstmpl;
|
||||
local_last_changed_at : abp_locinst_lastchange_tstmpl;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// TARGET OBJECT : behavior definition ZZR_CHANGEAPPROVAL000 (base BDEF, managed; generated 2026-09-15)
|
||||
// abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Behavior%20Definitions/ZZR_CHANGEAPPROVAL000/zzr_changeapproval000.bdef.json
|
||||
// ACTION : replace entire content, then activate (after the three ZD_* abstract entities and ZZR_CHANGEAPPROVAL000).
|
||||
// Sources (all verified 2026-09-15):
|
||||
// action syntax incl. ( features : instance ), parameter, result [1] $self
|
||||
// [abap-docs /abap-docs-cloud/ABENBDL_ACTION, ABENBDL_ACTIONS_FC, ABENBDL_ACTION_INPUT_PARAM, ABENBDL_ACTION2_ABEXA]
|
||||
// internal operations (usable only from the behavior pool) [abap-docs /abap-docs-cloud/ABENBDL_INTERNAL]
|
||||
// field ( readonly, numbering : managed ) for a UUID key [abap-docs /abap-docs-cloud/ABENBDL_FIELD_NUMBERING; /abap-fiori-showcase/01_general_features#readonly]
|
||||
// field ( readonly : update, mandatory : create ) combination [abap-docs /abap-fiori-showcase/06_object_page_content (StreamIsReadOnly)]
|
||||
// determination on modify { create; } sets the initial status [abap-docs /abap-docs-cloud/ABENBDL_DETERMINATIONS (setStatustoNew)]
|
||||
// readonly fields written by determinations/actions IN LOCAL MODE [same source: field ( readonly ) AmountSum + TotalPrice determination]
|
||||
// etag master [abap-docs /abap-docs-cloud/ABENBDL_ETAG]; explicit mapping because CDS aliases differ from table fields [abap-docs /abap-docs-cloud/ABENBDL_TYPE_MAPPING]
|
||||
// authorization master ( none ): "no authorization checks for the entire RAP BO" - access is governed exclusively by the
|
||||
// IAM app / business catalog (ADR-002, ARN-007) and read access by DCL [abap-docs /abap-docs-cloud/ABENBDL_AUTHORIZATION]
|
||||
// Open point (falsifiable at activation): StatusText/StatusCriticality/IsApprovable/IsRetriable are CDS-calculated and
|
||||
// deliberately absent from the mapping. ABENBDL_TYPE_MAPPING only requires a mapping where table and entity field
|
||||
// NAMES differ; it is silent on calculated elements. If activation reports an error (not a warning) for the unmapped
|
||||
// elements, fall back to persisting them (add the four columns to the table + mapping) and maintain them in the actions.
|
||||
managed implementation in class zzbp_r_changeapproval000 unique;
|
||||
strict ( 2 );
|
||||
|
||||
define behavior for ZZR_CHANGEAPPROVAL000 alias ChangeApproval
|
||||
persistent table zzchngpproval000
|
||||
lock master
|
||||
authorization master ( none )
|
||||
etag master LocalLastChangedAt
|
||||
{
|
||||
create;
|
||||
internal update;
|
||||
|
||||
field ( readonly, numbering : managed ) ID;
|
||||
field ( readonly : update, mandatory : create ) ItemNumber, ChangeType, ArenaEcoId;
|
||||
field ( mandatory : create ) SapPreview;
|
||||
field ( readonly ) Status, StatusText, StatusCriticality, IsApprovable, IsRetriable,
|
||||
RequestedBy, RequestedOn, DecidedBy, DecidedOn,
|
||||
SapChangeNumber, ErrorMessage, RejectReason,
|
||||
CreatedBy, CreatedAt, LastChangedBy, LastChangedAt, LocalLastChangedAt;
|
||||
|
||||
// Business-user actions (UI projection): PENDING -> APPROVED | REJECTED, FAILED -> EXECUTING (PRD RAP-1/RAP-2)
|
||||
action ( features : instance ) approve result [1] $self;
|
||||
action ( features : instance ) reject parameter ZD_CHANGEAPPROVAL_REJECTP result [1] $self;
|
||||
action ( features : instance ) retrySync result [1] $self;
|
||||
|
||||
// Worker actions (A2X projection): APPROVED -> EXECUTING -> SYNCED | FAILED (PRD RAP-6)
|
||||
action ( features : instance ) markExecuting result [1] $self;
|
||||
action ( features : instance ) markSynced parameter ZD_CHANGEAPPROVAL_SYNCEDP result [1] $self;
|
||||
action ( features : instance ) markFailed parameter ZD_CHANGEAPPROVAL_FAILEDP result [1] $self;
|
||||
|
||||
determination setInitialStatus on modify { create; }
|
||||
|
||||
mapping for zzchngpproval000
|
||||
{
|
||||
ID = id;
|
||||
ItemNumber = item_number;
|
||||
ItemName = item_name;
|
||||
ChangeType = change_type;
|
||||
ArenaEcoId = arena_eco_id;
|
||||
Status = status;
|
||||
RequestedBy = requested_by;
|
||||
RequestedOn = requested_on;
|
||||
DecidedBy = decided_by;
|
||||
DecidedOn = decided_on;
|
||||
SapChangeNumber = sap_change_number;
|
||||
ErrorMessage = error_message;
|
||||
RejectReason = reject_reason;
|
||||
SapPreview = sap_preview;
|
||||
CreatedBy = created_by;
|
||||
CreatedAt = created_at;
|
||||
LastChangedBy = last_changed_by;
|
||||
LastChangedAt = last_changed_at;
|
||||
LocalLastChangedAt = local_last_changed_at;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/* TARGET OBJECT : access control ZZR_CHANGEAPPROVAL000 (generated 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Access%20Controls/ZZR_CHANGEAPPROVAL000/zzr_changeapproval000.dcls.acds
|
||||
ACTION : replace entire content, then activate.
|
||||
Full access rule: read access is governed by the IAM app / business catalog (ADR-002); SAP delivers no full-access
|
||||
roles but customers may use them [source: abap-docs /abap-docs-cloud/ABENCDS_DCL_ROLE_GRANT_RULE, verified 2026-09-15].
|
||||
@MappingRole: true assigns the role to every user [source: abap-docs /abap-platform-rap-opensap/week2/unit7, verified 2026-09-15].
|
||||
Tighten later with a custom authorization object + pfcg_auth condition if per-user data restrictions are needed. */
|
||||
@EndUserText.label: 'Access control for ZZR_CHANGEAPPROVAL000'
|
||||
@MappingRole: true
|
||||
define role ZZR_CHANGEAPPROVAL000 {
|
||||
grant select on ZZR_CHANGEAPPROVAL000;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/* TARGET OBJECT : data definition ZZR_CHANGEAPPROVAL000 (root view entity, generated 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Core%20Data%20Services/Data%20Definitions/ZZR_CHANGEAPPROVAL000/zzr_changeapproval000.ddls.acds
|
||||
ACTION : replace entire content, then activate (table ZZCHNGPPROVAL000 must be active first).
|
||||
Notes: StatusText / StatusCriticality / IsApprovable / IsRetriable are derived from Status with CASE
|
||||
expressions here, because a transactional_query projection list may only contain elements of the
|
||||
projected entity, path expressions, associations and virtual elements - no expressions
|
||||
[source: abap-docs /abap-docs-cloud/ABENCDS_DEFINE_VIEW_AS_PROJECTION, verified 2026-09-15].
|
||||
CASE syntax [source: abap-docs /abap-docs-cloud/ABENCDS_CASE_EXPRESSION_V2, verified 2026-09-15];
|
||||
cast of a literal to a data element (abap_boolean, released) [source: abap-docs /abap-docs-cloud/ABENCDS_CAST_EXPRESSION_V2, verified 2026-09-15].
|
||||
@ObjectModel.text.element [source: abap-docs /abap-fiori-showcase/06_object_page_content#displaying-text-instead-of-id, verified 2026-09-15].
|
||||
@Semantics admin-field annotations [source: abap-docs /abap-platform-rap-opensap/week2/unit3#step-1-create-the-interface-cds-view-for-the-travel-entity, verified 2026-09-15].
|
||||
Criticality values 2/2/5/3/1/1 per PRD RAP-1. */
|
||||
@AccessControl.authorizationCheck: #CHECK
|
||||
@EndUserText.label: 'Arena change approval'
|
||||
define root view entity ZZR_CHANGEAPPROVAL000
|
||||
as select from zzchngpproval000
|
||||
{
|
||||
key id as ID,
|
||||
item_number as ItemNumber,
|
||||
item_name as ItemName,
|
||||
change_type as ChangeType,
|
||||
arena_eco_id as ArenaEcoId,
|
||||
|
||||
@ObjectModel.text.element: ['StatusText']
|
||||
status as Status,
|
||||
|
||||
case status
|
||||
when 'PENDING' then 'Pending approval'
|
||||
when 'APPROVED' then 'Approved - awaiting execution'
|
||||
when 'EXECUTING' then 'Executing in SAP'
|
||||
when 'SYNCED' then 'Synced to SAP'
|
||||
when 'REJECTED' then 'Rejected'
|
||||
when 'FAILED' then 'Execution failed'
|
||||
else status
|
||||
end as StatusText,
|
||||
|
||||
case status
|
||||
when 'PENDING' then 2
|
||||
when 'APPROVED' then 2
|
||||
when 'EXECUTING' then 5
|
||||
when 'SYNCED' then 3
|
||||
when 'REJECTED' then 1
|
||||
when 'FAILED' then 1
|
||||
else 0
|
||||
end as StatusCriticality,
|
||||
|
||||
requested_by as RequestedBy,
|
||||
requested_on as RequestedOn,
|
||||
decided_by as DecidedBy,
|
||||
decided_on as DecidedOn,
|
||||
sap_change_number as SapChangeNumber,
|
||||
error_message as ErrorMessage,
|
||||
reject_reason as RejectReason,
|
||||
sap_preview as SapPreview,
|
||||
|
||||
case status
|
||||
when 'PENDING' then cast( 'X' as abap_boolean )
|
||||
else cast( ' ' as abap_boolean )
|
||||
end as IsApprovable,
|
||||
|
||||
case status
|
||||
when 'FAILED' then cast( 'X' as abap_boolean )
|
||||
else cast( ' ' as abap_boolean )
|
||||
end as IsRetriable,
|
||||
|
||||
@Semantics.user.createdBy: true
|
||||
created_by as CreatedBy,
|
||||
@Semantics.systemDateTime.createdAt: true
|
||||
created_at as CreatedAt,
|
||||
@Semantics.user.lastChangedBy: true
|
||||
last_changed_by as LastChangedBy,
|
||||
@Semantics.systemDateTime.lastChangedAt: true
|
||||
last_changed_at as LastChangedAt,
|
||||
@Semantics.systemDateTime.localInstanceLastChangedAt: true
|
||||
local_last_changed_at as LocalLastChangedAt
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* TARGET OBJECT : service definition ZZUI_ARENA_CHANGE_APPRVL000_O4 (generated 2026-09-15)
|
||||
abap: URI : abap:/repotree-v1/0M7DEJI/System%20Library/ZLOCAL/ZARENA_PLM/Business%20Services/Service%20Definitions/ZZUI_ARENA_CHANGE_APPRVL000_O4/zzui_arena_change_apprvl000_o4.srvd.acds
|
||||
ACTION : replace entire content, then activate (after ZZC_CHANGEAPPROVAL000 view + BDEF).
|
||||
expose ... as <alias>: the alias becomes the entity set (ChangeApproval) and the entity type (ChangeApproval_Type)
|
||||
[source: abap-docs /abap-fiori-showcase/06_object_page_content (Service Definition), verified 2026-09-15].
|
||||
provider contracts odata_v4_ui switches on the UI-binding syntax checks and must match the binding type
|
||||
[source: abap-docs /abap-docs-cloud/ABENSRVD_PROVIDER_CONTRACT, verified 2026-09-15]. */
|
||||
@EndUserText.label: 'Arena change approval - UI service'
|
||||
define service ZZUI_ARENA_CHANGE_APPRVL000_O4
|
||||
provider contracts odata_v4_ui
|
||||
{
|
||||
expose ZZC_CHANGEAPPROVAL000 as ChangeApproval;
|
||||
}
|
||||
Reference in New Issue
Block a user