object_type); $approvalObject = $approvalObjectType->modelBuilderAllowed($request->object_id)->findOrFail($request->object_id); throw_validation_if( in_array($approvalObject?->approval_status, [ObjectApprovalStatus::DOING->value]), 'Do not initiate duplicate approvals' ); $approvalFlow = $this->getApprovalFlow($approvalObjectType, $approvalObject); $this->createApproval($approvalFlow, $approvalObjectType, $approvalObject->id, $request->remark); $this->changeApprovalStatus($approvalObject); } protected function createApproval( ApprovalFlow $approvalFlow, ApprovalObjectType $approvalObjectType, int $objectId, string $remark = null ): void { $firstNode = $approvalFlow->nodes[1]; $approval = Approval::query()->create([ 'approval_flow_id' => $approvalFlow->id, 'object_type' => $approvalObjectType->flowType()->value, 'object_id' => $objectId, 'node_level' => $firstNode['level'], 'approval_mode' => $firstNode['approval_mode'], 'users' => sprintf(",%s,", implode(',', $firstNode['approval_users'])), 'remark' => $remark, 'created_by' => Auth::id(), 'status' => ObjectApprovalStatus::DOING, 'company_id' => Auth::user()->company_id, ]); $extraFields = [ 'now' => 0, 'next' => 1, 'approval_mode' => $firstNode['approval_mode'], ]; if ($approval->approval_mode == ApprovalMode::SEQUENTIAL_APPROVAL->value) { $extraFields['next_sequential_user'] = $firstNode['approval_users'][0]; } ActionRepository::createByApproval( $approval, ObjectAction::APPROVAL_REQUEST, extraFields: $extraFields, ); } protected function changeApprovalStatus($approvalObject): void { $approvalObject->approval_status = ObjectApprovalStatus::DOING; $approvalObject->save(); } protected function getApprovalFlow(ApprovalObjectType $approvalObjectType, $approvalObject) { $approvalFlow = ApprovalFlow::query() ->where(function ($query) use ($approvalObjectType, $approvalObject) { $query->where([ "type" => $approvalObjectType->flowType()->value, "object_id" => 0, ]) ->when( $approvalObjectType->flowType() == ApprovalFlowType::TASK, fn ($query) => $query->orWhere(fn ($query) => $query->where([ "type" => $approvalObjectType->flowType()->value, 'object_type' => ApprovalFlowObjectType::PROJECT->value, 'object_id' => $approvalObject->project_id, ])) ); }) ->where("status", 1) ->orderByDesc("object_id") ->first(); throw_validation_if(! $approvalFlow, 'Clearly set up approval flow rules first.'); return $approvalFlow; } }