====== Automatic approval task approver transfer ====== The feature is **NOT RELEASED **and documentation is a **DRAFT**.. When an approval task's approver is **deactivated** or **deleted**, the identity is removed as an approver\\ from running approval tasks. When the task would be left without any approver, it is **reassigned** to new\\ approvers resolved by a configurable script (or to default approvers, when no script is configured). ==== On approver deactivation ==== Whenever an identity transitions from an active to a disabled state (`IdentityState.isDisabled()`), it is\\ removed as an approver from all **running** approval tasks (`ApprovalTaskState.RUNNING`). Approvers of\\ already terminated tasks are kept for history. Every way an identity can become disabled is covered, because the trigger is the state transition itself,\\ not the action that caused it: - manual deactivation (dashboard button, bulk action on the users table),\\ - the last valid contract ends (`validTill` in the past) — identity state `LEFT`,\\ - all contracts are excluded — identity state `DISABLED`. An identity with more than one contract stays active (and stays an approver) until its **last** valid contract ends. If the task still has at least one approver after the removal, nothing else happens — the task is **not** reassigned yet. Only when the removed approver was the last one is the task reassigned. ==== On approver deletion ==== Identity delete already removes the identity's approver records (referential integrity,\\ `IdentityDeleteProcessor`). A task left without any approver is reassigned the same way as on deactivation. ==== Resolving new approvers ==== 1. The script configured by `idm.sec.core.wf.approval.task.reassign.script` is evaluated (see below).\\ 2. Null, duplicate and disabled identities are filtered out from the script result.\\ 3. When no usable approver remains (script not configured, not found, failed, or returned nothing usable),\\ ** default approvers** are used — members of the admin role (by `idm.sec.core.role.admin` configuration).\\ 4. Delegations of the new approvers are applied (a delegate becomes the approver instead of the delegator). The reassignment does not re-send new task notifications. ==== Configuration ==== | \\ Property \\ |Default value|Description| |idm.pub.core.wf.approval.task.reassign.enabled|true|Switches this feature on and off.| |idm.sec.core.wf.approval.task.reassign.script|--|Code of the script that is to be used to resolve new approvers| ==== Interface of reassign scripts ==== The reassignment scripts are of type DEFAULT and can use the input parameters //approvalTask// - the task that just ran out od approvers - and //lastApprover //- the approver that was just removed. The script must return either IdmIdentityDto or List. Returning null, empty lists or throwing an exception will assign the task to the default approvers, using the getDefaultApprovers() method in DefaultIdmAprovalTaskApproverService.java. ==== Product provided scripts ==== The product provides three prewritten scripts to resolve new approvers. |Script code|Description| |approvalTaskReassignToIdentity|Reassigns the task to a single identity with a hardcoded username.| | \\ approvalTaskReassignToRole \\ \\ \\ |Reassigns the task to all valid identities with a hardcoded role assigned.| |approvalTaskReassignToLastApproverManager|Reassigns the task to managers of the last approver (found by the last approver's contracts — contract guarantees or managers by tree \\ structure). Falls back to admin role members when the last approver has no manager| ==== Frontend ==== When the feature is enabled, a warning about approver removal and possible task reassignment is shown: - in the confirm dialog of the //Deactivate manually// dashboard button (identity detail),\\ - in the //Deactivate manually// bulk action dialog on the users table (bulk action prevalidation). Localization key of the warning: `content.identities.action.deactivate.taskReassignWarning`. ==== Implementation notes ==== - `IdentityDisableReassignApprovalTasksProcessor` (core-impl) — reacts to the active → disabled identitytransition (identity `UPDATE` event, order `+10`), removes the identity from running tasks via\\`deleteWithAnyApproverLeftCheck`. Disableable processor.\\ - `IdentityDeleteProcessor` (core-impl, pre-existing) — calls `deleteWithAnyApproverLeftCheck` for the deleted identity's approver records.\\ - `IdentityDisableBulkAction.prevalidate()` — returns the frontend warning (`CoreResultCode.IDENTITY_DISABLE_BULK_ACTION_TASK_REASSIGN`), when the feature is enabled.