StoreService.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <?php
  2. namespace App\Services\Approval;
  3. use App\Models\Approval;
  4. use App\Models\ApprovalFlow;
  5. use App\Models\Enums\ApprovalFlowObjectType;
  6. use App\Models\Enums\ApprovalFlowType;
  7. use App\Models\Enums\ApprovalMode;
  8. use App\Models\Enums\ApprovalObjectType;
  9. use App\Models\Enums\ObjectAction;
  10. use App\Models\Enums\ObjectApprovalStatus;
  11. use App\Models\File;
  12. use App\Repositories\ActionRepository;
  13. use Illuminate\Support\Facades\Auth;
  14. class StoreService
  15. {
  16. public function store()
  17. {
  18. $request = request();
  19. $approvalObjectType = ApprovalObjectType::from($request->object_type);
  20. $approvalObject = $approvalObjectType->modelBuilderAllowed($request->object_id)->findOrFail($request->object_id);
  21. $this->checkStatus($approvalObject, $approvalObjectType);
  22. $approvalFlow = $this->getApprovalFlow($approvalObjectType, $approvalObject);
  23. $containerFileIds = $request->get("file_ids", []);
  24. $this->createApproval($approvalFlow, $approvalObjectType, $approvalObject, $request->remark, $containerFileIds);
  25. }
  26. protected function createApproval(
  27. ApprovalFlow $approvalFlow,
  28. ApprovalObjectType $approvalObjectType,
  29. $approvalObject,
  30. string $remark = null,
  31. array $containerFileIds = [],
  32. ): void
  33. {
  34. $firstNode = $approvalFlow->nodes[1];
  35. $approval = Approval::query()->create([
  36. 'approval_flow_id' => $approvalFlow->id,
  37. 'object_type' => $approvalObjectType->flowType()->value,
  38. 'object_id' => $approvalObject->id,
  39. 'node_level' => $firstNode['level'],
  40. 'approval_mode' => $firstNode['approval_mode'],
  41. 'users' => sprintf(",%s,", implode(',', $firstNode['approval_users'])),
  42. 'remark' => $remark,
  43. 'created_by' => Auth::id(),
  44. 'status' => ObjectApprovalStatus::DOING,
  45. 'company_id' => Auth::user()->company_id,
  46. 'sub_object_ids' => $containerFileIds,
  47. ]);
  48. $extraFields = [
  49. 'now' => 0,
  50. 'next' => 1,
  51. 'approval_mode' => $firstNode['approval_mode'],
  52. ];
  53. if ($approval->approval_mode == ApprovalMode::SEQUENTIAL_APPROVAL->value) {
  54. $extraFields['next_sequential_user'] = $firstNode['approval_users'][0];
  55. }
  56. ActionRepository::createByApproval(
  57. $approval,
  58. ObjectAction::APPROVAL_REQUEST,
  59. extraFields: $extraFields,
  60. );
  61. $this->changeApprovalStatus($approvalObject, $approvalObjectType, $approval, $containerFileIds);
  62. }
  63. protected function checkStatus($approvalObject, ApprovalObjectType $approvalObjectType)
  64. {
  65. if ($approvalObjectType == ApprovalObjectType::CONTAINER_FILE) {
  66. return;
  67. }
  68. throw_validation_if(
  69. in_array($approvalObject?->approval_status, [ObjectApprovalStatus::DOING->value]),
  70. 'Do not initiate duplicate approvals'
  71. );
  72. }
  73. protected function changeApprovalStatus(
  74. $approvalObject, ApprovalObjectType $approvalObjectType, Approval $approval, array $containerFileIds = []
  75. ): void
  76. {
  77. if ($approvalObjectType == ApprovalObjectType::CONTAINER_FILE) {
  78. File::query()->whereIn("id", $containerFileIds)->update([
  79. 'approval_status' => ObjectApprovalStatus::DOING,
  80. 'latest_approval_id' => $approval->id,
  81. ]);
  82. return;
  83. }
  84. $approvalObject->approval_status = ObjectApprovalStatus::DOING;
  85. $approvalObject->save();
  86. }
  87. protected function getApprovalFlow(ApprovalObjectType $approvalObjectType, $approvalObject)
  88. {
  89. $approvalFlow = ApprovalFlow::query()
  90. ->where(function ($query) use ($approvalObjectType, $approvalObject) {
  91. $query->where([
  92. "type" => $approvalObjectType->flowType()->value,
  93. "object_id" => 0,
  94. ])
  95. ->when(
  96. $approvalObjectType->flowType() == ApprovalFlowType::TASK,
  97. fn ($query) => $query->orWhere(fn ($query) => $query->where([
  98. "type" => $approvalObjectType->flowType()->value,
  99. 'object_type' => ApprovalFlowObjectType::PROJECT->value,
  100. 'object_id' => $approvalObject->project_id,
  101. ]))
  102. );
  103. })
  104. ->where("status", 1)
  105. ->orderByDesc("object_id")
  106. ->first();
  107. throw_validation_if(! $approvalFlow, 'Clearly set up approval flow rules first.');
  108. return $approvalFlow;
  109. }
  110. }