123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- <?php
- namespace App\Services\Approval;
- use App\Models\Approval;
- use App\Models\Enums\ApprovalMode;
- use App\Models\Enums\ApprovalObjectType;
- use App\Models\Enums\FileObjectType;
- use App\Models\Enums\ObjectAction;
- use App\Models\Enums\ObjectApprovalStatus;
- use App\Models\File;
- use App\Repositories\ActionRepository;
- use App\Services\File\Upload\FileUploadHelper;
- use Illuminate\Http\UploadedFile;
- use Illuminate\Support\Facades\Auth;
- class ActionService
- {
- use FileUploadHelper;
- protected ?Approval $approval = null;
- protected array $actionExtraFields = [];
- protected ?ObjectAction $objectAction = null;
- public function action(Approval $approval, int $status, string $comment = null, ?UploadedFile $uploadedFile = null): void
- {
- $this->approval = $approval;
- $this->actionExtraFields = [
- 'now' => $this->approval->node_level
- ];
- $fileInfo = $uploadedFile ? $this->chunkUploadFileByCompany($uploadedFile, FileObjectType::ACTION->value) : [];
- match($status) {
- 1 => $this->approved(),
- default => $this->rejected(),
- };
- $this->actionExtraFields['approval_mode'] = $this->approval->approval_mode;
- $action = $this->triggerAction($comment);
- $this->changeApprovalObjectStatus();
- $this->changeApproval();
- $this->fileToDatabase($fileInfo, $action->id);
- }
- protected function changeApproval(): void
- {
- $actionUsers = array_unique(array_filter([Auth::id(), ...explode(',', $this->approval->action_users)]));
- $this->approval->last_action_user_id = Auth::id();
- $this->approval->action_users = sprintf(",%s,", implode(",", $actionUsers));
- $this->approval->save();
- }
- protected function changeApprovalObjectStatus(): void
- {
- $approvalType = ApprovalObjectType::from($this->approval->object_type);
- $object = $approvalType
- ->modelBuilder()
- ->findOrFail($this->approval->object_id);
- if ($approvalType == ApprovalObjectType::CONTAINER_FILE) {
- File::query()->whereIn("id", $this->approval->sub_object_ids)->update([
- 'approval_status' => $this->approval->status
- ]);
- } else {
- $object->approval_status = $this->approval->status;
- $object->save();
- }
- }
- protected function triggerAction (string $comment = null)
- {
- return ActionRepository::createByApproval(
- $this->approval,
- $this->objectAction,
- $comment,
- extraFields: $this->actionExtraFields
- );
- }
- protected function approved(): void
- {
- $approvalFlowNodes = $this->approval->approvalFlow?->nodes;
- $nextNodeIndex = $this->approval->node_level + 1;
- $nextNode = $approvalFlowNodes[$nextNodeIndex] ?? [];
- $approvalObjectUsers = array_values(array_filter(explode(",", $this->approval->users), function($value) {
- return $value != Auth::id() && $value;
- }));
- switch (ApprovalMode::tryFrom($this->approval->approval_mode)) {
- case ApprovalMode::ALTERNATIVE_APPROVAL:
- if (! $nextNode) {
- $this->approvedHandle();
- } else {
- $this->approvedToNextNodeHandle($nextNodeIndex, $nextNode);
- }
- break;
- case ApprovalMode::COUNTERSIGNATURE:
- case ApprovalMode::SEQUENTIAL_APPROVAL:
- if (count($approvalObjectUsers) > 0 ) {
- $this->approvedWaitOthers($approvalObjectUsers);
- } elseif (! $nextNode) {
- $this->approvedHandle();
- } else {
- $this->approvedToNextNodeHandle($nextNodeIndex, $nextNode);
- }
- break;
- }
- }
- protected function approvedWaitOthers(array $approvalObjectUsers)
- {
- $this->approval->users = sprintf(",%s,", implode(',', $approvalObjectUsers));
- $this->objectAction = ObjectAction::APPROVED_WAIT_OTHERS;
- if ($this->approval->approval_mode == ApprovalMode::SEQUENTIAL_APPROVAL->value) {
- $this->actionExtraFields['next_sequential_user'] = $approvalObjectUsers[0];
- }
- }
- protected function cleanApprovalFields()
- {
- $this->approval->node_level = null;
- $this->approval->users = null;
- $this->approval->approval_mode = null;
- }
- protected function approvedHandle()
- {
- $this->approval->status = ObjectApprovalStatus::APPROVED->value;
- $this->cleanApprovalFields();
- $this->objectAction = ObjectAction::APPROVAL_APPROVED;
- }
- protected function approvedToNextNodeHandle(int $nextNodeIndex, array $nextNode)
- {
- $this->actionExtraFields['next'] = $nextNodeIndex;
- $this->approval->node_level = $nextNodeIndex;
- $this->approval->users = sprintf(",%s,", implode(',', $nextNode['approval_users']));
- $this->approval->approval_mode = $nextNode['approval_mode'];
- $this->objectAction = ObjectAction::APPROVED_TO_NEXT_NODE;
- if ($this->approval->approval_mode == ApprovalMode::SEQUENTIAL_APPROVAL->value) {
- $this->actionExtraFields['next_sequential_user'] = $nextNode['approval_users'][0];
- }
- }
- protected function rejected(): void
- {
- $this->approval->status = ObjectApprovalStatus::REJECTED->value;
- $this->cleanApprovalFields();
- $this->objectAction = ObjectAction::APPROVAL_REJECTED;
- }
- }
|