StoreService.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. $approvalFlow = $this->getNewApprovalFlow($request->approvalFlow_id);
  24. $containerFileIds = $request->get("file_ids", []);
  25. $this->createApproval($approvalFlow, $approvalObjectType, $approvalObject, $request->remark, $containerFileIds);
  26. }
  27. protected function createApproval(
  28. ApprovalFlow $approvalFlow,
  29. ApprovalObjectType $approvalObjectType,
  30. $approvalObject,
  31. string $remark = null,
  32. array $containerFileIds = [],
  33. ): void
  34. {
  35. $firstNode = $approvalFlow->nodes[1];
  36. $approval = Approval::query()->create([
  37. 'approval_flow_id' => $approvalFlow->id,
  38. 'object_type' => $approvalObjectType->flowType()->value,
  39. 'object_id' => $approvalObject->id,
  40. 'node_level' => $firstNode['level'],
  41. 'approval_mode' => $firstNode['approval_mode'],
  42. 'users' => sprintf(",%s,", implode(',', $firstNode['approval_users'])),
  43. 'remark' => $remark,
  44. 'created_by' => Auth::id(),
  45. 'status' => ObjectApprovalStatus::DOING,
  46. 'company_id' => Auth::user()->company_id,
  47. 'sub_object_ids' => $containerFileIds,
  48. ]);
  49. $extraFields = [
  50. 'now' => 0,
  51. 'next' => 1,
  52. 'approval_mode' => $firstNode['approval_mode'],
  53. ];
  54. if ($approval->approval_mode == ApprovalMode::SEQUENTIAL_APPROVAL->value) {
  55. $extraFields['next_sequential_user'] = $firstNode['approval_users'][0];
  56. }
  57. ActionRepository::createByApproval(
  58. $approval,
  59. ObjectAction::APPROVAL_REQUEST,
  60. extraFields: $extraFields,
  61. );
  62. $this->changeApprovalStatus($approvalObject, $approvalObjectType, $approval, $containerFileIds);
  63. }
  64. protected function checkStatus($approvalObject, ApprovalObjectType $approvalObjectType)
  65. {
  66. if ($approvalObjectType == ApprovalObjectType::CONTAINER_FILE) {
  67. return;
  68. }
  69. throw_validation_if(
  70. in_array($approvalObject?->approval_status, [ObjectApprovalStatus::DOING->value]),
  71. 'Do not initiate duplicate approvals'
  72. );
  73. }
  74. protected function changeApprovalStatus(
  75. $approvalObject, ApprovalObjectType $approvalObjectType, Approval $approval, array $containerFileIds = []
  76. ): void
  77. {
  78. if ($approvalObjectType == ApprovalObjectType::CONTAINER_FILE) {
  79. File::query()->whereIn("id", $containerFileIds)->update([
  80. 'approval_status' => ObjectApprovalStatus::DOING,
  81. 'latest_approval_id' => $approval->id,
  82. ]);
  83. return;
  84. }
  85. $approvalObject->approval_status = ObjectApprovalStatus::DOING;
  86. $approvalObject->save();
  87. }
  88. protected function getApprovalFlow(ApprovalObjectType $approvalObjectType, $approvalObject)
  89. {
  90. $approvalFlow = ApprovalFlow::query()
  91. ->where(function ($query) use ($approvalObjectType, $approvalObject) {
  92. $query->where([
  93. "type" => $approvalObjectType->flowType()->value,
  94. "object_id" => 0,
  95. ])
  96. ->when(
  97. $approvalObjectType->flowType() == ApprovalFlowType::TASK,
  98. fn ($query) => $query->orWhere(fn ($query) => $query->where([
  99. "type" => $approvalObjectType->flowType()->value,
  100. 'object_type' => ApprovalFlowObjectType::PROJECT->value,
  101. 'object_id' => $approvalObject->project_id,
  102. ]))
  103. );
  104. })
  105. ->where("status", 1)
  106. ->orderByDesc("object_id")
  107. ->first();
  108. throw_validation_if(! $approvalFlow, 'Clearly set up approval flow rules first.');
  109. return $approvalFlow;
  110. }
  111. protected function getNewApprovalFlow($id)
  112. {
  113. $approvalFlow = ApprovalFlow::query() ->where("status", 1)->findOrFail($id);
  114. throw_validation_if(! $approvalFlow, 'Clearly set up approval flow rules first.');
  115. return $approvalFlow;
  116. }
  117. }