|
@@ -3,10 +3,12 @@
|
|
|
namespace App\Services\Approval;
|
|
|
|
|
|
use App\Models\Approval;
|
|
|
+use App\Models\Enums\ApprovalMode;
|
|
|
use App\Models\Enums\ApprovalObjectType;
|
|
|
use App\Models\Enums\ObjectAction;
|
|
|
use App\Models\Enums\ObjectApprovalStatus;
|
|
|
use App\Repositories\ActionRepository;
|
|
|
+use Illuminate\Support\Facades\Auth;
|
|
|
|
|
|
class ActionService
|
|
|
{
|
|
@@ -14,15 +16,23 @@ class ActionService
|
|
|
|
|
|
protected array $actionExtraFields = [];
|
|
|
|
|
|
+ protected ?ObjectAction $objectAction = null;
|
|
|
+
|
|
|
public function action(Approval $approval, int $status, string $comment = null): void
|
|
|
{
|
|
|
$this->approval = $approval;
|
|
|
|
|
|
+ $this->actionExtraFields = [
|
|
|
+ 'now' => $this->approval->node_level
|
|
|
+ ];
|
|
|
+
|
|
|
match($status) {
|
|
|
1 => $this->approved(),
|
|
|
default => $this->rejected(),
|
|
|
};
|
|
|
|
|
|
+ $this->actionExtraFields['approval_mode'] = $this->approval->approval_mode;
|
|
|
+
|
|
|
$this->triggerAction($comment);
|
|
|
|
|
|
$this->changeApprovalObjectStatus();
|
|
@@ -47,15 +57,9 @@ class ActionService
|
|
|
|
|
|
protected function triggerAction (string $comment = null): void
|
|
|
{
|
|
|
- $objectAction = match ($this->approval->status) {
|
|
|
- ObjectApprovalStatus::APPROVED->value => ObjectAction::APPROVAL_APPROVED,
|
|
|
- ObjectApprovalStatus::DOING->value => ObjectAction::APPROVED_TO_NEXT_NODE,
|
|
|
- ObjectApprovalStatus::REJECTED->value => ObjectAction::APPROVAL_REJECTED,
|
|
|
- };
|
|
|
-
|
|
|
ActionRepository::createByApproval(
|
|
|
$this->approval,
|
|
|
- $objectAction,
|
|
|
+ $this->objectAction,
|
|
|
$comment,
|
|
|
extraFields: $this->actionExtraFields
|
|
|
);
|
|
@@ -65,20 +69,64 @@ class ActionService
|
|
|
{
|
|
|
$approvalFlowNodes = $this->approval->approvalFlow?->nodes;
|
|
|
$nextNodeIndex = $this->approval->node_level + 1;
|
|
|
- $nextNodes = $approvalFlowNodes[$nextNodeIndex] ?? [];
|
|
|
+ $nextNode = $approvalFlowNodes[$nextNodeIndex] ?? [];
|
|
|
+
|
|
|
+ $approvalObjectUsers = array_values(array_filter(explode(",", $this->approval->users), function($value) {
|
|
|
+ return $value != Auth::id() && $value;
|
|
|
+ }));
|
|
|
+
|
|
|
+ switch (ApprovalMode::tryFrom($this->approval->approval_mode)) {
|
|
|
+ case ApprovalMode::ALTERNATIVE_APPROVAL:
|
|
|
+ if (! $nextNode) {
|
|
|
+ $this->approvedHandle();
|
|
|
+ } else {
|
|
|
+ $this->approvedToNextNodeHandle($nextNodeIndex, $nextNode);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case ApprovalMode::COUNTERSIGNATURE:
|
|
|
+ case ApprovalMode::SEQUENTIAL_APPROVAL:
|
|
|
+ if (count($approvalObjectUsers) > 0 ) {
|
|
|
+ $this->approvedWaitOthers($approvalObjectUsers);
|
|
|
+ } elseif (! $nextNode) {
|
|
|
+ $this->approvedHandle();
|
|
|
+ } else {
|
|
|
+ $this->approvedToNextNodeHandle($nextNodeIndex, $nextNode);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function approvedWaitOthers(array $approvalObjectUsers)
|
|
|
+ {
|
|
|
+ $this->approval->users = sprintf(",%s,", implode(',', $approvalObjectUsers));
|
|
|
+
|
|
|
+ $this->objectAction = ObjectAction::APPROVED_WAIT_OTHERS;
|
|
|
|
|
|
- if (! $nextNodes) {
|
|
|
- $this->approval->status = ObjectApprovalStatus::APPROVED->value;
|
|
|
- return;
|
|
|
+ if ($this->approval->approval_mode == ApprovalMode::SEQUENTIAL_APPROVAL->value) {
|
|
|
+ $this->actionExtraFields['next_sequential_user'] = $approvalObjectUsers[0];
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- $this->actionExtraFields = [
|
|
|
- 'now' => $this->approval->node_level,
|
|
|
- 'next' => $nextNodeIndex,
|
|
|
- ];
|
|
|
+ protected function approvedHandle()
|
|
|
+ {
|
|
|
+ $this->approval->status = ObjectApprovalStatus::APPROVED->value;
|
|
|
+
|
|
|
+ $this->objectAction = ObjectAction::APPROVAL_APPROVED;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function approvedToNextNodeHandle(int $nextNodeIndex, array $nextNode)
|
|
|
+ {
|
|
|
+ $this->actionExtraFields['next'] = $nextNodeIndex;
|
|
|
|
|
|
$this->approval->node_level = $nextNodeIndex;
|
|
|
- $this->approval->users = sprintf(",%s,", implode(',', $nextNodes['approval_users']));
|
|
|
+ $this->approval->users = sprintf(",%s,", implode(',', $nextNode['approval_users']));
|
|
|
+ $this->approval->approval_mode = $nextNode['approval_mode'];
|
|
|
+
|
|
|
+ $this->objectAction = ObjectAction::APPROVED_TO_NEXT_NODE;
|
|
|
+
|
|
|
+ if ($this->approval->approval_mode == ApprovalMode::SEQUENTIAL_APPROVAL->value) {
|
|
|
+ $this->actionExtraFields['next_sequential_user'] = $nextNode['approval_users'][0];
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
protected function rejected(): void
|