StoreService.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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\Repositories\ActionRepository;
  12. use Illuminate\Support\Facades\Auth;
  13. class StoreService
  14. {
  15. public function store()
  16. {
  17. $request = request();
  18. $approvalObjectType = ApprovalObjectType::from($request->object_type);
  19. $approvalObject = $approvalObjectType->modelBuilderAllowed($request->object_id)->findOrFail($request->object_id);
  20. throw_validation_if(
  21. in_array($approvalObject?->approval_status, [ObjectApprovalStatus::DOING->value]),
  22. 'Do not initiate duplicate approvals'
  23. );
  24. $approvalFlow = $this->getApprovalFlow($approvalObjectType, $approvalObject);
  25. $this->createApproval($approvalFlow, $approvalObjectType, $approvalObject->id, $request->remark);
  26. $this->changeApprovalStatus($approvalObject);
  27. }
  28. protected function createApproval(
  29. ApprovalFlow $approvalFlow, ApprovalObjectType $approvalObjectType, int $objectId, string $remark = null
  30. ): void
  31. {
  32. $firstNode = $approvalFlow->nodes[1];
  33. $approval = Approval::query()->create([
  34. 'approval_flow_id' => $approvalFlow->id,
  35. 'object_type' => $approvalObjectType->flowType()->value,
  36. 'object_id' => $objectId,
  37. 'node_level' => $firstNode['level'],
  38. 'approval_mode' => $firstNode['approval_mode'],
  39. 'users' => sprintf(",%s,", implode(',', $firstNode['approval_users'])),
  40. 'remark' => $remark,
  41. 'created_by' => Auth::id(),
  42. 'status' => ObjectApprovalStatus::DOING,
  43. 'company_id' => Auth::user()->company_id,
  44. ]);
  45. $extraFields = [
  46. 'now' => 0,
  47. 'next' => 1,
  48. 'approval_mode' => $firstNode['approval_mode'],
  49. ];
  50. if ($approval->approval_mode == ApprovalMode::SEQUENTIAL_APPROVAL->value) {
  51. $extraFields['next_sequential_user'] = $firstNode['approval_users'][0];
  52. }
  53. ActionRepository::createByApproval(
  54. $approval,
  55. ObjectAction::APPROVAL_REQUEST,
  56. extraFields: $extraFields,
  57. );
  58. }
  59. protected function changeApprovalStatus($approvalObject): void
  60. {
  61. $approvalObject->approval_status = ObjectApprovalStatus::DOING;
  62. $approvalObject->save();
  63. }
  64. protected function getApprovalFlow(ApprovalObjectType $approvalObjectType, $approvalObject)
  65. {
  66. $approvalFlow = ApprovalFlow::query()
  67. ->where(function ($query) use ($approvalObjectType, $approvalObject) {
  68. $query->where([
  69. "type" => $approvalObjectType->flowType()->value,
  70. "object_id" => 0,
  71. ])
  72. ->when(
  73. $approvalObjectType->flowType() == ApprovalFlowType::TASK,
  74. fn ($query) => $query->orWhere(fn ($query) => $query->where([
  75. "type" => $approvalObjectType->flowType()->value,
  76. 'object_type' => ApprovalFlowObjectType::PROJECT->value,
  77. 'object_id' => $approvalObject->project_id,
  78. ]))
  79. );
  80. })
  81. ->where("status", 1)
  82. ->orderByDesc("object_id")
  83. ->first();
  84. throw_validation_if(! $approvalFlow, 'Clearly set up approval flow rules first.');
  85. return $approvalFlow;
  86. }
  87. }