StoreService.php 3.2 KB

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