Bladeren bron

Support container file approval

moell 4 maanden geleden
bovenliggende
commit
5380d5ad89

+ 18 - 0
app/Http/Requests/API/Approval/CreateOrUpdateRequest.php

@@ -3,6 +3,9 @@
 namespace App\Http\Requests\API\Approval;
 
 use App\Models\Enums\ApprovalObjectType;
+use App\Models\Enums\FileObjectType;
+use App\Models\Enums\ObjectApprovalStatus;
+use App\Models\File;
 use Illuminate\Foundation\Http\FormRequest;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Validation\Rules\Enum;
@@ -45,6 +48,21 @@ class CreateOrUpdateRequest extends FormRequest
                             $fail('Resources without permission to access.');
                         }
                     }
+                ],
+                'file_ids' => [
+                    'array',
+                    function ($attribute, $value, $fail) {
+                        $count = File::query()
+                            ->where("company_id", Auth::user()->company_id)
+                            ->whereIn('id', $value)
+                            ->where("object_type", FileObjectType::CONTAINER)
+                            ->where("object_id", $this->get("object_id"))
+                            ->where("approval_status", ObjectApprovalStatus::WAIT)
+                            ->count();
+                        if ($count != count($value)) {
+                            $fail('Please select the file to be approved.');
+                        }
+                    }
                 ]
             ];
         }

+ 6 - 1
app/Models/Approval.php

@@ -25,7 +25,12 @@ class Approval extends Model
         'remark',
         'created_by',
         'status',
-        'company_id'
+        'company_id',
+        'sub_object_ids',
+    ];
+
+    protected $casts = [
+        'sub_object_ids' => 'array',
     ];
 
     protected static function booted(): void

+ 2 - 0
app/Models/Enums/ActionObjectType.php

@@ -31,6 +31,8 @@ enum ActionObjectType: string
 
     case CONTAINER_CONTENT = "container_content";
 
+    case CONTAINER_FILE = "container_file";
+
     public function modelBuilder(): \Illuminate\Database\Eloquent\Builder
     {
         return match ($this) {

+ 2 - 0
app/Models/Enums/ApprovalFlowType.php

@@ -11,4 +11,6 @@ enum ApprovalFlowType: string
     case TASK = "task";
 
     case CONTAINER = "container";
+
+    case CONTAINER_FILE = "container_file";
 }

+ 6 - 2
app/Models/Enums/ApprovalObjectType.php

@@ -17,6 +17,8 @@ enum ApprovalObjectType: string
 
     case CONTAINER = "container";
 
+    case CONTAINER_FILE = "container_file";
+
 
     public function modelBuilder(): \Illuminate\Database\Eloquent\Builder
     {
@@ -24,7 +26,7 @@ enum ApprovalObjectType: string
             self::PROJECT => Project::query(),
             self::TASK => Task::query(),
             self::REQUIREMENT => Requirement::query(),
-            self::CONTAINER => Container::query(),
+            self::CONTAINER, self::CONTAINER_FILE => Container::query(),
         };
     }
 
@@ -35,6 +37,7 @@ enum ApprovalObjectType: string
             self::TASK => ApprovalFlowType::TASK,
             self::REQUIREMENT => ApprovalFlowType::REQUIREMENT,
             self::CONTAINER => ApprovalFlowType::CONTAINER,
+            self::CONTAINER_FILE => ApprovalFlowType::CONTAINER_FILE,
         };
     }
 
@@ -45,6 +48,7 @@ enum ApprovalObjectType: string
             self::TASK => ActionObjectType::TASK,
             self::REQUIREMENT => ActionObjectType::REQUIREMENT,
             self::CONTAINER => ActionObjectType::CONTAINER,
+            self::CONTAINER_FILE => ActionObjectType::CONTAINER_FILE,
         };
     }
 
@@ -54,7 +58,7 @@ enum ApprovalObjectType: string
             self::PROJECT => Project::query()->allowed($id),
             self::TASK => Task::query()->allowed($id),
             self::REQUIREMENT => Requirement::query(),
-            self::CONTAINER => Container::query()->allowed($id),
+            self::CONTAINER, self::CONTAINER_FILE => Container::query()->allowed($id),
         };
     }
 

+ 40 - 10
app/Services/Approval/StoreService.php

@@ -10,6 +10,7 @@ use App\Models\Enums\ApprovalMode;
 use App\Models\Enums\ApprovalObjectType;
 use App\Models\Enums\ObjectAction;
 use App\Models\Enums\ObjectApprovalStatus;
+use App\Models\File;
 use App\Repositories\ActionRepository;
 use Illuminate\Support\Facades\Auth;
 
@@ -23,21 +24,21 @@ class StoreService
 
         $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'
-        );
+        $this->checkStatus($approvalObject, $approvalObjectType);
 
         $approvalFlow = $this->getApprovalFlow($approvalObjectType, $approvalObject);
 
-        $this->createApproval($approvalFlow, $approvalObjectType, $approvalObject->id, $request->remark);
-
-        $this->changeApprovalStatus($approvalObject);
+        $containerFileIds = $request->get("file_ids", []);
 
+        $this->createApproval($approvalFlow, $approvalObjectType, $approvalObject, $request->remark, $containerFileIds);
     }
 
     protected function createApproval(
-        ApprovalFlow $approvalFlow, ApprovalObjectType $approvalObjectType, int $objectId,  string $remark = null
+        ApprovalFlow $approvalFlow,
+        ApprovalObjectType $approvalObjectType,
+        $approvalObject,
+        string $remark = null,
+        array $containerFileIds = [],
     ): void
     {
         $firstNode =  $approvalFlow->nodes[1];
@@ -45,7 +46,7 @@ class StoreService
         $approval = Approval::query()->create([
             'approval_flow_id' => $approvalFlow->id,
             'object_type' => $approvalObjectType->flowType()->value,
-            'object_id' => $objectId,
+            'object_id' => $approvalObject->id,
             'node_level' => $firstNode['level'],
             'approval_mode' => $firstNode['approval_mode'],
             'users' => sprintf(",%s,", implode(',', $firstNode['approval_users'])),
@@ -53,12 +54,17 @@ class StoreService
             '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'],
+            'batch' => [
+                'type' => 'file',
+                'ids' => $containerFileIds,
+            ]
         ];
 
         if ($approval->approval_mode == ApprovalMode::SEQUENTIAL_APPROVAL->value) {
@@ -70,10 +76,34 @@ class StoreService
             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): void
+    protected function changeApprovalStatus(
+        $approvalObject, ApprovalObjectType $approvalObjectType, Approval $approval, array $containerFileIds = []
+    ): void
     {
+        if ($approvalObjectType == ApprovalObjectType::CONTAINER_FILE) {
+            File::query()->whereIn("id", $containerFileIds)->update([
+                'approval_status' => ObjectApprovalStatus::DOING,
+                'latest_approval_id' => $approval->id,
+            ]);
+            return;
+        }
+
         $approvalObject->approval_status = ObjectApprovalStatus::DOING;
         $approvalObject->save();
     }

+ 29 - 0
database/migrations/2024_10_19_202359_add_approval_status_to_files_table.php

@@ -0,0 +1,29 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('files', function (Blueprint $table) {
+            $table->string("approval_status", 30)->nullable()->default(\App\Models\Enums\ObjectApprovalStatus::WAIT->value);
+            $table->integer("latest_approval_id")->nullable();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('files', function (Blueprint $table) {
+            $table->dropColumn(['approval_status', 'latest_approval_id']);
+        });
+    }
+};

+ 28 - 0
database/migrations/2024_10_19_225050_add_sub_object_ids_to_approvals_table.php

@@ -0,0 +1,28 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('approvals', function (Blueprint $table) {
+            $table->json("sub_object_ids")->nullable();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('approvals', function (Blueprint $table) {
+            $table->dropColumn(['sub_object_ids']);
+        });
+    }
+};