@php $authUser = Auth::user(); $viewerDashboardContext = strtolower(trim((string) request()->query('view', ''))); $userRole = \App\Support\WorkflowPermission::normalizeRole((string) ($authUser->role ?? \App\Support\WorkflowPermission::ROLE_REQUESTER)); $currentState = (string) ($requestItem->workflow_state ?? \App\Models\RequesterRequest::STATE_SUBMITTED); $currentHolderRole = \App\Support\WorkflowPermission::normalizeRole((string) ($requestItem->current_holder_role ?? \App\Support\WorkflowPermission::ROLE_REQUESTER)); $roleCanReviewDocument = \App\Support\WorkflowPermission::canUseAdminPermission((string) ($authUser->role ?? ''), \App\Support\WorkflowPermission::ADMIN_PERMISSION_REVIEW_DOCUMENT); $roleCanOrganizationOfficer = \App\Support\WorkflowPermission::canUseAdminPermission((string) ($authUser->role ?? ''), \App\Support\WorkflowPermission::ADMIN_PERMISSION_ORGANIZATION_OFFICER); $roleCanRequestDocument = \App\Support\WorkflowPermission::canUseAdminPermission((string) ($authUser->role ?? ''), \App\Support\WorkflowPermission::ADMIN_PERMISSION_REQUEST_DOCUMENT); $roleCanRegisterDocumentNumber = \App\Support\WorkflowPermission::canUseAdminPermission((string) ($authUser->role ?? ''), \App\Support\WorkflowPermission::ADMIN_PERMISSION_REGISTER_DOCUMENT_NUMBER); $isRequesterOwner = (int) ($requestItem->user_id ?? 0) === (int) ($authUser->id ?? 0); $forceRequesterPerspective = $viewerDashboardContext === 'requests' && $isRequesterOwner; $requestOrganizationName = strtolower(trim((string) ($requestItem->organization_name ?? ''))); $userOrganizationName = strtolower(trim((string) ($authUser->organization_name ?? ''))); $workflowStepsOrdered = collect(is_array($requestItem->workflow_steps_override) && count($requestItem->workflow_steps_override) > 0 ? $requestItem->workflow_steps_override : (optional($requestItem->workflowTemplate)->steps ?? [])) ->filter(fn ($step) => is_array($step)) ->sortBy(fn ($step) => (int) ($step['order'] ?? 0)) ->values(); $currentStepOrder = (int) ($requestItem->current_workflow_step_order ?? 0); $currentStepConfig = $currentStepOrder > 0 ? $workflowStepsOrdered->first(fn ($step) => (int) ($step['order'] ?? 0) === $currentStepOrder) : null; if (!is_array($currentStepConfig)) { $currentStepConfig = $workflowStepsOrdered->first(fn ($step) => (string) ($step['to_state'] ?? '') === $currentState); } $workflowStepOrganizationName = static function ($step): string { if (!is_array($step)) { return ''; } $organizationName = trim((string) data_get($step, 'organization_name', '')); return $organizationName !== '' ? $organizationName : trim((string) data_get($step, 'office_name', '')); }; $currentStepOrganizationRaw = $workflowStepOrganizationName($currentStepConfig); $currentStepOrganizationName = strtolower($currentStepOrganizationRaw); $currentStepTypeForOrganizationGuard = strtolower(trim((string) data_get($currentStepConfig, 'step_type', ''))); $currentStepOrganizationDisabled = $currentStepTypeForOrganizationGuard === 'organization' && $currentStepOrganizationRaw !== '' && !\App\Models\Organization::activeNameExists($currentStepOrganizationRaw); $currentStepIndex = $workflowStepsOrdered->search(function ($step) use ($currentStepConfig, $currentStepOrder, $currentState) { if (!is_array($step)) { return false; } return ($currentStepOrder > 0 && (int) ($step['order'] ?? 0) === $currentStepOrder) || ($currentStepOrder <= 0 && (string) ($step['to_state'] ?? '') === $currentState) || ($currentStepConfig && (int) ($step['order'] ?? 0) === (int) ($currentStepConfig['order'] ?? 0)); }); $currentStepIndex = $currentStepIndex === false ? null : (int) $currentStepIndex; $nextStep = $currentStepIndex === null ? null : $workflowStepsOrdered->slice($currentStepIndex + 1)->first(); $normalizeStepRole = static function (?array $step): string { if (!is_array($step)) { return ''; } $stepType = strtolower(trim((string) ($step['step_type'] ?? ''))); $actorRole = \App\Support\WorkflowPermission::normalizeRole((string) ($step['actor_role'] ?? '')); if ($actorRole !== '' && !in_array($actorRole, [ \App\Support\WorkflowPermission::PERMISSION_REVIEWER, \App\Support\WorkflowPermission::PERMISSION_APPROVER, ], true)) { return $actorRole; } return match ($stepType) { 'vice_rector' => \App\Support\WorkflowPermission::ROLE_VICE_RECTOR, 'rector', 'approval' => \App\Support\WorkflowPermission::ROLE_RECTOR, 'organization' => \App\Support\WorkflowPermission::ROLE_REQUESTER, default => $actorRole, }; }; $nextActorRole = $normalizeStepRole(is_array($nextStep) ? $nextStep : null); $currentStepPermissionRole = strtolower(trim((string) data_get($currentStepConfig, 'permission_type', ''))); if (!in_array($currentStepPermissionRole, [ \App\Support\WorkflowPermission::PERMISSION_REVIEWER, \App\Support\WorkflowPermission::PERMISSION_APPROVER, ], true)) { $currentStepType = strtolower(trim((string) data_get($currentStepConfig, 'step_type', ''))); $currentStepActorRole = $normalizeStepRole(is_array($currentStepConfig) ? $currentStepConfig : null); $currentStepPermissionRole = in_array($currentStepType, ['approval', 'vice_rector'], true) || in_array($currentStepActorRole, [ \App\Support\WorkflowPermission::ROLE_RECTOR, \App\Support\WorkflowPermission::ROLE_VICE_RECTOR, ], true) ? \App\Support\WorkflowPermission::PERMISSION_APPROVER : \App\Support\WorkflowPermission::PERMISSION_REVIEWER; } $isCurrentHolder = (int) ($requestItem->current_holder_user_id ?? 0) === (int) ($authUser->id ?? 0); $isSharedRoleQueue = $userRole !== '' && $currentHolderRole !== '' && $userRole === $currentHolderRole && empty($requestItem->current_holder_user_id) && ($requestOrganizationName === '' || $userOrganizationName === '' || $requestOrganizationName === $userOrganizationName); $isOrganizationQueue = $currentHolderRole === \App\Support\WorkflowPermission::ROLE_REQUESTER && empty($requestItem->current_holder_user_id) && $requestOrganizationName !== '' && $userOrganizationName !== '' && $requestOrganizationName === $userOrganizationName; $legacyOrganizationQueueAccess = $currentHolderRole === \App\Support\WorkflowPermission::ROLE_REQUESTER && $roleCanReviewDocument && !$currentStepOrganizationDisabled && $userOrganizationName !== '' && ( ($currentStepOrganizationName !== '' && $currentStepOrganizationName === $userOrganizationName) || ($requestOrganizationName !== '' && $requestOrganizationName === $userOrganizationName) ); $holderCanAct = !$currentStepOrganizationDisabled && ($isCurrentHolder || $isSharedRoleQueue || $isOrganizationQueue || $legacyOrganizationQueueAccess); $isActionableStatus = in_array(strtolower((string) ($requestItem->status ?? '')), ['pending', 'approved', 'rejected'], true) && !in_array($currentState, [ \App\Models\RequesterRequest::STATE_COMPLETED, \App\Models\RequesterRequest::STATE_REJECTED, ], true); $historyEntries = $requestItem->history ?? collect(); $lastSendBackEntry = $historyEntries ->filter(fn ($entry) => (string) ($entry->action ?? '') === \App\Support\WorkflowPermission::ACTION_REQUEST_REVISION) ->filter(fn ($entry) => trim((string) data_get(is_array($entry->meta) ? $entry->meta : [], 'sent_back_by_role', '')) !== '') ->sortByDesc('id') ->first(); $lastSendBackMeta = is_array($lastSendBackEntry?->meta) ? $lastSendBackEntry->meta : []; $sendBackAlreadyReturned = $lastSendBackEntry ? $historyEntries ->filter(fn ($entry) => (int) ($entry->id ?? 0) > (int) ($lastSendBackEntry->id ?? 0)) ->contains(function ($entry) { return (string) ($entry->action ?? '') === \App\Support\WorkflowPermission::ACTION_FORWARD_TO_RECTOR && (bool) data_get(is_array($entry->meta) ? $entry->meta : [], 'returned_back', false); }) : false; $sentBackToUserId = (int) data_get($lastSendBackMeta, 'sent_back_to_user_id', 0); $sentBackToRole = \App\Support\WorkflowPermission::normalizeRole((string) data_get($lastSendBackMeta, 'sent_back_to_role', '')); $sentBackToState = (string) data_get($lastSendBackMeta, 'sent_back_to_state', (string) ($lastSendBackEntry->to_state ?? '')); $sentBackToStepOrder = (int) data_get($lastSendBackMeta, 'sent_back_selected_target_step_order', 0); $sentBackTargetType = strtolower(trim((string) data_get($lastSendBackMeta, 'sent_back_target_type', ''))); $sentBackOrganization = strtolower(trim((string) data_get($lastSendBackMeta, 'sent_back_selected_target_organization', data_get($lastSendBackMeta, 'organization_name', '')))); $sentBackByUserId = (int) data_get($lastSendBackMeta, 'sent_back_by_user_id', (int) ($lastSendBackEntry->actor_user_id ?? 0)); $sentBackTargetsRequesterOwner = $sentBackTargetType !== 'stage' && $sentBackToStepOrder <= 0 && $isRequesterOwner && ( $sentBackToUserId === 0 || $sentBackToUserId === (int) ($authUser->id ?? 0) || in_array($sentBackTargetType, ['', 'requester', 'user'], true) || $sentBackToRole === \App\Support\WorkflowPermission::ROLE_REQUESTER ); $sentBackTargetsCurrentOrganizationQueue = $sentBackToRole === \App\Support\WorkflowPermission::ROLE_REQUESTER && ($sentBackTargetType === 'stage' || $sentBackToStepOrder > 0) && !$sentBackTargetsRequesterOwner && $roleCanReviewDocument && $roleCanOrganizationOfficer && ( $sentBackOrganization === '' || $requestOrganizationName === '' || $sentBackOrganization === $requestOrganizationName || $sentBackOrganization === $userOrganizationName ); $sentBackTargetMatchesCurrentHolder = $sentBackTargetsCurrentOrganizationQueue || ($sentBackToUserId > 0 ? $sentBackToUserId === (int) ($authUser->id ?? 0) : ($sentBackToRole !== '' && $sentBackToRole === $currentHolderRole && $sentBackToRole === $userRole)); $sentBackTargetMatchesCurrentStep = ( ($sentBackToState === '' || $sentBackToState === $currentState) && ($sentBackToStepOrder <= 0 || $sentBackToStepOrder === $currentStepOrder) ) || $sentBackTargetsCurrentOrganizationQueue; $isPendingReturnBackTarget = $lastSendBackEntry !== null && !$sendBackAlreadyReturned && ( $sentBackByUserId !== (int) ($authUser->id ?? 0) || ($forceRequesterPerspective && $sentBackTargetsRequesterOwner) ) && $sentBackTargetMatchesCurrentHolder && $sentBackTargetMatchesCurrentStep && $holderCanAct; $isWaitingForSentBackReturn = $lastSendBackEntry !== null && !$sendBackAlreadyReturned && $sentBackByUserId === (int) ($authUser->id ?? 0) && !($forceRequesterPerspective && $sentBackTargetsRequesterOwner); $allowedActions = $roleCanReviewDocument ? \App\Support\WorkflowPermission::allowedActions($currentStepPermissionRole, $currentState, $nextActorRole) : []; $canForwardByPermission = in_array(\App\Support\WorkflowPermission::ACTION_FORWARD_TO_RECTOR, $allowedActions, true); $canSendBackInUi = in_array(\App\Support\WorkflowPermission::ACTION_REQUEST_REVISION, $allowedActions, true) && $currentStepOrder > 0; $canApproveByPermission = in_array(\App\Support\WorkflowPermission::ACTION_APPROVE_DOCUMENT, $allowedActions, true); $canRejectByPermission = in_array(\App\Support\WorkflowPermission::ACTION_REJECT_DOCUMENT, $allowedActions, true); $canCommentAction = $roleCanReviewDocument && $holderCanAct && $isActionableStatus && \App\Support\WorkflowPermission::canUseUiPermission($currentStepPermissionRole, 'review/comment'); $canUploadAction = $roleCanReviewDocument && $holderCanAct && $isActionableStatus && \App\Support\WorkflowPermission::canUseUiPermission($currentStepPermissionRole, 'upload_document'); if ($isPendingReturnBackTarget) { $canForwardByPermission = true; $canSendBackInUi = $roleCanReviewDocument && !$sentBackTargetsRequesterOwner && $currentStepOrder > 0; $canApproveByPermission = false; $canRejectByPermission = false; $canCommentAction = !$sentBackTargetsRequesterOwner && $canCommentAction; $canUploadAction = !$sentBackTargetsRequesterOwner && $canUploadAction; } if ($isWaitingForSentBackReturn) { $canForwardByPermission = false; $canSendBackInUi = false; $canApproveByPermission = false; $canRejectByPermission = false; } $userCanActFromWorkQueueAsRequesterAndOrganizationMember = $viewerDashboardContext === 'work' && $isRequesterOwner && $roleCanReviewDocument && $userOrganizationName !== '' && $currentStepOrganizationName !== '' && $userOrganizationName === $currentStepOrganizationName; if ($forceRequesterPerspective && !$userCanActFromWorkQueueAsRequesterAndOrganizationMember && !$isPendingReturnBackTarget) { $canForwardByPermission = false; $canSendBackInUi = false; $canApproveByPermission = false; $canRejectByPermission = false; $canCommentAction = false; $canUploadAction = false; } $canStageReviewer = $holderCanAct && $isActionableStatus && $currentStepPermissionRole === \App\Support\WorkflowPermission::PERMISSION_REVIEWER && ($canForwardByPermission || $isPendingReturnBackTarget); $canStageApprover = $holderCanAct && $isActionableStatus && $currentStepPermissionRole === \App\Support\WorkflowPermission::PERMISSION_APPROVER && ($canApproveByPermission || $canRejectByPermission || $canSendBackInUi); $showWorkflowActionPanel = $canStageReviewer || $canStageApprover || $canUploadAction || $isWaitingForSentBackReturn; $transitionUrl = route('document-viewer.workflow.transition', $requestItem->id); $isFinalForwardStep = !$nextStep; $forwardActionLabel = $isPendingReturnBackTarget ? __('Return Back') : ($isFinalForwardStep ? __('Complete') : __('Forward to Next Step')); $forwardActionShortLabel = $isPendingReturnBackTarget ? __('Return') : ($isFinalForwardStep ? __('Complete') : __('Forward')); $forwardActionModalTitle = $isPendingReturnBackTarget ? __('Return Back to Next Step') : ($isFinalForwardStep ? __('Complete Workflow Step') : __('Forward to Next Step')); $forwardActionDescription = $isPendingReturnBackTarget ? __('This will return the document back to the stage that requested revision.') : ($isFinalForwardStep ? __('This is the final stage transition. Submitting will complete this workflow.') : __('This will forward the document to the next configured step in the workflow.')); $forwardActionPlaceholder = $isPendingReturnBackTarget ? __('Add a return note...') : ($isFinalForwardStep ? __('Add a completion note...') : __('Add a forwarding note...')); $forwardButtonClass = $isPendingReturnBackTarget ? 'btn-secondary' : ($isFinalForwardStep ? 'btn-success' : 'btn-primary'); $forwardModalButtonClass = $isPendingReturnBackTarget ? 'btn-secondary' : ($isFinalForwardStep ? 'btn-success' : 'btn-secondary'); $forwardModalIconClass = $isPendingReturnBackTarget ? 'text-secondary' : ($isFinalForwardStep ? 'text-success' : 'text-secondary'); $forwardIcon = $isPendingReturnBackTarget ? 'ri-arrow-left-right-line' : ($isFinalForwardStep ? 'ri-check-line' : 'ri-arrow-right-line'); $shouldWarnMissingRegistryBeforeForward = $roleCanRegisterDocumentNumber && trim((string) ($requestItem->registry_document_number ?? '')) === '' && !$isPendingReturnBackTarget; $forwardModalButtonAttributes = $shouldWarnMissingRegistryBeforeForward ? 'data-registry-forward-target="#reviewModalForward"' : 'data-bs-toggle="modal" data-bs-target="#reviewModalForward"'; $sendBackStageOptions = $workflowStepsOrdered ->filter(function ($step) use ($currentStepOrder) { $order = (int) ($step['order'] ?? 0); $toState = strtolower(trim((string) ($step['to_state'] ?? ''))); $actorRole = \App\Support\WorkflowPermission::normalizeRole((string) ($step['actor_role'] ?? '')); return $order > 0 && ($currentStepOrder <= 0 || $order < $currentStepOrder) && $actorRole !== \App\Support\WorkflowPermission::ROLE_RECTOR && $toState !== \App\Models\RequesterRequest::STATE_COMPLETED; }) ->map(function ($step) { $order = (int) ($step['order'] ?? 0); $organizationName = trim((string) ($step['organization_name'] ?? '')); $label = $organizationName !== '' ? $organizationName : (trim((string) ($step['label'] ?? '')) ?: \App\Models\RequesterRequest::workflowLabel((string) ($step['to_state'] ?? ''))); return [ 'value' => 'stage:' . $order, 'label' => __('Step :order', ['order' => $order]) . ' - ' . __($label), ]; }) ->values(); $sendBackUserOptions = collect($sendBackTargetOptions ?? []); $sendBackCombinedTargetOptions = collect(); $requesterOption = $sendBackUserOptions->first(fn ($option) => (bool) ($option['is_requester'] ?? false)); if (is_array($requesterOption) && (int) ($requesterOption['id'] ?? 0) > 0) { $sendBackCombinedTargetOptions->push([ 'value' => 'user:' . (int) ($requesterOption['id'] ?? 0), 'label' => __('Requester') . ' - ' . trim((string) ($requesterOption['name'] ?? '')), ]); } $sendBackCombinedTargetOptions = $sendBackCombinedTargetOptions->merge($sendBackStageOptions); $reviewWorkflowActionCount = 0; $reviewWorkflowActionCount += ($canForwardByPermission && ($canStageReviewer || $isPendingReturnBackTarget)) ? 1 : 0; $reviewWorkflowActionCount += ($canApproveByPermission && $canStageApprover) ? 1 : 0; $reviewWorkflowActionCount += ($canSendBackInUi && ($canStageReviewer || $canStageApprover)) ? 1 : 0; $reviewWorkflowActionCount += ($canRejectByPermission && $canStageApprover) ? 1 : 0; $hasWorkflowDecisionActions = $reviewWorkflowActionCount > 0 || $isWaitingForSentBackReturn; @endphp @if($currentStepOrganizationDisabled)
{{ __('Organization disabled.') }}
{{ __('This document is assigned to a disabled organization. Please re-enable the organization or update this document workflow.') }}
{{ __('Note: please contact admin.') }}
{{ __('Waiting for return.') }}
{{ __('This document was sent back and is waiting for the target user to return it.') }}