StoreService.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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. $list = File::query()->whereIn("id", $containerFileIds)->get();
  80. foreach ($list as $value){
  81. $approval_status = $value->approval_status == ObjectApprovalStatus::REJECTED->value ? ObjectApprovalStatus::RESUBMISSION->value : ObjectApprovalStatus::DOING->value;
  82. File::query()->where("id", $value->id)->update([
  83. 'approval_status' => $approval_status,
  84. 'latest_approval_id' => $approval->id,
  85. ]);
  86. }
  87. return;
  88. }
  89. $approvalObject->approval_status = ObjectApprovalStatus::DOING;
  90. $approvalObject->save();
  91. }
  92. protected function getApprovalFlow(ApprovalObjectType $approvalObjectType, $approvalObject)
  93. {
  94. $approvalFlow = ApprovalFlow::query()
  95. ->where(function ($query) use ($approvalObjectType, $approvalObject) {
  96. $query->where([
  97. "type" => $approvalObjectType->flowType()->value,
  98. "object_id" => 0,
  99. ])
  100. ->when(
  101. $approvalObjectType->flowType() == ApprovalFlowType::TASK,
  102. fn ($query) => $query->orWhere(fn ($query) => $query->where([
  103. "type" => $approvalObjectType->flowType()->value,
  104. 'object_type' => ApprovalFlowObjectType::PROJECT->value,
  105. 'object_id' => $approvalObject->project_id,
  106. ]))
  107. );
  108. })
  109. ->where("status", 1)
  110. ->orderByDesc("object_id")
  111. ->first();
  112. throw_validation_if(! $approvalFlow, 'Clearly set up approval flow rules first.');
  113. return $approvalFlow;
  114. }
  115. protected function getNewApprovalFlow($id)
  116. {
  117. $approvalFlow = ApprovalFlow::query() ->where("status", 1)->findOrFail($id);
  118. throw_validation_if(! $approvalFlow, 'Clearly set up approval flow rules first.');
  119. return $approvalFlow;
  120. }
  121. }