object_type); $approvalObject = $approvalObjectType->modelBuilderAllowed($request->object_id)->findOrFail($request->object_id); $this->checkStatus($approvalObject, $approvalObjectType); // $approvalFlow = $this->getApprovalFlow($approvalObjectType, $approvalObject); $approvalFlow = $this->getNewApprovalFlow($request->approvalFlow_id); $containerFileIds = $request->get("file_ids", []); $this->createApproval($approvalFlow, $approvalObjectType, $approvalObject, $request->remark, $containerFileIds); } protected function createApproval( ApprovalFlow $approvalFlow, ApprovalObjectType $approvalObjectType, $approvalObject, string $remark = null, array $containerFileIds = [], ): void { $firstNode = $approvalFlow->nodes[1]; $approval = Approval::query()->create([ 'approval_flow_id' => $approvalFlow->id, 'object_type' => $approvalObjectType->flowType()->value, 'object_id' => $approvalObject->id, '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, 'sub_object_ids' => $containerFileIds, ]); $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, ); $this->changeApprovalStatus($approvalObject, $approvalObjectType, $approval, $containerFileIds); } protected function checkStatus($approvalObject, ApprovalObjectType $approvalObjectType) { if ($approvalObjectType == ApprovalObjectType::CONTAINER_FILE) { return; } throw_validation_if( in_array($approvalObject?->approval_status, [ObjectApprovalStatus::DOING->value]), 'Do not initiate duplicate approvals' ); } protected function changeApprovalStatus( $approvalObject, ApprovalObjectType $approvalObjectType, Approval $approval, array $containerFileIds = [] ): void { if ($approvalObjectType == ApprovalObjectType::CONTAINER_FILE) { $list = File::query()->whereIn("id", $containerFileIds)->get(); foreach ($list as $value){ $approval_status = $value->approval_status == ObjectApprovalStatus::REJECTED->value ? ObjectApprovalStatus::RESUBMISSION->value : ObjectApprovalStatus::DOING->value; File::query()->where("id", $value->id)->update([ 'approval_status' => $approval_status, 'latest_approval_id' => $approval->id, ]); } return; } $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; } protected function getNewApprovalFlow($id) { $approvalFlow = ApprovalFlow::query() ->where("status", 1)->findOrFail($id); throw_validation_if(! $approvalFlow, 'Clearly set up approval flow rules first.'); return $approvalFlow; } }