From 95f5ed44d6d201b8b62d0cb9ec228e0da0deb005 Mon Sep 17 00:00:00 2001 From: Adrian Hopek Date: Mon, 21 Mar 2022 15:29:20 +0100 Subject: [PATCH] - actions and notifications refactor (#88) * wip * fix * fix * fix * add test * fix * wip * fix * fix translations Co-authored-by: EwelinaLasowy --- .../Providers/EventServiceProvider.php | 33 +------ .../AcceptAsAdministrativeAction.php | 24 +++++ .../AcceptAsTechnicalAction.php | 33 +++++++ .../Actions/VacationRequest/ApproveAction.php | 42 ++++++++ .../Actions/VacationRequest/CancelAction.php | 42 ++++++++ .../Actions/VacationRequest/CreateAction.php | 98 +++++++++++++++++++ .../Actions/VacationRequest/RejectAction.php | 39 ++++++++ .../WaitForAdminApprovalAction.php | 39 ++++++++ .../WaitForTechApprovalAction.php | 39 ++++++++ ...acationRequestAcceptedByAdministrative.php | 19 ---- .../VacationRequestAcceptedByTechnical.php | 19 ---- app/Domain/Events/VacationRequestApproved.php | 19 ---- .../Events/VacationRequestCancelled.php | 19 ---- app/Domain/Events/VacationRequestCreated.php | 19 ---- app/Domain/Events/VacationRequestRejected.php | 19 ---- .../Events/VacationRequestStateChanged.php | 24 ----- .../VacationRequestWaitsForAdminApproval.php | 19 ---- .../VacationRequestWaitsForTechApproval.php | 19 ---- .../CreateVacationRequestActivity.php | 19 ---- ...cceptedByAdministrativeVacationRequest.php | 20 ---- ...ndleAcceptedByTechnicalVacationRequest.php | 30 ------ .../HandleApprovedVacationRequest.php | 16 --- .../HandleCancelledVacationRequest.php | 16 --- .../HandleCreatedVacationRequest.php | 42 -------- ...endApprovedVacationRequestNotification.php | 33 ------- ...ndCancelledVacationRequestNotification.php | 33 ------- ...SendCreatedVacationRequestNotification.php | 26 ----- ...endRejectedVacationRequestNotification.php | 33 ------- ...inistrativeVacationRequestNotification.php | 31 ------ ...orTechnicalVacationRequestNotification.php | 31 ------ .../VacationRequestCancelledNotification.php | 74 -------------- .../VacationRequestCreatedNotification.php | 45 +++++++-- ...VacationRequestCreatedOnEmployeeBehalf.php | 73 -------------- .../VacationRequestRejectedNotification.php | 74 -------------- ...ationRequestStatusChangedNotification.php} | 9 +- ...questWaitsForAdminApprovalNotification.php | 74 -------------- ...onRequestWaitsForApprovalNotification.php} | 2 +- .../VacationRequest/VacationRequestState.php | 5 + app/Domain/VacationRequestStateManager.php | 57 ++++------- .../Scopes/SelectedYearPeriodScope.php | 22 ----- .../Console/Commands/CreateUserCommand.php | 25 ----- .../Controllers/VacationLimitController.php | 1 + .../Controllers/VacationRequestController.php | 61 +++++------- ...18_remove_avatar_column_in_users_table.php | 23 +++++ resources/lang/pl.json | 19 +--- tests/Feature/VacationRequestTest.php | 34 +++---- .../Unit/VacationRequestNotificationTest.php | 58 +++++++++-- 47 files changed, 537 insertions(+), 1014 deletions(-) create mode 100644 app/Domain/Actions/VacationRequest/AcceptAsAdministrativeAction.php create mode 100644 app/Domain/Actions/VacationRequest/AcceptAsTechnicalAction.php create mode 100644 app/Domain/Actions/VacationRequest/ApproveAction.php create mode 100644 app/Domain/Actions/VacationRequest/CancelAction.php create mode 100644 app/Domain/Actions/VacationRequest/CreateAction.php create mode 100644 app/Domain/Actions/VacationRequest/RejectAction.php create mode 100644 app/Domain/Actions/VacationRequest/WaitForAdminApprovalAction.php create mode 100644 app/Domain/Actions/VacationRequest/WaitForTechApprovalAction.php delete mode 100644 app/Domain/Events/VacationRequestAcceptedByAdministrative.php delete mode 100644 app/Domain/Events/VacationRequestAcceptedByTechnical.php delete mode 100644 app/Domain/Events/VacationRequestApproved.php delete mode 100644 app/Domain/Events/VacationRequestCancelled.php delete mode 100644 app/Domain/Events/VacationRequestCreated.php delete mode 100644 app/Domain/Events/VacationRequestRejected.php delete mode 100644 app/Domain/Events/VacationRequestStateChanged.php delete mode 100644 app/Domain/Events/VacationRequestWaitsForAdminApproval.php delete mode 100644 app/Domain/Events/VacationRequestWaitsForTechApproval.php delete mode 100644 app/Domain/Listeners/CreateVacationRequestActivity.php delete mode 100644 app/Domain/Listeners/HandleAcceptedByAdministrativeVacationRequest.php delete mode 100644 app/Domain/Listeners/HandleAcceptedByTechnicalVacationRequest.php delete mode 100644 app/Domain/Listeners/HandleApprovedVacationRequest.php delete mode 100644 app/Domain/Listeners/HandleCancelledVacationRequest.php delete mode 100644 app/Domain/Listeners/HandleCreatedVacationRequest.php delete mode 100644 app/Domain/Listeners/SendApprovedVacationRequestNotification.php delete mode 100644 app/Domain/Listeners/SendCancelledVacationRequestNotification.php delete mode 100644 app/Domain/Listeners/SendCreatedVacationRequestNotification.php delete mode 100644 app/Domain/Listeners/SendRejectedVacationRequestNotification.php delete mode 100644 app/Domain/Listeners/SendWaitedForAdministrativeVacationRequestNotification.php delete mode 100644 app/Domain/Listeners/SendWaitedForTechnicalVacationRequestNotification.php delete mode 100644 app/Domain/Notifications/VacationRequestCancelledNotification.php delete mode 100644 app/Domain/Notifications/VacationRequestCreatedOnEmployeeBehalf.php delete mode 100644 app/Domain/Notifications/VacationRequestRejectedNotification.php rename app/Domain/Notifications/{VacationRequestApprovedNotification.php => VacationRequestStatusChangedNotification.php} (86%) delete mode 100644 app/Domain/Notifications/VacationRequestWaitsForAdminApprovalNotification.php rename app/Domain/Notifications/{VacationRequestWaitsForTechApprovalNotification.php => VacationRequestWaitsForApprovalNotification.php} (96%) delete mode 100644 app/Eloquent/Scopes/SelectedYearPeriodScope.php delete mode 100644 app/Infrastructure/Console/Commands/CreateUserCommand.php create mode 100644 database/migrations/2022_03_18_113018_remove_avatar_column_in_users_table.php diff --git a/app/Architecture/Providers/EventServiceProvider.php b/app/Architecture/Providers/EventServiceProvider.php index 3107b26..e1b1534 100644 --- a/app/Architecture/Providers/EventServiceProvider.php +++ b/app/Architecture/Providers/EventServiceProvider.php @@ -5,39 +5,8 @@ declare(strict_types=1); namespace Toby\Architecture\Providers; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; -use Toby\Domain\Events\VacationRequestAcceptedByAdministrative; -use Toby\Domain\Events\VacationRequestAcceptedByTechnical; -use Toby\Domain\Events\VacationRequestApproved; -use Toby\Domain\Events\VacationRequestCancelled; -use Toby\Domain\Events\VacationRequestCreated; -use Toby\Domain\Events\VacationRequestRejected; -use Toby\Domain\Events\VacationRequestStateChanged; -use Toby\Domain\Events\VacationRequestWaitsForAdminApproval; -use Toby\Domain\Events\VacationRequestWaitsForTechApproval; -use Toby\Domain\Listeners\CreateVacationRequestActivity; -use Toby\Domain\Listeners\HandleAcceptedByAdministrativeVacationRequest; -use Toby\Domain\Listeners\HandleAcceptedByTechnicalVacationRequest; -use Toby\Domain\Listeners\HandleApprovedVacationRequest; -use Toby\Domain\Listeners\HandleCancelledVacationRequest; -use Toby\Domain\Listeners\HandleCreatedVacationRequest; -use Toby\Domain\Listeners\SendApprovedVacationRequestNotification; -use Toby\Domain\Listeners\SendCancelledVacationRequestNotification; -use Toby\Domain\Listeners\SendCreatedVacationRequestNotification; -use Toby\Domain\Listeners\SendRejectedVacationRequestNotification; -use Toby\Domain\Listeners\SendWaitedForAdministrativeVacationRequestNotification; -use Toby\Domain\Listeners\SendWaitedForTechnicalVacationRequestNotification; class EventServiceProvider extends ServiceProvider { - protected $listen = [ - VacationRequestStateChanged::class => [CreateVacationRequestActivity::class], - VacationRequestCreated::class => [HandleCreatedVacationRequest::class, SendCreatedVacationRequestNotification::class], - VacationRequestAcceptedByTechnical::class => [HandleAcceptedByTechnicalVacationRequest::class], - VacationRequestAcceptedByAdministrative::class => [HandleAcceptedByAdministrativeVacationRequest::class], - VacationRequestApproved::class => [HandleApprovedVacationRequest::class, SendApprovedVacationRequestNotification::class], - VacationRequestRejected::class => [SendRejectedVacationRequestNotification::class], - VacationRequestCancelled::class => [HandleCancelledVacationRequest::class, SendCancelledVacationRequestNotification::class], - VacationRequestWaitsForTechApproval::class => [SendWaitedForTechnicalVacationRequestNotification::class], - VacationRequestWaitsForAdminApproval::class => [SendWaitedForAdministrativeVacationRequestNotification::class], - ]; + protected $listen = []; } diff --git a/app/Domain/Actions/VacationRequest/AcceptAsAdministrativeAction.php b/app/Domain/Actions/VacationRequest/AcceptAsAdministrativeAction.php new file mode 100644 index 0000000..33923e8 --- /dev/null +++ b/app/Domain/Actions/VacationRequest/AcceptAsAdministrativeAction.php @@ -0,0 +1,24 @@ +stateManager->acceptAsAdministrative($vacationRequest, $user); + + $this->approveAction->execute($vacationRequest); + } +} diff --git a/app/Domain/Actions/VacationRequest/AcceptAsTechnicalAction.php b/app/Domain/Actions/VacationRequest/AcceptAsTechnicalAction.php new file mode 100644 index 0000000..9660d6d --- /dev/null +++ b/app/Domain/Actions/VacationRequest/AcceptAsTechnicalAction.php @@ -0,0 +1,33 @@ +stateManager->acceptAsTechnical($vacationRequest, $user); + + if ($this->configRetriever->needsAdministrativeApproval($vacationRequest->type)) { + $this->waitForAdminApprovalAction->execute($vacationRequest); + + return; + } + + $this->approveAction->execute($vacationRequest); + } +} diff --git a/app/Domain/Actions/VacationRequest/ApproveAction.php b/app/Domain/Actions/VacationRequest/ApproveAction.php new file mode 100644 index 0000000..3d55542 --- /dev/null +++ b/app/Domain/Actions/VacationRequest/ApproveAction.php @@ -0,0 +1,42 @@ +stateManager->approve($vacationRequest, $user); + + SendVacationRequestDaysToGoogleCalendar::dispatch($vacationRequest); + + $this->notify($vacationRequest); + } + + protected function notify(VacationRequest $vacationRequest): void + { + $users = User::query() + ->where("id", "!=", $vacationRequest->user->id) + ->whereIn("role", [Role::TechnicalApprover, Role::AdministrativeApprover, Role::Administrator]) + ->get(); + + foreach ($users as $user) { + $user->notify(new VacationRequestStatusChangedNotification($vacationRequest, $user)); + } + + $vacationRequest->user->notify(new VacationRequestStatusChangedNotification($vacationRequest, $vacationRequest->user)); + } +} diff --git a/app/Domain/Actions/VacationRequest/CancelAction.php b/app/Domain/Actions/VacationRequest/CancelAction.php new file mode 100644 index 0000000..508f5b0 --- /dev/null +++ b/app/Domain/Actions/VacationRequest/CancelAction.php @@ -0,0 +1,42 @@ +stateManager->cancel($vacationRequest, $user); + + ClearVacationRequestDaysInGoogleCalendar::dispatch($vacationRequest); + + $this->notify($vacationRequest); + } + + protected function notify(VacationRequest $vacationRequest): void + { + $users = User::query() + ->where("id", "!=", $vacationRequest->user->id) + ->whereIn("role", [Role::TechnicalApprover, Role::AdministrativeApprover, Role::Administrator]) + ->get(); + + foreach ($users as $user) { + $user->notify(new VacationRequestStatusChangedNotification($vacationRequest, $user)); + } + + $vacationRequest->user->notify(new VacationRequestStatusChangedNotification($vacationRequest, $vacationRequest->user)); + } +} diff --git a/app/Domain/Actions/VacationRequest/CreateAction.php b/app/Domain/Actions/VacationRequest/CreateAction.php new file mode 100644 index 0000000..3915d6e --- /dev/null +++ b/app/Domain/Actions/VacationRequest/CreateAction.php @@ -0,0 +1,98 @@ +createVacationRequest($data, $creator); + $this->handleCreatedVacationRequest($vacationRequest); + $this->notify($vacationRequest); + + return $vacationRequest; + } + + /** + * @throws ValidationException + */ + protected function createVacationRequest(array $data, User $creator): VacationRequest + { + /** @var VacationRequest $vacationRequest */ + $vacationRequest = $creator->createdVacationRequests()->make($data); + + $this->vacationRequestValidator->validate($vacationRequest); + + $vacationRequest->save(); + + $days = $this->vacationDaysCalculator->calculateDays( + $vacationRequest->yearPeriod, + $vacationRequest->from, + $vacationRequest->to, + ); + + foreach ($days as $day) { + $vacationRequest->vacations()->create([ + "date" => $day, + "user_id" => $vacationRequest->user->id, + "year_period_id" => $vacationRequest->yearPeriod->id, + ]); + } + + $this->stateManager->markAsCreated($vacationRequest); + + return $vacationRequest; + } + + protected function handleCreatedVacationRequest(VacationRequest $vacationRequest): void + { + if ($vacationRequest->hasFlowSkipped()) { + $this->approveAction->execute($vacationRequest); + + return; + } + + if ($this->configRetriever->needsTechnicalApproval($vacationRequest->type)) { + $this->waitForTechApprovalAction->execute($vacationRequest); + + return; + } + + if ($this->configRetriever->needsAdministrativeApproval($vacationRequest->type)) { + $this->waitForAdminApprovalAction->execute($vacationRequest); + + return; + } + + $this->stateManager->approve($vacationRequest); + } + + protected function notify(VacationRequest $vacationRequest): void + { + $vacationRequest->user->notify(new VacationRequestCreatedNotification($vacationRequest)); + } +} diff --git a/app/Domain/Actions/VacationRequest/RejectAction.php b/app/Domain/Actions/VacationRequest/RejectAction.php new file mode 100644 index 0000000..8f6645b --- /dev/null +++ b/app/Domain/Actions/VacationRequest/RejectAction.php @@ -0,0 +1,39 @@ +stateManager->reject($vacationRequest, $user); + + $this->notify($vacationRequest); + } + + protected function notify(VacationRequest $vacationRequest): void + { + $users = User::query() + ->where("id", "!=", $vacationRequest->user->id) + ->whereIn("role", [Role::TechnicalApprover, Role::AdministrativeApprover, Role::Administrator]) + ->get(); + + foreach ($users as $user) { + $user->notify(new VacationRequestStatusChangedNotification($vacationRequest, $user)); + } + + $vacationRequest->user->notify(new VacationRequestStatusChangedNotification($vacationRequest, $vacationRequest->user)); + } +} diff --git a/app/Domain/Actions/VacationRequest/WaitForAdminApprovalAction.php b/app/Domain/Actions/VacationRequest/WaitForAdminApprovalAction.php new file mode 100644 index 0000000..833b470 --- /dev/null +++ b/app/Domain/Actions/VacationRequest/WaitForAdminApprovalAction.php @@ -0,0 +1,39 @@ +stateManager->waitForAdministrative($vacationRequest); + + $this->waitForAdminApprovers($vacationRequest); + } + + protected function waitForAdminApprovers(VacationRequest $vacationRequest): void + { + $users = User::query() + ->whereIn("role", [Role::AdministrativeApprover, Role::Administrator]) + ->get(); + + foreach ($users as $user) { + $user->notify(new VacationRequestWaitsForApprovalNotification($vacationRequest, $user)); + } + } +} diff --git a/app/Domain/Actions/VacationRequest/WaitForTechApprovalAction.php b/app/Domain/Actions/VacationRequest/WaitForTechApprovalAction.php new file mode 100644 index 0000000..1686698 --- /dev/null +++ b/app/Domain/Actions/VacationRequest/WaitForTechApprovalAction.php @@ -0,0 +1,39 @@ +stateManager->waitForTechnical($vacationRequest); + + $this->notifyTechApprovers($vacationRequest); + } + + protected function notifyTechApprovers(VacationRequest $vacationRequest): void + { + $users = User::query() + ->whereIn("role", [Role::TechnicalApprover, Role::Administrator]) + ->get(); + + foreach ($users as $user) { + $user->notify(new VacationRequestWaitsForApprovalNotification($vacationRequest, $user)); + } + } +} diff --git a/app/Domain/Events/VacationRequestAcceptedByAdministrative.php b/app/Domain/Events/VacationRequestAcceptedByAdministrative.php deleted file mode 100644 index e964e4f..0000000 --- a/app/Domain/Events/VacationRequestAcceptedByAdministrative.php +++ /dev/null @@ -1,19 +0,0 @@ -vacationRequest->activities()->create([ - "from" => $event->from, - "to" => $event->to, - "user_id" => $event->user?->id, - ]); - } -} diff --git a/app/Domain/Listeners/HandleAcceptedByAdministrativeVacationRequest.php b/app/Domain/Listeners/HandleAcceptedByAdministrativeVacationRequest.php deleted file mode 100644 index c7e082b..0000000 --- a/app/Domain/Listeners/HandleAcceptedByAdministrativeVacationRequest.php +++ /dev/null @@ -1,20 +0,0 @@ -stateManager->approve($event->vacationRequest); - } -} diff --git a/app/Domain/Listeners/HandleAcceptedByTechnicalVacationRequest.php b/app/Domain/Listeners/HandleAcceptedByTechnicalVacationRequest.php deleted file mode 100644 index 3883f98..0000000 --- a/app/Domain/Listeners/HandleAcceptedByTechnicalVacationRequest.php +++ /dev/null @@ -1,30 +0,0 @@ -vacationRequest; - - if ($this->configRetriever->needsAdministrativeApproval($vacationRequest->type)) { - $this->stateManager->waitForAdministrative($vacationRequest); - - return; - } - - $this->stateManager->approve($vacationRequest); - } -} diff --git a/app/Domain/Listeners/HandleApprovedVacationRequest.php b/app/Domain/Listeners/HandleApprovedVacationRequest.php deleted file mode 100644 index 2ece205..0000000 --- a/app/Domain/Listeners/HandleApprovedVacationRequest.php +++ /dev/null @@ -1,16 +0,0 @@ -vacationRequest); - } -} diff --git a/app/Domain/Listeners/HandleCancelledVacationRequest.php b/app/Domain/Listeners/HandleCancelledVacationRequest.php deleted file mode 100644 index 87d333d..0000000 --- a/app/Domain/Listeners/HandleCancelledVacationRequest.php +++ /dev/null @@ -1,16 +0,0 @@ -vacationRequest); - } -} diff --git a/app/Domain/Listeners/HandleCreatedVacationRequest.php b/app/Domain/Listeners/HandleCreatedVacationRequest.php deleted file mode 100644 index cfa64d3..0000000 --- a/app/Domain/Listeners/HandleCreatedVacationRequest.php +++ /dev/null @@ -1,42 +0,0 @@ -vacationRequest; - - if ($vacationRequest->hasFlowSkipped()) { - $this->stateManager->approve($vacationRequest); - - return; - } - - if ($this->configRetriever->needsTechnicalApproval($vacationRequest->type)) { - $this->stateManager->waitForTechnical($vacationRequest); - - return; - } - - if ($this->configRetriever->needsAdministrativeApproval($vacationRequest->type)) { - $this->stateManager->waitForAdministrative($vacationRequest); - - return; - } - - $this->stateManager->approve($vacationRequest); - } -} diff --git a/app/Domain/Listeners/SendApprovedVacationRequestNotification.php b/app/Domain/Listeners/SendApprovedVacationRequestNotification.php deleted file mode 100644 index b902326..0000000 --- a/app/Domain/Listeners/SendApprovedVacationRequestNotification.php +++ /dev/null @@ -1,33 +0,0 @@ -getUsersForNotifications() as $user) { - $user->notify(new VacationRequestApprovedNotification($event->vacationRequest, $user)); - } - - $event->vacationRequest->user->notify(new VacationRequestApprovedNotification($event->vacationRequest, $event->vacationRequest->user)); - } - - protected function getUsersForNotifications(): Collection - { - return User::query() - ->whereIn("role", [Role::TechnicalApprover, Role::AdministrativeApprover]) - ->get(); - } -} diff --git a/app/Domain/Listeners/SendCancelledVacationRequestNotification.php b/app/Domain/Listeners/SendCancelledVacationRequestNotification.php deleted file mode 100644 index a52cf20..0000000 --- a/app/Domain/Listeners/SendCancelledVacationRequestNotification.php +++ /dev/null @@ -1,33 +0,0 @@ -getUsersForNotifications() as $user) { - $user->notify(new VacationRequestCancelledNotification($event->vacationRequest, $user)); - } - - $event->vacationRequest->user->notify(new VacationRequestCancelledNotification($event->vacationRequest, $event->vacationRequest->user)); - } - - protected function getUsersForNotifications(): Collection - { - return User::query() - ->whereIn("role", [Role::TechnicalApprover, Role::AdministrativeApprover]) - ->get(); - } -} diff --git a/app/Domain/Listeners/SendCreatedVacationRequestNotification.php b/app/Domain/Listeners/SendCreatedVacationRequestNotification.php deleted file mode 100644 index 33d60c7..0000000 --- a/app/Domain/Listeners/SendCreatedVacationRequestNotification.php +++ /dev/null @@ -1,26 +0,0 @@ -vacationRequest; - - if ($vacationRequest->creator->is($vacationRequest->user)) { - $vacationRequest->user->notify(new VacationRequestCreatedNotification($vacationRequest)); - } else { - $vacationRequest->user->notify(new VacationRequestCreatedOnEmployeeBehalf($vacationRequest)); - } - } -} diff --git a/app/Domain/Listeners/SendRejectedVacationRequestNotification.php b/app/Domain/Listeners/SendRejectedVacationRequestNotification.php deleted file mode 100644 index bdbbdc7..0000000 --- a/app/Domain/Listeners/SendRejectedVacationRequestNotification.php +++ /dev/null @@ -1,33 +0,0 @@ -getUsersForNotifications() as $user) { - $user->notify(new VacationRequestRejectedNotification($event->vacationRequest, $user)); - } - - $event->vacationRequest->user->notify(new VacationRequestRejectedNotification($event->vacationRequest, $event->vacationRequest->user)); - } - - protected function getUsersForNotifications(): Collection - { - return User::query() - ->whereIn("role", [Role::TechnicalApprover, Role::AdministrativeApprover]) - ->get(); - } -} diff --git a/app/Domain/Listeners/SendWaitedForAdministrativeVacationRequestNotification.php b/app/Domain/Listeners/SendWaitedForAdministrativeVacationRequestNotification.php deleted file mode 100644 index f71885b..0000000 --- a/app/Domain/Listeners/SendWaitedForAdministrativeVacationRequestNotification.php +++ /dev/null @@ -1,31 +0,0 @@ -getUsersForNotifications() as $user) { - $user->notify(new VacationRequestWaitsForAdminApprovalNotification($event->vacationRequest, $user)); - } - } - - protected function getUsersForNotifications(): Collection - { - return User::query() - ->where("role", [Role::AdministrativeApprover]) - ->get(); - } -} diff --git a/app/Domain/Listeners/SendWaitedForTechnicalVacationRequestNotification.php b/app/Domain/Listeners/SendWaitedForTechnicalVacationRequestNotification.php deleted file mode 100644 index d2d11d9..0000000 --- a/app/Domain/Listeners/SendWaitedForTechnicalVacationRequestNotification.php +++ /dev/null @@ -1,31 +0,0 @@ -getUsersForNotifications() as $user) { - $user->notify(new VacationRequestWaitsForTechApprovalNotification($event->vacationRequest, $user)); - } - } - - protected function getUsersForNotifications(): Collection - { - return User::query() - ->where("role", [Role::TechnicalApprover]) - ->get(); - } -} diff --git a/app/Domain/Notifications/VacationRequestCancelledNotification.php b/app/Domain/Notifications/VacationRequestCancelledNotification.php deleted file mode 100644 index bb5d8f4..0000000 --- a/app/Domain/Notifications/VacationRequestCancelledNotification.php +++ /dev/null @@ -1,74 +0,0 @@ - $this->vacationRequest, - ], - ); - - return $this->buildMailMessage($url); - } - - protected function buildMailMessage(string $url): MailMessage - { - $user = $this->user->first_name; - $title = $this->vacationRequest->name; - $type = $this->vacationRequest->type->label(); - $from = $this->vacationRequest->from->toDisplayString(); - $to = $this->vacationRequest->to->toDisplayString(); - $days = $this->vacationRequest->vacations()->count(); - $requester = $this->vacationRequest->user->fullName; - - return (new MailMessage()) - ->greeting(__("Hi :user!", [ - "user" => $user, - ])) - ->subject(__("Vacation request :title has been cancelled", [ - "title" => $title, - ])) - ->line(__("The vacation request :title for user :requester has been cancelled.", [ - "title" => $title, - "requester" => $requester, - ])) - ->line(__("Vacation type: :type", [ - "type" => $type, - ])) - ->line(__("From :from to :to (number of days: :days)", [ - "from" => $from, - "to" => $to, - "days" => $days, - ])) - ->action(__("Click here for details"), $url); - } -} diff --git a/app/Domain/Notifications/VacationRequestCreatedNotification.php b/app/Domain/Notifications/VacationRequestCreatedNotification.php index 512191a..6166be6 100644 --- a/app/Domain/Notifications/VacationRequestCreatedNotification.php +++ b/app/Domain/Notifications/VacationRequestCreatedNotification.php @@ -40,24 +40,17 @@ class VacationRequestCreatedNotification extends Notification protected function buildMailMessage(string $url): MailMessage { $user = $this->vacationRequest->user->first_name; - $title = $this->vacationRequest->name; $type = $this->vacationRequest->type->label(); $from = $this->vacationRequest->from->toDisplayString(); $to = $this->vacationRequest->to->toDisplayString(); $days = $this->vacationRequest->vacations()->count(); - $appName = config("app.name"); return (new MailMessage()) ->greeting(__("Hi :user!", [ "user" => $user, ])) - ->subject(__("Vacation request :title has been created", [ - "title" => $title, - ])) - ->line(__("The vacation request :title has been created correctly in the :appName.", [ - "title" => $title, - "appName" => $appName, - ])) + ->subject($this->buildSubject()) + ->line($this->buildDescription()) ->line(__("Vacation type: :type", [ "type" => $type, ])) @@ -68,4 +61,38 @@ class VacationRequestCreatedNotification extends Notification ])) ->action(__("Click here for details"), $url); } + + protected function buildSubject(): string + { + $name = $this->vacationRequest->name; + + if ($this->vacationRequest->creator()->is($this->vacationRequest->user)) { + return __("Vacation request :title has been created", [ + "title" => $name, + ]); + } + + return __("Vacation request :title has been created on your behalf", [ + "title" => $name, + ]); + } + + protected function buildDescription(): string + { + $name = $this->vacationRequest->name; + $appName = config("app.name"); + + if ($this->vacationRequest->creator()->is($this->vacationRequest->user)) { + return __("The vacation request :title has been created correctly in the :appName.", [ + "title" => $name, + "appName" => $appName, + ]); + } + + return __("The vacation request :title has been created correctly by user :creator on your behalf in the :appName.", [ + "title" => $this->vacationRequest->name, + "appName" => $appName, + "creator" => $this->vacationRequest->creator->fullName, + ]); + } } diff --git a/app/Domain/Notifications/VacationRequestCreatedOnEmployeeBehalf.php b/app/Domain/Notifications/VacationRequestCreatedOnEmployeeBehalf.php deleted file mode 100644 index 4d2872a..0000000 --- a/app/Domain/Notifications/VacationRequestCreatedOnEmployeeBehalf.php +++ /dev/null @@ -1,73 +0,0 @@ - $this->vacationRequest, - ], - ); - return $this->buildMailMessage($url); - } - - protected function buildMailMessage(string $url): MailMessage - { - $creator = $this->vacationRequest->creator->fullName; - $user = $this->vacationRequest->user->first_name; - $title = $this->vacationRequest->name; - $type = $this->vacationRequest->type->label(); - $from = $this->vacationRequest->from->toDisplayString(); - $to = $this->vacationRequest->to->toDisplayString(); - $days = $this->vacationRequest->vacations()->count(); - $appName = config("app.name"); - - return (new MailMessage()) - ->greeting(__("Hi :user!", [ - "user" => $user, - ])) - ->subject(__("Vacation request :title has been created on your behalf", [ - "title" => $title, - ])) - ->line(__("The vacation request :title has been created correctly by user :creator on your behalf in the :appName.", [ - "title" => $title, - "appName" => $appName, - "creator" => $creator, - ])) - ->line(__("Vacation type: :type", [ - "type" => $type, - ])) - ->line(__("From :from to :to (number of days: :days)", [ - "from" => $from, - "to" => $to, - "days" => $days, - ])) - ->action(__("Click here for details"), $url); - } -} diff --git a/app/Domain/Notifications/VacationRequestRejectedNotification.php b/app/Domain/Notifications/VacationRequestRejectedNotification.php deleted file mode 100644 index e538cf9..0000000 --- a/app/Domain/Notifications/VacationRequestRejectedNotification.php +++ /dev/null @@ -1,74 +0,0 @@ - $this->vacationRequest, - ], - ); - - return $this->buildMailMessage($url); - } - - protected function buildMailMessage(string $url): MailMessage - { - $user = $this->user->first_name; - $title = $this->vacationRequest->name; - $type = $this->vacationRequest->type->label(); - $from = $this->vacationRequest->from->toDisplayString(); - $to = $this->vacationRequest->to->toDisplayString(); - $days = $this->vacationRequest->vacations()->count(); - $requester = $this->vacationRequest->user->fullName; - - return (new MailMessage()) - ->greeting(__("Hi :user!", [ - "user" => $user, - ])) - ->subject(__("Vacation request :title has been rejected", [ - "title" => $title, - ])) - ->line(__("The vacation request :title for user :requester has been rejected.", [ - "title" => $title, - "requester" => $requester, - ])) - ->line(__("Vacation type: :type", [ - "type" => $type, - ])) - ->line(__("From :from to :to (number of days: :days)", [ - "from" => $from, - "to" => $to, - "days" => $days, - ])) - ->action(__("Click here for details"), $url); - } -} diff --git a/app/Domain/Notifications/VacationRequestApprovedNotification.php b/app/Domain/Notifications/VacationRequestStatusChangedNotification.php similarity index 86% rename from app/Domain/Notifications/VacationRequestApprovedNotification.php rename to app/Domain/Notifications/VacationRequestStatusChangedNotification.php index b21b98c..cfe0673 100644 --- a/app/Domain/Notifications/VacationRequestApprovedNotification.php +++ b/app/Domain/Notifications/VacationRequestStatusChangedNotification.php @@ -11,7 +11,7 @@ use InvalidArgumentException; use Toby\Eloquent\Models\User; use Toby\Eloquent\Models\VacationRequest; -class VacationRequestApprovedNotification extends Notification +class VacationRequestStatusChangedNotification extends Notification { use Queueable; @@ -45,6 +45,7 @@ class VacationRequestApprovedNotification extends Notification $user = $this->user->first_name; $title = $this->vacationRequest->name; $type = $this->vacationRequest->type->label(); + $status = $this->vacationRequest->state->label(); $from = $this->vacationRequest->from->toDisplayString(); $to = $this->vacationRequest->to->toDisplayString(); $days = $this->vacationRequest->vacations()->count(); @@ -54,12 +55,14 @@ class VacationRequestApprovedNotification extends Notification ->greeting(__("Hi :user!", [ "user" => $user, ])) - ->subject(__("Vacation request :title has been approved", [ + ->subject(__("Vacation request :title has been :status", [ "title" => $title, + "status" => $status, ])) - ->line(__("The vacation request :title for user :requester has been approved.", [ + ->line(__("The vacation request :title for user :requester has been :status.", [ "title" => $title, "requester" => $requester, + "status" => $status, ])) ->line(__("Vacation type: :type", [ "type" => $type, diff --git a/app/Domain/Notifications/VacationRequestWaitsForAdminApprovalNotification.php b/app/Domain/Notifications/VacationRequestWaitsForAdminApprovalNotification.php deleted file mode 100644 index 4487cde..0000000 --- a/app/Domain/Notifications/VacationRequestWaitsForAdminApprovalNotification.php +++ /dev/null @@ -1,74 +0,0 @@ - $this->vacationRequest, - ], - ); - - return $this->buildMailMessage($url); - } - - protected function buildMailMessage(string $url): MailMessage - { - $user = $this->user->first_name; - $requester = $this->vacationRequest->user->fullName; - $title = $this->vacationRequest->name; - $type = $this->vacationRequest->type->label(); - $from = $this->vacationRequest->from->toDisplayString(); - $to = $this->vacationRequest->to->toDisplayString(); - $days = $this->vacationRequest->vacations()->count(); - - return (new MailMessage()) - ->greeting(__("Hi :user!", [ - "user" => $user, - ])) - ->subject(__("Vacation request :title is waiting for your approval", [ - "title" => $title, - ])) - ->line(__("The vacation request :title from user: :requester is waiting for your approval.", [ - "title" => $title, - "requester" => $requester, - ])) - ->line(__("Vacation type: :type", [ - "type" => $type, - ])) - ->line(__("From :from to :to (number of days: :days)", [ - "from" => $from, - "to" => $to, - "days" => $days, - ])) - ->action(__("Click here for details"), $url); - } -} diff --git a/app/Domain/Notifications/VacationRequestWaitsForTechApprovalNotification.php b/app/Domain/Notifications/VacationRequestWaitsForApprovalNotification.php similarity index 96% rename from app/Domain/Notifications/VacationRequestWaitsForTechApprovalNotification.php rename to app/Domain/Notifications/VacationRequestWaitsForApprovalNotification.php index f98cb85..4e9199c 100644 --- a/app/Domain/Notifications/VacationRequestWaitsForTechApprovalNotification.php +++ b/app/Domain/Notifications/VacationRequestWaitsForApprovalNotification.php @@ -11,7 +11,7 @@ use InvalidArgumentException; use Toby\Eloquent\Models\User; use Toby\Eloquent\Models\VacationRequest; -class VacationRequestWaitsForTechApprovalNotification extends Notification +class VacationRequestWaitsForApprovalNotification extends Notification { use Queueable; diff --git a/app/Domain/States/VacationRequest/VacationRequestState.php b/app/Domain/States/VacationRequest/VacationRequestState.php index b415b0b..6021583 100644 --- a/app/Domain/States/VacationRequest/VacationRequestState.php +++ b/app/Domain/States/VacationRequest/VacationRequestState.php @@ -36,4 +36,9 @@ abstract class VacationRequestState extends State Approved::class, ], Cancelled::class); } + + public function label(): string + { + return __(static::$name); + } } diff --git a/app/Domain/VacationRequestStateManager.php b/app/Domain/VacationRequestStateManager.php index ca61f52..10afcd0 100644 --- a/app/Domain/VacationRequestStateManager.php +++ b/app/Domain/VacationRequestStateManager.php @@ -4,17 +4,7 @@ declare(strict_types=1); namespace Toby\Domain; -use Illuminate\Contracts\Auth\Factory as Auth; use Illuminate\Contracts\Events\Dispatcher; -use Toby\Domain\Events\VacationRequestAcceptedByAdministrative; -use Toby\Domain\Events\VacationRequestAcceptedByTechnical; -use Toby\Domain\Events\VacationRequestApproved; -use Toby\Domain\Events\VacationRequestCancelled; -use Toby\Domain\Events\VacationRequestCreated; -use Toby\Domain\Events\VacationRequestRejected; -use Toby\Domain\Events\VacationRequestStateChanged; -use Toby\Domain\Events\VacationRequestWaitsForAdminApproval; -use Toby\Domain\Events\VacationRequestWaitsForTechApproval; use Toby\Domain\States\VacationRequest\AcceptedByAdministrative; use Toby\Domain\States\VacationRequest\AcceptedByTechnical; use Toby\Domain\States\VacationRequest\Approved; @@ -29,63 +19,47 @@ use Toby\Eloquent\Models\VacationRequest; class VacationRequestStateManager { public function __construct( - protected Auth $auth, protected Dispatcher $dispatcher, ) {} - public function markAsCreated(VacationRequest $vacationRequest, ?User $user = null): void + public function markAsCreated(VacationRequest $vacationRequest): void { - $this->fireStateChangedEvent($vacationRequest, null, $vacationRequest->state, $user); - - $this->dispatcher->dispatch(new VacationRequestCreated($vacationRequest)); + $this->createActivity($vacationRequest, null, $vacationRequest->state, $vacationRequest->creator); } public function approve(VacationRequest $vacationRequest, ?User $user = null): void { $this->changeState($vacationRequest, Approved::class, $user); - - $this->dispatcher->dispatch(new VacationRequestApproved($vacationRequest)); } - public function reject(VacationRequest $vacationRequest, ?User $user = null): void + public function reject(VacationRequest $vacationRequest, User $user): void { $this->changeState($vacationRequest, Rejected::class, $user); - $this->dispatcher->dispatch(new VacationRequestRejected($vacationRequest)); } - public function cancel(VacationRequest $vacationRequest, ?User $user = null): void + public function cancel(VacationRequest $vacationRequest, User $user): void { $this->changeState($vacationRequest, Cancelled::class, $user); - - $this->dispatcher->dispatch(new VacationRequestCancelled($vacationRequest)); } - public function acceptAsTechnical(VacationRequest $vacationRequest, ?User $user = null): void + public function acceptAsTechnical(VacationRequest $vacationRequest, User $user): void { $this->changeState($vacationRequest, AcceptedByTechnical::class, $user); - - $this->dispatcher->dispatch(new VacationRequestAcceptedByTechnical($vacationRequest)); } - public function acceptAsAdministrative(VacationRequest $vacationRequest, ?User $user = null): void + public function acceptAsAdministrative(VacationRequest $vacationRequest, User $user): void { $this->changeState($vacationRequest, AcceptedByAdministrative::class, $user); - - $this->dispatcher->dispatch(new VacationRequestAcceptedByAdministrative($vacationRequest)); } - public function waitForTechnical(VacationRequest $vacationRequest, ?User $user = null): void + public function waitForTechnical(VacationRequest $vacationRequest): void { - $this->changeState($vacationRequest, WaitingForTechnical::class, $user); - - $this->dispatcher->dispatch(new VacationRequestWaitsForTechApproval($vacationRequest)); + $this->changeState($vacationRequest, WaitingForTechnical::class); } - public function waitForAdministrative(VacationRequest $vacationRequest, ?User $user = null): void + public function waitForAdministrative(VacationRequest $vacationRequest): void { - $this->changeState($vacationRequest, WaitingForAdministrative::class, $user); - - $this->dispatcher->dispatch(new VacationRequestWaitsForAdminApproval($vacationRequest)); + $this->changeState($vacationRequest, WaitingForAdministrative::class); } protected function changeState(VacationRequest $vacationRequest, string $state, ?User $user = null): void @@ -94,16 +68,19 @@ class VacationRequestStateManager $vacationRequest->state->transitionTo($state); $vacationRequest->save(); - $this->fireStateChangedEvent($vacationRequest, $previousState, $vacationRequest->state, $user); + $this->createActivity($vacationRequest, $previousState, $vacationRequest->state, $user); } - protected function fireStateChangedEvent( + protected function createActivity( VacationRequest $vacationRequest, ?VacationRequestState $from, VacationRequestState $to, ?User $user = null, ): void { - $event = new VacationRequestStateChanged($vacationRequest, $from, $to, $user); - $this->dispatcher->dispatch($event); + $vacationRequest->activities()->create([ + "from" => $from, + "to" => $to, + "user_id" => $user?->id, + ]); } } diff --git a/app/Eloquent/Scopes/SelectedYearPeriodScope.php b/app/Eloquent/Scopes/SelectedYearPeriodScope.php deleted file mode 100644 index e278570..0000000 --- a/app/Eloquent/Scopes/SelectedYearPeriodScope.php +++ /dev/null @@ -1,22 +0,0 @@ -where("year_period_id", $this->yearPeriodRetriever->selected()->id); - } -} diff --git a/app/Infrastructure/Console/Commands/CreateUserCommand.php b/app/Infrastructure/Console/Commands/CreateUserCommand.php deleted file mode 100644 index b0092fd..0000000 --- a/app/Infrastructure/Console/Commands/CreateUserCommand.php +++ /dev/null @@ -1,25 +0,0 @@ -argument("email"); - - User::factory([ - "email" => $email, - ])->create(); - - $this->info("The user has been created"); - } -} diff --git a/app/Infrastructure/Http/Controllers/VacationLimitController.php b/app/Infrastructure/Http/Controllers/VacationLimitController.php index 8adf315..a56f2c3 100644 --- a/app/Infrastructure/Http/Controllers/VacationLimitController.php +++ b/app/Infrastructure/Http/Controllers/VacationLimitController.php @@ -25,6 +25,7 @@ class VacationLimitController extends Controller $limits = $yearPeriod ->vacationLimits() ->with("user") + ->has("user") ->orderByUserField("last_name") ->orderByUserField("first_name") ->get(); diff --git a/app/Infrastructure/Http/Controllers/VacationRequestController.php b/app/Infrastructure/Http/Controllers/VacationRequestController.php index 80a2cca..a11c1de 100644 --- a/app/Infrastructure/Http/Controllers/VacationRequestController.php +++ b/app/Infrastructure/Http/Controllers/VacationRequestController.php @@ -12,15 +12,17 @@ use Illuminate\Http\Request; use Illuminate\Http\Response as LaravelResponse; use Illuminate\Validation\ValidationException; use Inertia\Response; +use Toby\Domain\Actions\VacationRequest\AcceptAsAdministrativeAction; +use Toby\Domain\Actions\VacationRequest\AcceptAsTechnicalAction; +use Toby\Domain\Actions\VacationRequest\CancelAction; +use Toby\Domain\Actions\VacationRequest\CreateAction; +use Toby\Domain\Actions\VacationRequest\RejectAction; use Toby\Domain\Enums\VacationType; use Toby\Domain\States\VacationRequest\AcceptedByAdministrative; use Toby\Domain\States\VacationRequest\AcceptedByTechnical; use Toby\Domain\States\VacationRequest\Cancelled; use Toby\Domain\States\VacationRequest\Rejected; -use Toby\Domain\VacationDaysCalculator; -use Toby\Domain\VacationRequestStateManager; use Toby\Domain\VacationRequestStatesRetriever; -use Toby\Domain\Validation\VacationRequestValidator; use Toby\Eloquent\Helpers\YearPeriodRetriever; use Toby\Eloquent\Models\User; use Toby\Eloquent\Models\VacationRequest; @@ -91,7 +93,12 @@ class VacationRequestController extends Controller ->with(["user", "vacations"]) ->where("year_period_id", $yearPeriod->id) ->when($user !== null, fn(Builder $query) => $query->where("user_id", $user)) - ->when($status !== null, fn(Builder $query) => $query->states(VacationRequestStatesRetriever::filterByStatusGroup($status, $request->user()))) + ->when( + $status !== null, + fn(Builder $query) => $query->states( + VacationRequestStatesRetriever::filterByStatusGroup($status, $request->user()), + ), + ) ->latest() ->paginate(); @@ -179,12 +186,8 @@ class VacationRequestController extends Controller * @throws AuthorizationException * @throws ValidationException */ - public function store( - VacationRequestRequest $request, - VacationRequestValidator $vacationRequestValidator, - VacationRequestStateManager $stateManager, - VacationDaysCalculator $vacationDaysCalculator, - ): RedirectResponse { + public function store(VacationRequestRequest $request, CreateAction $createAction): RedirectResponse + { if ($request->createsOnBehalfOfEmployee()) { $this->authorize("createOnBehalfOfEmployee", VacationRequest::class); } @@ -193,27 +196,7 @@ class VacationRequestController extends Controller $this->authorize("skipFlow", VacationRequest::class); } - /** @var VacationRequest $vacationRequest */ - $vacationRequest = $request->user()->createdVacationRequests()->make($request->data()); - $vacationRequestValidator->validate($vacationRequest); - - $vacationRequest->save(); - - $days = $vacationDaysCalculator->calculateDays( - $vacationRequest->yearPeriod, - $vacationRequest->from, - $vacationRequest->to, - ); - - foreach ($days as $day) { - $vacationRequest->vacations()->create([ - "date" => $day, - "user_id" => $vacationRequest->user->id, - "year_period_id" => $vacationRequest->yearPeriod->id, - ]); - } - - $stateManager->markAsCreated($vacationRequest, $request->user()); + $vacationRequest = $createAction->execute($request->data(), $request->user()); return redirect() ->route("vacation.requests.show", $vacationRequest) @@ -226,11 +209,11 @@ class VacationRequestController extends Controller public function reject( Request $request, VacationRequest $vacationRequest, - VacationRequestStateManager $stateManager, + RejectAction $rejectAction, ): RedirectResponse { $this->authorize("reject", $vacationRequest); - $stateManager->reject($vacationRequest, $request->user()); + $rejectAction->execute($vacationRequest, $request->user()); return redirect()->back() ->with("success", __("Vacation request has been rejected.")); @@ -242,11 +225,11 @@ class VacationRequestController extends Controller public function cancel( Request $request, VacationRequest $vacationRequest, - VacationRequestStateManager $stateManager, + CancelAction $cancelAction, ): RedirectResponse { $this->authorize("cancel", $vacationRequest); - $stateManager->cancel($vacationRequest, $request->user()); + $cancelAction->execute($vacationRequest, $request->user()); return redirect()->back() ->with("success", __("Vacation request has been cancelled.")); @@ -258,11 +241,11 @@ class VacationRequestController extends Controller public function acceptAsTechnical( Request $request, VacationRequest $vacationRequest, - VacationRequestStateManager $stateManager, + AcceptAsTechnicalAction $acceptAsTechnicalAction, ): RedirectResponse { $this->authorize("acceptAsTechApprover", $vacationRequest); - $stateManager->acceptAsTechnical($vacationRequest, $request->user()); + $acceptAsTechnicalAction->execute($vacationRequest, $request->user()); return redirect()->back() ->with("success", __("Vacation request has been accepted.")); @@ -274,11 +257,11 @@ class VacationRequestController extends Controller public function acceptAsAdministrative( Request $request, VacationRequest $vacationRequest, - VacationRequestStateManager $stateManager, + AcceptAsAdministrativeAction $acceptAsAdministrativeAction, ): RedirectResponse { $this->authorize("acceptAsAdminApprover", $vacationRequest); - $stateManager->acceptAsAdministrative($vacationRequest, $request->user()); + $acceptAsAdministrativeAction->execute($vacationRequest, $request->user()); return redirect()->back() ->with("success", __("Vacation request has been accepted.")); diff --git a/database/migrations/2022_03_18_113018_remove_avatar_column_in_users_table.php b/database/migrations/2022_03_18_113018_remove_avatar_column_in_users_table.php new file mode 100644 index 0000000..7e0817b --- /dev/null +++ b/database/migrations/2022_03_18_113018_remove_avatar_column_in_users_table.php @@ -0,0 +1,23 @@ +dropColumn("avatar"); + }); + } + + public function down(): void + { + Schema::table("users", function (Blueprint $table): void { + $table->string("avatar")->nullable(); + }); + } +}; diff --git a/resources/lang/pl.json b/resources/lang/pl.json index 98c46cf..e4caa5e 100644 --- a/resources/lang/pl.json +++ b/resources/lang/pl.json @@ -18,14 +18,9 @@ "administrator": "Administrator", "technical_approver": "Techniczny akceptujący", "administrative_approver": "Administracyjny akceptujący", - "created": "Utworzony", - "cancelled": "Anulowany", - "rejected": "Odrzucony", - "approved": "Zatwierdzony", - "waiting_for_technical": "Czeka na akceptację od technicznego", - "waiting_for_administrative": "Czeka na akceptację od administracyjnego", - "accepted_by_technical": "Zaakceptowany przez technicznego", - "accepted_by_administrative": "Zaakceptowany przez administracyjnego", + "cancelled": "anulowany", + "rejected": "odrzucony", + "approved": "zatwierdzony", "You have pending vacation request in this range.": "Masz oczekujący wniosek urlopowy w tym zakresie dat.", "You have approved vacation request in this range.": "Masz zaakceptowany wniosek urlopowy w tym zakresie dat.", "Vacation limit has been exceeded.": "Limit urlopu został przekroczony.", @@ -65,12 +60,8 @@ "Click here for details": "Kliknij, aby zobaczyć szczegóły", "Vacation request :title is waiting for your approval": "Wniosek urlopowy :title czeka na zaakceptowanie", "The vacation request :title from user: :requester is waiting for your approval.": "Wniosek urlopowy :title od użytkownika :requester czeka na Twoją akceptację.", - "Vacation request :title has been approved": "Wniosek urlopowy :title został zatwierdzony", - "The vacation request :title for user :requester has been approved.": "Wniosek urlopowy :title od użytkownika :requester został zatwierdzony.", - "Vacation request :title has been cancelled": "Wniosek urlopowy :title został anulowany", - "The vacation request :title for user :requester has been cancelled.": "Wniosek urlopowy :title od użytkownika :requester został anulowany.", - "Vacation request :title has been rejected": "Wniosek urlopowy :title został odrzucony", - "The vacation request :title for user :requester has been rejected.": "Wniosek urlopowy :title od użytkownika :requester został odrzucony.", + "Vacation request :title has been :status": "Wniosek urlopowy :title został :status", + "The vacation request :title for user :requester has been :status.": "Wniosek urlopowy :title od użytkownika :requester został :status.", "Vacation request :title has been created on your behalf": "Wniosek urlopowy :title został utworzony w Twoim imieniu", "The vacation request :title has been created correctly by user :creator on your behalf in the :appName.": "W systemie :appName został poprawnie utworzony wniosek urlopowy :title w Twoim imieniu przez użytkownika :creator." } diff --git a/tests/Feature/VacationRequestTest.php b/tests/Feature/VacationRequestTest.php index 7dbca66..07bf8a5 100644 --- a/tests/Feature/VacationRequestTest.php +++ b/tests/Feature/VacationRequestTest.php @@ -6,14 +6,11 @@ namespace Tests\Feature; use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Support\Carbon; -use Illuminate\Support\Facades\Event; +use Illuminate\Support\Facades\Bus; +use Illuminate\Support\Facades\Notification; use Inertia\Testing\AssertableInertia as Assert; use Tests\FeatureTestCase; use Toby\Domain\Enums\VacationType; -use Toby\Domain\Events\VacationRequestAcceptedByAdministrative; -use Toby\Domain\Events\VacationRequestAcceptedByTechnical; -use Toby\Domain\Events\VacationRequestApproved; -use Toby\Domain\Events\VacationRequestRejected; use Toby\Domain\PolishHolidaysRetriever; use Toby\Domain\States\VacationRequest\Approved; use Toby\Domain\States\VacationRequest\Rejected; @@ -34,6 +31,9 @@ class VacationRequestTest extends FeatureTestCase { parent::setUp(); + Bus::fake(); + Notification::fake(); + $this->polishHolidaysRetriever = $this->app->make(PolishHolidaysRetriever::class); } @@ -130,8 +130,6 @@ class VacationRequestTest extends FeatureTestCase public function testUserCanCreateVacationRequestOnEmployeeBehalfAndSkipAcceptanceFlow(): void { - Event::fake(VacationRequestApproved::class); - $creator = User::factory()->admin()->createQuietly(); $user = User::factory()->createQuietly(); @@ -169,8 +167,6 @@ class VacationRequestTest extends FeatureTestCase public function testTechnicalApproverCanApproveVacationRequest(): void { - Event::fake(VacationRequestAcceptedByTechnical::class); - $user = User::factory()->createQuietly(); $technicalApprover = User::factory()->technicalApprover()->createQuietly(); $currentYearPeriod = YearPeriod::current(); @@ -187,13 +183,13 @@ class VacationRequestTest extends FeatureTestCase ->post("/vacation-requests/{$vacationRequest->id}/accept-as-technical") ->assertSessionHasNoErrors(); - Event::assertDispatched(VacationRequestAcceptedByTechnical::class); + $vacationRequest->refresh(); + + $this->assertTrue($vacationRequest->state->equals(WaitingForAdministrative::class)); } public function testAdministrativeApproverCanApproveVacationRequest(): void { - Event::fake(VacationRequestAcceptedByAdministrative::class); - $user = User::factory()->createQuietly(); $administrativeApprover = User::factory()->administrativeApprover()->createQuietly(); @@ -210,13 +206,13 @@ class VacationRequestTest extends FeatureTestCase ->post("/vacation-requests/{$vacationRequest->id}/accept-as-administrative") ->assertSessionHasNoErrors(); - Event::assertDispatched(VacationRequestAcceptedByAdministrative::class); + $vacationRequest->refresh(); + + $this->assertTrue($vacationRequest->state->equals(Approved::class)); } public function testTechnicalApproverCanRejectVacationRequest(): void { - Event::fake(VacationRequestRejected::class); - $user = User::factory()->createQuietly(); $technicalApprover = User::factory()->technicalApprover()->createQuietly(); $currentYearPeriod = YearPeriod::current(); @@ -228,6 +224,7 @@ class VacationRequestTest extends FeatureTestCase ->for($currentYearPeriod) ->create(); + /** @var VacationRequest $vacationRequest */ $vacationRequest = VacationRequest::factory([ "state" => WaitingForTechnical::class, "type" => VacationType::Vacation, @@ -240,10 +237,9 @@ class VacationRequestTest extends FeatureTestCase ->post("/vacation-requests/{$vacationRequest->id}/reject") ->assertSessionHasNoErrors(); - Event::assertDispatched(VacationRequestRejected::class); - $this->assertDatabaseHas("vacation_requests", [ - "state" => Rejected::$name, - ]); + $vacationRequest->refresh(); + + $this->assertTrue($vacationRequest->state->equals(Rejected::class)); } public function testUserCannotCreateVacationRequestIfHeExceedsHisVacationLimit(): void diff --git a/tests/Unit/VacationRequestNotificationTest.php b/tests/Unit/VacationRequestNotificationTest.php index 0a59f51..18c4035 100644 --- a/tests/Unit/VacationRequestNotificationTest.php +++ b/tests/Unit/VacationRequestNotificationTest.php @@ -9,11 +9,14 @@ use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Notification; use Tests\TestCase; use Tests\Traits\InteractsWithYearPeriods; +use Toby\Domain\Actions\VacationRequest\RejectAction; +use Toby\Domain\Actions\VacationRequest\WaitForTechApprovalAction; use Toby\Domain\Enums\Role; use Toby\Domain\Enums\VacationType; -use Toby\Domain\Notifications\VacationRequestWaitsForTechApprovalNotification; +use Toby\Domain\Notifications\VacationRequestStatusChangedNotification; +use Toby\Domain\Notifications\VacationRequestWaitsForApprovalNotification; use Toby\Domain\States\VacationRequest\Created; -use Toby\Domain\VacationRequestStateManager; +use Toby\Domain\States\VacationRequest\WaitingForTechnical; use Toby\Eloquent\Models\User; use Toby\Eloquent\Models\VacationRequest; use Toby\Eloquent\Models\YearPeriod; @@ -23,14 +26,10 @@ class VacationRequestNotificationTest extends TestCase use DatabaseMigrations; use InteractsWithYearPeriods; - protected VacationRequestStateManager $stateManager; - protected function setUp(): void { parent::setUp(); - $this->stateManager = $this->app->make(VacationRequestStateManager::class); - $this->createCurrentYearPeriod(); } @@ -47,6 +46,9 @@ class VacationRequestNotificationTest extends TestCase $administrativeApprover = User::factory([ "role" => Role::AdministrativeApprover, ])->createQuietly(); + $admin = User::factory([ + "role" => Role::Administrator, + ])->createQuietly(); $currentYearPeriod = YearPeriod::current(); @@ -62,9 +64,47 @@ class VacationRequestNotificationTest extends TestCase ->for($currentYearPeriod) ->create(); - $this->stateManager->waitForTechnical($vacationRequest); + $waitForTechApprovalAction = $this->app->make(WaitForTechApprovalAction::class); - Notification::assertSentTo($technicalApprover, VacationRequestWaitsForTechApprovalNotification::class); - Notification::assertNotSentTo([$user, $administrativeApprover], VacationRequestWaitsForTechApprovalNotification::class); + $waitForTechApprovalAction->execute($vacationRequest); + + Notification::assertSentTo([$technicalApprover, $admin], VacationRequestWaitsForApprovalNotification::class); + Notification::assertNotSentTo([$user, $administrativeApprover], VacationRequestWaitsForApprovalNotification::class); + } + + public function testNotificationIsSentOnceToUser(): void + { + Notification::fake(); + + $technicalApprover = User::factory([ + "role" => Role::TechnicalApprover, + ])->createQuietly(); + $administrativeApprover = User::factory([ + "role" => Role::AdministrativeApprover, + ])->createQuietly(); + $admin = User::factory([ + "role" => Role::Administrator, + ])->createQuietly(); + + $currentYearPeriod = YearPeriod::current(); + + /** @var VacationRequest $vacationRequest */ + $vacationRequest = VacationRequest::factory([ + "type" => VacationType::Vacation->value, + "state" => WaitingForTechnical::class, + "from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(), + "to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(), + "comment" => "Comment for the vacation request.", + ]) + ->for($administrativeApprover) + ->for($currentYearPeriod) + ->create(); + + $rejectAction = $this->app->make(RejectAction::class); + + $rejectAction->execute($vacationRequest, $technicalApprover); + + Notification::assertSentTo([$technicalApprover, $admin, $administrativeApprover], VacationRequestStatusChangedNotification::class); + Notification::assertTimesSent(3, VacationRequestStatusChangedNotification::class); } }