upload current sources

This commit is contained in:
2026-09-16 01:47:28 -07:00
commit f8b45ea4a5
109 changed files with 26012 additions and 0 deletions
@@ -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.