objectAction = ObjectAction::tryFrom($this->action->action); } public function handle() { if ($this->objectAction->isApproval()) { $this->handleByApprovalAction(); } else { $this->handleByObjectAction($this->userIDs()); } } abstract protected function userIDs(): array; protected function handleByApprovalAction() { $approval = Approval::query()->find($this->action->additional_id); if (! $approval) { return; } list($approvalUserIDs, $notifiedUserIDs) = $this->objectActionApprovalNotificationUserIDs($approval, $this->action); $this->storeNotification($notifiedUserIDs); $this->storeNotification($approvalUserIDs, [ 'action' => 'waitingForMyApproval' ]); } protected function handleByObjectAction(array $userIDs) { $this->storeNotification($userIDs); } protected function storeNotification(array $userIds, array $extraFields = []) { if (! $userIds) { return; } $notification = Notification::query()->create([ 'object_type' => NotificationObjectType::ACTION->value, 'object_id' => $this->action->id, 'extra_fields' => $extraFields ?: null, ]); foreach ($userIds as $userId) { NotificationRecord::query()->create([ 'notification_id' => $notification->id, 'user_id' => $userId, ]); } } protected function notificationNextApprovalUsers(Approval $approval) { $approvalFlow = $approval->approvalFlow()->first(); if (! $approvalFlow) { return; } $nextNode = $approvalFlow->nodes[$this->action->extra_fields['next']]; $approvalObjectUsers = array_values(array_filter(explode(',', $approval->users))); $userIds = match (ApprovalMode::tryFrom($nextNode['approval_mode'])) { ApprovalMode::ALTERNATIVE_APPROVAL, ApprovalMode::COUNTERSIGNATURE => $nextNode['approval_users'] ?? [], ApprovalMode::SEQUENTIAL_APPROVAL => $this->action->extra_fields['next_sequential_user'] ?? [], default => [], }; $this->storeNotification($userIds, [ 'action' => 'waitingForMyApproval' ]); } }