- actions and notifications refactor (#88)
* wip * fix * fix * fix * add test * fix * wip * fix * fix translations Co-authored-by: EwelinaLasowy <ewelina.lasowy@blumilk.pl>
This commit is contained in:
		| @@ -5,39 +5,8 @@ declare(strict_types=1); | |||||||
| namespace Toby\Architecture\Providers; | namespace Toby\Architecture\Providers; | ||||||
|  |  | ||||||
| use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; | 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 | class EventServiceProvider extends ServiceProvider | ||||||
| { | { | ||||||
|     protected $listen = [ |     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], |  | ||||||
|     ]; |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Domain\Actions\VacationRequest; | ||||||
|  |  | ||||||
|  | use Toby\Domain\VacationRequestStateManager; | ||||||
|  | use Toby\Eloquent\Models\User; | ||||||
|  | use Toby\Eloquent\Models\VacationRequest; | ||||||
|  |  | ||||||
|  | class AcceptAsAdministrativeAction | ||||||
|  | { | ||||||
|  |     public function __construct( | ||||||
|  |         protected VacationRequestStateManager $stateManager, | ||||||
|  |         protected ApproveAction $approveAction, | ||||||
|  |     ) {} | ||||||
|  |  | ||||||
|  |     public function execute(VacationRequest $vacationRequest, User $user): void | ||||||
|  |     { | ||||||
|  |         $this->stateManager->acceptAsAdministrative($vacationRequest, $user); | ||||||
|  |  | ||||||
|  |         $this->approveAction->execute($vacationRequest); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,33 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Domain\Actions\VacationRequest; | ||||||
|  |  | ||||||
|  | use Toby\Domain\VacationRequestStateManager; | ||||||
|  | use Toby\Domain\VacationTypeConfigRetriever; | ||||||
|  | use Toby\Eloquent\Models\User; | ||||||
|  | use Toby\Eloquent\Models\VacationRequest; | ||||||
|  |  | ||||||
|  | class AcceptAsTechnicalAction | ||||||
|  | { | ||||||
|  |     public function __construct( | ||||||
|  |         protected VacationRequestStateManager $stateManager, | ||||||
|  |         protected VacationTypeConfigRetriever $configRetriever, | ||||||
|  |         protected WaitForAdminApprovalAction $waitForAdminApprovalAction, | ||||||
|  |         protected ApproveAction $approveAction, | ||||||
|  |     ) {} | ||||||
|  |  | ||||||
|  |     public function execute(VacationRequest $vacationRequest, User $user): void | ||||||
|  |     { | ||||||
|  |         $this->stateManager->acceptAsTechnical($vacationRequest, $user); | ||||||
|  |  | ||||||
|  |         if ($this->configRetriever->needsAdministrativeApproval($vacationRequest->type)) { | ||||||
|  |             $this->waitForAdminApprovalAction->execute($vacationRequest); | ||||||
|  |  | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $this->approveAction->execute($vacationRequest); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								app/Domain/Actions/VacationRequest/ApproveAction.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								app/Domain/Actions/VacationRequest/ApproveAction.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Domain\Actions\VacationRequest; | ||||||
|  |  | ||||||
|  | use Toby\Domain\Enums\Role; | ||||||
|  | use Toby\Domain\Notifications\VacationRequestStatusChangedNotification; | ||||||
|  | use Toby\Domain\VacationRequestStateManager; | ||||||
|  | use Toby\Eloquent\Models\User; | ||||||
|  | use Toby\Eloquent\Models\VacationRequest; | ||||||
|  | use Toby\Infrastructure\Jobs\SendVacationRequestDaysToGoogleCalendar; | ||||||
|  |  | ||||||
|  | class ApproveAction | ||||||
|  | { | ||||||
|  |     public function __construct( | ||||||
|  |         protected VacationRequestStateManager $stateManager, | ||||||
|  |     ) {} | ||||||
|  |  | ||||||
|  |     public function execute(VacationRequest $vacationRequest, ?User $user = null): void | ||||||
|  |     { | ||||||
|  |         $this->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)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								app/Domain/Actions/VacationRequest/CancelAction.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								app/Domain/Actions/VacationRequest/CancelAction.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Domain\Actions\VacationRequest; | ||||||
|  |  | ||||||
|  | use Toby\Domain\Enums\Role; | ||||||
|  | use Toby\Domain\Notifications\VacationRequestStatusChangedNotification; | ||||||
|  | use Toby\Domain\VacationRequestStateManager; | ||||||
|  | use Toby\Eloquent\Models\User; | ||||||
|  | use Toby\Eloquent\Models\VacationRequest; | ||||||
|  | use Toby\Infrastructure\Jobs\ClearVacationRequestDaysInGoogleCalendar; | ||||||
|  |  | ||||||
|  | class CancelAction | ||||||
|  | { | ||||||
|  |     public function __construct( | ||||||
|  |         protected VacationRequestStateManager $stateManager, | ||||||
|  |     ) {} | ||||||
|  |  | ||||||
|  |     public function execute(VacationRequest $vacationRequest, User $user): void | ||||||
|  |     { | ||||||
|  |         $this->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)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										98
									
								
								app/Domain/Actions/VacationRequest/CreateAction.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								app/Domain/Actions/VacationRequest/CreateAction.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Domain\Actions\VacationRequest; | ||||||
|  |  | ||||||
|  | use Illuminate\Validation\ValidationException; | ||||||
|  | use Toby\Domain\Notifications\VacationRequestCreatedNotification; | ||||||
|  | use Toby\Domain\VacationDaysCalculator; | ||||||
|  | use Toby\Domain\VacationRequestStateManager; | ||||||
|  | use Toby\Domain\VacationTypeConfigRetriever; | ||||||
|  | use Toby\Domain\Validation\VacationRequestValidator; | ||||||
|  | use Toby\Eloquent\Models\User; | ||||||
|  | use Toby\Eloquent\Models\VacationRequest; | ||||||
|  |  | ||||||
|  | class CreateAction | ||||||
|  | { | ||||||
|  |     public function __construct( | ||||||
|  |         protected VacationRequestStateManager $stateManager, | ||||||
|  |         protected VacationRequestValidator $vacationRequestValidator, | ||||||
|  |         protected VacationTypeConfigRetriever $configRetriever, | ||||||
|  |         protected VacationDaysCalculator $vacationDaysCalculator, | ||||||
|  |         protected WaitForTechApprovalAction $waitForTechApprovalAction, | ||||||
|  |         protected WaitForAdminApprovalAction $waitForAdminApprovalAction, | ||||||
|  |         protected ApproveAction $approveAction, | ||||||
|  |     ) {} | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @throws ValidationException | ||||||
|  |      */ | ||||||
|  |     public function execute(array $data, User $creator): VacationRequest | ||||||
|  |     { | ||||||
|  |         $vacationRequest = $this->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)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								app/Domain/Actions/VacationRequest/RejectAction.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/Domain/Actions/VacationRequest/RejectAction.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Domain\Actions\VacationRequest; | ||||||
|  |  | ||||||
|  | use Toby\Domain\Enums\Role; | ||||||
|  | use Toby\Domain\Notifications\VacationRequestStatusChangedNotification; | ||||||
|  | use Toby\Domain\VacationRequestStateManager; | ||||||
|  | use Toby\Eloquent\Models\User; | ||||||
|  | use Toby\Eloquent\Models\VacationRequest; | ||||||
|  |  | ||||||
|  | class RejectAction | ||||||
|  | { | ||||||
|  |     public function __construct( | ||||||
|  |         protected VacationRequestStateManager $stateManager, | ||||||
|  |     ) {} | ||||||
|  |  | ||||||
|  |     public function execute(VacationRequest $vacationRequest, User $user): void | ||||||
|  |     { | ||||||
|  |         $this->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)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,39 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Domain\Actions\VacationRequest; | ||||||
|  |  | ||||||
|  | use Toby\Domain\Enums\Role; | ||||||
|  | use Toby\Domain\Notifications\VacationRequestWaitsForApprovalNotification; | ||||||
|  | use Toby\Domain\VacationRequestStateManager; | ||||||
|  | use Toby\Domain\VacationTypeConfigRetriever; | ||||||
|  | use Toby\Eloquent\Models\User; | ||||||
|  | use Toby\Eloquent\Models\VacationRequest; | ||||||
|  |  | ||||||
|  | class WaitForAdminApprovalAction | ||||||
|  | { | ||||||
|  |     public function __construct( | ||||||
|  |         protected VacationRequestStateManager $stateManager, | ||||||
|  |         protected VacationTypeConfigRetriever $configRetriever, | ||||||
|  |         protected ApproveAction $approveAction, | ||||||
|  |     ) {} | ||||||
|  |  | ||||||
|  |     public function execute(VacationRequest $vacationRequest): void | ||||||
|  |     { | ||||||
|  |         $this->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)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,39 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | namespace Toby\Domain\Actions\VacationRequest; | ||||||
|  |  | ||||||
|  | use Toby\Domain\Enums\Role; | ||||||
|  | use Toby\Domain\Notifications\VacationRequestWaitsForApprovalNotification; | ||||||
|  | use Toby\Domain\VacationRequestStateManager; | ||||||
|  | use Toby\Domain\VacationTypeConfigRetriever; | ||||||
|  | use Toby\Eloquent\Models\User; | ||||||
|  | use Toby\Eloquent\Models\VacationRequest; | ||||||
|  |  | ||||||
|  | class WaitForTechApprovalAction | ||||||
|  | { | ||||||
|  |     public function __construct( | ||||||
|  |         protected VacationRequestStateManager $stateManager, | ||||||
|  |         protected VacationTypeConfigRetriever $configRetriever, | ||||||
|  |         protected ApproveAction $approveAction, | ||||||
|  |     ) {} | ||||||
|  |  | ||||||
|  |     public function execute(VacationRequest $vacationRequest): void | ||||||
|  |     { | ||||||
|  |         $this->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)); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Events; |  | ||||||
|  |  | ||||||
| use Illuminate\Foundation\Events\Dispatchable; |  | ||||||
| use Illuminate\Queue\SerializesModels; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestAcceptedByAdministrative |  | ||||||
| { |  | ||||||
|     use Dispatchable; |  | ||||||
|     use SerializesModels; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         public VacationRequest $vacationRequest, |  | ||||||
|     ) {} |  | ||||||
| } |  | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Events; |  | ||||||
|  |  | ||||||
| use Illuminate\Foundation\Events\Dispatchable; |  | ||||||
| use Illuminate\Queue\SerializesModels; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestAcceptedByTechnical |  | ||||||
| { |  | ||||||
|     use Dispatchable; |  | ||||||
|     use SerializesModels; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         public VacationRequest $vacationRequest, |  | ||||||
|     ) {} |  | ||||||
| } |  | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Events; |  | ||||||
|  |  | ||||||
| use Illuminate\Foundation\Events\Dispatchable; |  | ||||||
| use Illuminate\Queue\SerializesModels; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestApproved |  | ||||||
| { |  | ||||||
|     use Dispatchable; |  | ||||||
|     use SerializesModels; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         public VacationRequest $vacationRequest, |  | ||||||
|     ) {} |  | ||||||
| } |  | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Events; |  | ||||||
|  |  | ||||||
| use Illuminate\Foundation\Events\Dispatchable; |  | ||||||
| use Illuminate\Queue\SerializesModels; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestCancelled |  | ||||||
| { |  | ||||||
|     use Dispatchable; |  | ||||||
|     use SerializesModels; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         public VacationRequest $vacationRequest, |  | ||||||
|     ) {} |  | ||||||
| } |  | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Events; |  | ||||||
|  |  | ||||||
| use Illuminate\Foundation\Events\Dispatchable; |  | ||||||
| use Illuminate\Queue\SerializesModels; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestCreated |  | ||||||
| { |  | ||||||
|     use Dispatchable; |  | ||||||
|     use SerializesModels; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         public VacationRequest $vacationRequest, |  | ||||||
|     ) {} |  | ||||||
| } |  | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Events; |  | ||||||
|  |  | ||||||
| use Illuminate\Foundation\Events\Dispatchable; |  | ||||||
| use Illuminate\Queue\SerializesModels; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestRejected |  | ||||||
| { |  | ||||||
|     use Dispatchable; |  | ||||||
|     use SerializesModels; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         public VacationRequest $vacationRequest, |  | ||||||
|     ) {} |  | ||||||
| } |  | ||||||
| @@ -1,24 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Events; |  | ||||||
|  |  | ||||||
| use Illuminate\Foundation\Events\Dispatchable; |  | ||||||
| use Illuminate\Queue\SerializesModels; |  | ||||||
| use Toby\Domain\States\VacationRequest\VacationRequestState; |  | ||||||
| use Toby\Eloquent\Models\User; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestStateChanged |  | ||||||
| { |  | ||||||
|     use Dispatchable; |  | ||||||
|     use SerializesModels; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         public VacationRequest $vacationRequest, |  | ||||||
|         public ?VacationRequestState $from, |  | ||||||
|         public VacationRequestState $to, |  | ||||||
|         public ?User $user = null, |  | ||||||
|     ) {} |  | ||||||
| } |  | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Events; |  | ||||||
|  |  | ||||||
| use Illuminate\Foundation\Events\Dispatchable; |  | ||||||
| use Illuminate\Queue\SerializesModels; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestWaitsForAdminApproval |  | ||||||
| { |  | ||||||
|     use Dispatchable; |  | ||||||
|     use SerializesModels; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         public VacationRequest $vacationRequest, |  | ||||||
|     ) {} |  | ||||||
| } |  | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Events; |  | ||||||
|  |  | ||||||
| use Illuminate\Foundation\Events\Dispatchable; |  | ||||||
| use Illuminate\Queue\SerializesModels; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestWaitsForTechApproval |  | ||||||
| { |  | ||||||
|     use Dispatchable; |  | ||||||
|     use SerializesModels; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         public VacationRequest $vacationRequest, |  | ||||||
|     ) {} |  | ||||||
| } |  | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Toby\Domain\Events\VacationRequestStateChanged; |  | ||||||
|  |  | ||||||
| class CreateVacationRequestActivity |  | ||||||
| { |  | ||||||
|     public function handle(VacationRequestStateChanged $event): void |  | ||||||
|     { |  | ||||||
|         $event->vacationRequest->activities()->create([ |  | ||||||
|             "from" => $event->from, |  | ||||||
|             "to" => $event->to, |  | ||||||
|             "user_id" => $event->user?->id, |  | ||||||
|         ]); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,20 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Toby\Domain\Events\VacationRequestAcceptedByAdministrative; |  | ||||||
| use Toby\Domain\VacationRequestStateManager; |  | ||||||
|  |  | ||||||
| class HandleAcceptedByAdministrativeVacationRequest |  | ||||||
| { |  | ||||||
|     public function __construct( |  | ||||||
|         protected VacationRequestStateManager $stateManager, |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function handle(VacationRequestAcceptedByAdministrative $event): void |  | ||||||
|     { |  | ||||||
|         $this->stateManager->approve($event->vacationRequest); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,30 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Toby\Domain\Events\VacationRequestAcceptedByTechnical; |  | ||||||
| use Toby\Domain\VacationRequestStateManager; |  | ||||||
| use Toby\Domain\VacationTypeConfigRetriever; |  | ||||||
|  |  | ||||||
| class HandleAcceptedByTechnicalVacationRequest |  | ||||||
| { |  | ||||||
|     public function __construct( |  | ||||||
|         protected VacationTypeConfigRetriever $configRetriever, |  | ||||||
|         protected VacationRequestStateManager $stateManager, |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function handle(VacationRequestAcceptedByTechnical $event): void |  | ||||||
|     { |  | ||||||
|         $vacationRequest = $event->vacationRequest; |  | ||||||
|  |  | ||||||
|         if ($this->configRetriever->needsAdministrativeApproval($vacationRequest->type)) { |  | ||||||
|             $this->stateManager->waitForAdministrative($vacationRequest); |  | ||||||
|  |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         $this->stateManager->approve($vacationRequest); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Toby\Domain\Events\VacationRequestApproved; |  | ||||||
| use Toby\Infrastructure\Jobs\SendVacationRequestDaysToGoogleCalendar; |  | ||||||
|  |  | ||||||
| class HandleApprovedVacationRequest |  | ||||||
| { |  | ||||||
|     public function handle(VacationRequestApproved $event): void |  | ||||||
|     { |  | ||||||
|         SendVacationRequestDaysToGoogleCalendar::dispatch($event->vacationRequest); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,16 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Toby\Domain\Events\VacationRequestCancelled; |  | ||||||
| use Toby\Infrastructure\Jobs\ClearVacationRequestDaysInGoogleCalendar; |  | ||||||
|  |  | ||||||
| class HandleCancelledVacationRequest |  | ||||||
| { |  | ||||||
|     public function handle(VacationRequestCancelled $event): void |  | ||||||
|     { |  | ||||||
|         ClearVacationRequestDaysInGoogleCalendar::dispatch($event->vacationRequest); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,42 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Toby\Domain\Events\VacationRequestCreated; |  | ||||||
| use Toby\Domain\VacationRequestStateManager; |  | ||||||
| use Toby\Domain\VacationTypeConfigRetriever; |  | ||||||
|  |  | ||||||
| class HandleCreatedVacationRequest |  | ||||||
| { |  | ||||||
|     public function __construct( |  | ||||||
|         protected VacationTypeConfigRetriever $configRetriever, |  | ||||||
|         protected VacationRequestStateManager $stateManager, |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function handle(VacationRequestCreated $event): void |  | ||||||
|     { |  | ||||||
|         $vacationRequest = $event->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); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,33 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use Toby\Domain\Enums\Role; |  | ||||||
| use Toby\Domain\Events\VacationRequestApproved; |  | ||||||
| use Toby\Domain\Notifications\VacationRequestApprovedNotification; |  | ||||||
| use Toby\Eloquent\Models\User; |  | ||||||
|  |  | ||||||
| class SendApprovedVacationRequestNotification |  | ||||||
| { |  | ||||||
|     public function __construct( |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function handle(VacationRequestApproved $event): void |  | ||||||
|     { |  | ||||||
|         foreach ($this->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(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,33 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use Toby\Domain\Enums\Role; |  | ||||||
| use Toby\Domain\Events\VacationRequestCancelled; |  | ||||||
| use Toby\Domain\Notifications\VacationRequestCancelledNotification; |  | ||||||
| use Toby\Eloquent\Models\User; |  | ||||||
|  |  | ||||||
| class SendCancelledVacationRequestNotification |  | ||||||
| { |  | ||||||
|     public function __construct( |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function handle(VacationRequestCancelled $event): void |  | ||||||
|     { |  | ||||||
|         foreach ($this->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(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,26 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Toby\Domain\Events\VacationRequestCreated; |  | ||||||
| use Toby\Domain\Notifications\VacationRequestCreatedNotification; |  | ||||||
| use Toby\Domain\Notifications\VacationRequestCreatedOnEmployeeBehalf; |  | ||||||
|  |  | ||||||
| class SendCreatedVacationRequestNotification |  | ||||||
| { |  | ||||||
|     public function __construct( |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function handle(VacationRequestCreated $event): void |  | ||||||
|     { |  | ||||||
|         $vacationRequest = $event->vacationRequest; |  | ||||||
|  |  | ||||||
|         if ($vacationRequest->creator->is($vacationRequest->user)) { |  | ||||||
|             $vacationRequest->user->notify(new VacationRequestCreatedNotification($vacationRequest)); |  | ||||||
|         } else { |  | ||||||
|             $vacationRequest->user->notify(new VacationRequestCreatedOnEmployeeBehalf($vacationRequest)); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,33 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use Toby\Domain\Enums\Role; |  | ||||||
| use Toby\Domain\Events\VacationRequestRejected; |  | ||||||
| use Toby\Domain\Notifications\VacationRequestRejectedNotification; |  | ||||||
| use Toby\Eloquent\Models\User; |  | ||||||
|  |  | ||||||
| class SendRejectedVacationRequestNotification |  | ||||||
| { |  | ||||||
|     public function __construct( |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function handle(VacationRequestRejected $event): void |  | ||||||
|     { |  | ||||||
|         foreach ($this->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(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use Toby\Domain\Enums\Role; |  | ||||||
| use Toby\Domain\Events\VacationRequestWaitsForAdminApproval; |  | ||||||
| use Toby\Domain\Notifications\VacationRequestWaitsForAdminApprovalNotification; |  | ||||||
| use Toby\Eloquent\Models\User; |  | ||||||
|  |  | ||||||
| class SendWaitedForAdministrativeVacationRequestNotification |  | ||||||
| { |  | ||||||
|     public function __construct( |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function handle(VacationRequestWaitsForAdminApproval $event): void |  | ||||||
|     { |  | ||||||
|         foreach ($this->getUsersForNotifications() as $user) { |  | ||||||
|             $user->notify(new VacationRequestWaitsForAdminApprovalNotification($event->vacationRequest, $user)); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     protected function getUsersForNotifications(): Collection |  | ||||||
|     { |  | ||||||
|         return User::query() |  | ||||||
|             ->where("role", [Role::AdministrativeApprover]) |  | ||||||
|             ->get(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Listeners; |  | ||||||
|  |  | ||||||
| use Illuminate\Support\Collection; |  | ||||||
| use Toby\Domain\Enums\Role; |  | ||||||
| use Toby\Domain\Events\VacationRequestWaitsForTechApproval; |  | ||||||
| use Toby\Domain\Notifications\VacationRequestWaitsForTechApprovalNotification; |  | ||||||
| use Toby\Eloquent\Models\User; |  | ||||||
|  |  | ||||||
| class SendWaitedForTechnicalVacationRequestNotification |  | ||||||
| { |  | ||||||
|     public function __construct( |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function handle(VacationRequestWaitsForTechApproval $event): void |  | ||||||
|     { |  | ||||||
|         foreach ($this->getUsersForNotifications() as $user) { |  | ||||||
|             $user->notify(new VacationRequestWaitsForTechApprovalNotification($event->vacationRequest, $user)); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     protected function getUsersForNotifications(): Collection |  | ||||||
|     { |  | ||||||
|         return User::query() |  | ||||||
|             ->where("role", [Role::TechnicalApprover]) |  | ||||||
|             ->get(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,74 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Notifications; |  | ||||||
|  |  | ||||||
| use Illuminate\Bus\Queueable; |  | ||||||
| use Illuminate\Notifications\Messages\MailMessage; |  | ||||||
| use Illuminate\Notifications\Notification; |  | ||||||
| use InvalidArgumentException; |  | ||||||
| use Toby\Eloquent\Models\User; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestCancelledNotification extends Notification |  | ||||||
| { |  | ||||||
|     use Queueable; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         protected VacationRequest $vacationRequest, |  | ||||||
|         protected User $user, |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function via(): array |  | ||||||
|     { |  | ||||||
|         return ["mail"]; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @throws InvalidArgumentException |  | ||||||
|      */ |  | ||||||
|     public function toMail(): MailMessage |  | ||||||
|     { |  | ||||||
|         $url = route( |  | ||||||
|             "vacation.requests.show", |  | ||||||
|             [ |  | ||||||
|                 "vacationRequest" => $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); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -40,24 +40,17 @@ class VacationRequestCreatedNotification extends Notification | |||||||
|     protected function buildMailMessage(string $url): MailMessage |     protected function buildMailMessage(string $url): MailMessage | ||||||
|     { |     { | ||||||
|         $user = $this->vacationRequest->user->first_name; |         $user = $this->vacationRequest->user->first_name; | ||||||
|         $title = $this->vacationRequest->name; |  | ||||||
|         $type = $this->vacationRequest->type->label(); |         $type = $this->vacationRequest->type->label(); | ||||||
|         $from = $this->vacationRequest->from->toDisplayString(); |         $from = $this->vacationRequest->from->toDisplayString(); | ||||||
|         $to = $this->vacationRequest->to->toDisplayString(); |         $to = $this->vacationRequest->to->toDisplayString(); | ||||||
|         $days = $this->vacationRequest->vacations()->count(); |         $days = $this->vacationRequest->vacations()->count(); | ||||||
|         $appName = config("app.name"); |  | ||||||
|  |  | ||||||
|         return (new MailMessage()) |         return (new MailMessage()) | ||||||
|             ->greeting(__("Hi :user!", [ |             ->greeting(__("Hi :user!", [ | ||||||
|                 "user" => $user, |                 "user" => $user, | ||||||
|             ])) |             ])) | ||||||
|             ->subject(__("Vacation request :title has been created", [ |             ->subject($this->buildSubject()) | ||||||
|                 "title" => $title, |             ->line($this->buildDescription()) | ||||||
|             ])) |  | ||||||
|             ->line(__("The vacation request :title has been created correctly in the :appName.", [ |  | ||||||
|                 "title" => $title, |  | ||||||
|                 "appName" => $appName, |  | ||||||
|             ])) |  | ||||||
|             ->line(__("Vacation type: :type", [ |             ->line(__("Vacation type: :type", [ | ||||||
|                 "type" => $type, |                 "type" => $type, | ||||||
|             ])) |             ])) | ||||||
| @@ -68,4 +61,38 @@ class VacationRequestCreatedNotification extends Notification | |||||||
|             ])) |             ])) | ||||||
|             ->action(__("Click here for details"), $url); |             ->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, | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,73 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Notifications; |  | ||||||
|  |  | ||||||
| use Illuminate\Bus\Queueable; |  | ||||||
| use Illuminate\Notifications\Messages\MailMessage; |  | ||||||
| use Illuminate\Notifications\Notification; |  | ||||||
| use InvalidArgumentException; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestCreatedOnEmployeeBehalf extends Notification |  | ||||||
| { |  | ||||||
|     use Queueable; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         protected VacationRequest $vacationRequest, |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function via(): array |  | ||||||
|     { |  | ||||||
|         return ["mail"]; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @throws InvalidArgumentException |  | ||||||
|      */ |  | ||||||
|     public function toMail(): MailMessage |  | ||||||
|     { |  | ||||||
|         $url = route( |  | ||||||
|             "vacation.requests.show", |  | ||||||
|             [ |  | ||||||
|                 "vacationRequest" => $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); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,74 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Notifications; |  | ||||||
|  |  | ||||||
| use Illuminate\Bus\Queueable; |  | ||||||
| use Illuminate\Notifications\Messages\MailMessage; |  | ||||||
| use Illuminate\Notifications\Notification; |  | ||||||
| use InvalidArgumentException; |  | ||||||
| use Toby\Eloquent\Models\User; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestRejectedNotification extends Notification |  | ||||||
| { |  | ||||||
|     use Queueable; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         protected VacationRequest $vacationRequest, |  | ||||||
|         protected User $user, |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function via(): array |  | ||||||
|     { |  | ||||||
|         return ["mail"]; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @throws InvalidArgumentException |  | ||||||
|      */ |  | ||||||
|     public function toMail(): MailMessage |  | ||||||
|     { |  | ||||||
|         $url = route( |  | ||||||
|             "vacation.requests.show", |  | ||||||
|             [ |  | ||||||
|                 "vacationRequest" => $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); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -11,7 +11,7 @@ use InvalidArgumentException; | |||||||
| use Toby\Eloquent\Models\User; | use Toby\Eloquent\Models\User; | ||||||
| use Toby\Eloquent\Models\VacationRequest; | use Toby\Eloquent\Models\VacationRequest; | ||||||
| 
 | 
 | ||||||
| class VacationRequestApprovedNotification extends Notification | class VacationRequestStatusChangedNotification extends Notification | ||||||
| { | { | ||||||
|     use Queueable; |     use Queueable; | ||||||
| 
 | 
 | ||||||
| @@ -45,6 +45,7 @@ class VacationRequestApprovedNotification extends Notification | |||||||
|         $user = $this->user->first_name; |         $user = $this->user->first_name; | ||||||
|         $title = $this->vacationRequest->name; |         $title = $this->vacationRequest->name; | ||||||
|         $type = $this->vacationRequest->type->label(); |         $type = $this->vacationRequest->type->label(); | ||||||
|  |         $status = $this->vacationRequest->state->label(); | ||||||
|         $from = $this->vacationRequest->from->toDisplayString(); |         $from = $this->vacationRequest->from->toDisplayString(); | ||||||
|         $to = $this->vacationRequest->to->toDisplayString(); |         $to = $this->vacationRequest->to->toDisplayString(); | ||||||
|         $days = $this->vacationRequest->vacations()->count(); |         $days = $this->vacationRequest->vacations()->count(); | ||||||
| @@ -54,12 +55,14 @@ class VacationRequestApprovedNotification extends Notification | |||||||
|             ->greeting(__("Hi :user!", [ |             ->greeting(__("Hi :user!", [ | ||||||
|                 "user" => $user, |                 "user" => $user, | ||||||
|             ])) |             ])) | ||||||
|             ->subject(__("Vacation request :title has been approved", [ |             ->subject(__("Vacation request :title has been :status", [ | ||||||
|                 "title" => $title, |                 "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, |                 "title" => $title, | ||||||
|                 "requester" => $requester, |                 "requester" => $requester, | ||||||
|  |                 "status" => $status, | ||||||
|             ])) |             ])) | ||||||
|             ->line(__("Vacation type: :type", [ |             ->line(__("Vacation type: :type", [ | ||||||
|                 "type" => $type, |                 "type" => $type, | ||||||
| @@ -1,74 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Domain\Notifications; |  | ||||||
|  |  | ||||||
| use Illuminate\Bus\Queueable; |  | ||||||
| use Illuminate\Notifications\Messages\MailMessage; |  | ||||||
| use Illuminate\Notifications\Notification; |  | ||||||
| use InvalidArgumentException; |  | ||||||
| use Toby\Eloquent\Models\User; |  | ||||||
| use Toby\Eloquent\Models\VacationRequest; |  | ||||||
|  |  | ||||||
| class VacationRequestWaitsForAdminApprovalNotification extends Notification |  | ||||||
| { |  | ||||||
|     use Queueable; |  | ||||||
|  |  | ||||||
|     public function __construct( |  | ||||||
|         protected VacationRequest $vacationRequest, |  | ||||||
|         protected User $user, |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function via(): array |  | ||||||
|     { |  | ||||||
|         return ["mail"]; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @throws InvalidArgumentException |  | ||||||
|      */ |  | ||||||
|     public function toMail(): MailMessage |  | ||||||
|     { |  | ||||||
|         $url = route( |  | ||||||
|             "vacation.requests.show", |  | ||||||
|             [ |  | ||||||
|                 "vacationRequest" => $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); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -11,7 +11,7 @@ use InvalidArgumentException; | |||||||
| use Toby\Eloquent\Models\User; | use Toby\Eloquent\Models\User; | ||||||
| use Toby\Eloquent\Models\VacationRequest; | use Toby\Eloquent\Models\VacationRequest; | ||||||
| 
 | 
 | ||||||
| class VacationRequestWaitsForTechApprovalNotification extends Notification | class VacationRequestWaitsForApprovalNotification extends Notification | ||||||
| { | { | ||||||
|     use Queueable; |     use Queueable; | ||||||
| 
 | 
 | ||||||
| @@ -36,4 +36,9 @@ abstract class VacationRequestState extends State | |||||||
|                 Approved::class, |                 Approved::class, | ||||||
|             ], Cancelled::class); |             ], Cancelled::class); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function label(): string | ||||||
|  |     { | ||||||
|  |         return __(static::$name); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,17 +4,7 @@ declare(strict_types=1); | |||||||
|  |  | ||||||
| namespace Toby\Domain; | namespace Toby\Domain; | ||||||
|  |  | ||||||
| use Illuminate\Contracts\Auth\Factory as Auth; |  | ||||||
| use Illuminate\Contracts\Events\Dispatcher; | 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\AcceptedByAdministrative; | ||||||
| use Toby\Domain\States\VacationRequest\AcceptedByTechnical; | use Toby\Domain\States\VacationRequest\AcceptedByTechnical; | ||||||
| use Toby\Domain\States\VacationRequest\Approved; | use Toby\Domain\States\VacationRequest\Approved; | ||||||
| @@ -29,63 +19,47 @@ use Toby\Eloquent\Models\VacationRequest; | |||||||
| class VacationRequestStateManager | class VacationRequestStateManager | ||||||
| { | { | ||||||
|     public function __construct( |     public function __construct( | ||||||
|         protected Auth $auth, |  | ||||||
|         protected Dispatcher $dispatcher, |         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->createActivity($vacationRequest, null, $vacationRequest->state, $vacationRequest->creator); | ||||||
|  |  | ||||||
|         $this->dispatcher->dispatch(new VacationRequestCreated($vacationRequest)); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function approve(VacationRequest $vacationRequest, ?User $user = null): void |     public function approve(VacationRequest $vacationRequest, ?User $user = null): void | ||||||
|     { |     { | ||||||
|         $this->changeState($vacationRequest, Approved::class, $user); |         $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->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->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->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->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->changeState($vacationRequest, WaitingForTechnical::class); | ||||||
|  |  | ||||||
|         $this->dispatcher->dispatch(new VacationRequestWaitsForTechApproval($vacationRequest)); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function waitForAdministrative(VacationRequest $vacationRequest, ?User $user = null): void |     public function waitForAdministrative(VacationRequest $vacationRequest): void | ||||||
|     { |     { | ||||||
|         $this->changeState($vacationRequest, WaitingForAdministrative::class, $user); |         $this->changeState($vacationRequest, WaitingForAdministrative::class); | ||||||
|  |  | ||||||
|         $this->dispatcher->dispatch(new VacationRequestWaitsForAdminApproval($vacationRequest)); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected function changeState(VacationRequest $vacationRequest, string $state, ?User $user = null): void |     protected function changeState(VacationRequest $vacationRequest, string $state, ?User $user = null): void | ||||||
| @@ -94,16 +68,19 @@ class VacationRequestStateManager | |||||||
|         $vacationRequest->state->transitionTo($state); |         $vacationRequest->state->transitionTo($state); | ||||||
|         $vacationRequest->save(); |         $vacationRequest->save(); | ||||||
|  |  | ||||||
|         $this->fireStateChangedEvent($vacationRequest, $previousState, $vacationRequest->state, $user); |         $this->createActivity($vacationRequest, $previousState, $vacationRequest->state, $user); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected function fireStateChangedEvent( |     protected function createActivity( | ||||||
|         VacationRequest $vacationRequest, |         VacationRequest $vacationRequest, | ||||||
|         ?VacationRequestState $from, |         ?VacationRequestState $from, | ||||||
|         VacationRequestState $to, |         VacationRequestState $to, | ||||||
|         ?User $user = null, |         ?User $user = null, | ||||||
|     ): void { |     ): void { | ||||||
|         $event = new VacationRequestStateChanged($vacationRequest, $from, $to, $user); |         $vacationRequest->activities()->create([ | ||||||
|         $this->dispatcher->dispatch($event); |             "from" => $from, | ||||||
|  |             "to" => $to, | ||||||
|  |             "user_id" => $user?->id, | ||||||
|  |         ]); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,22 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Eloquent\Scopes; |  | ||||||
|  |  | ||||||
| use Illuminate\Database\Eloquent\Builder; |  | ||||||
| use Illuminate\Database\Eloquent\Model; |  | ||||||
| use Illuminate\Database\Eloquent\Scope; |  | ||||||
| use Toby\Eloquent\Helpers\YearPeriodRetriever; |  | ||||||
|  |  | ||||||
| class SelectedYearPeriodScope implements Scope |  | ||||||
| { |  | ||||||
|     public function __construct( |  | ||||||
|         protected YearPeriodRetriever $yearPeriodRetriever, |  | ||||||
|     ) {} |  | ||||||
|  |  | ||||||
|     public function apply(Builder $builder, Model $model): Builder |  | ||||||
|     { |  | ||||||
|         return $builder->where("year_period_id", $this->yearPeriodRetriever->selected()->id); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,25 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| declare(strict_types=1); |  | ||||||
|  |  | ||||||
| namespace Toby\Infrastructure\Console\Commands; |  | ||||||
|  |  | ||||||
| use Illuminate\Console\Command; |  | ||||||
| use Toby\Eloquent\Models\User; |  | ||||||
|  |  | ||||||
| class CreateUserCommand extends Command |  | ||||||
| { |  | ||||||
|     protected $signature = "user:create {email : an email for the user}"; |  | ||||||
|     protected $description = "Creates a user"; |  | ||||||
|  |  | ||||||
|     public function handle(): void |  | ||||||
|     { |  | ||||||
|         $email = $this->argument("email"); |  | ||||||
|  |  | ||||||
|         User::factory([ |  | ||||||
|             "email" => $email, |  | ||||||
|         ])->create(); |  | ||||||
|  |  | ||||||
|         $this->info("The user has been created"); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -25,6 +25,7 @@ class VacationLimitController extends Controller | |||||||
|         $limits = $yearPeriod |         $limits = $yearPeriod | ||||||
|             ->vacationLimits() |             ->vacationLimits() | ||||||
|             ->with("user") |             ->with("user") | ||||||
|  |             ->has("user") | ||||||
|             ->orderByUserField("last_name") |             ->orderByUserField("last_name") | ||||||
|             ->orderByUserField("first_name") |             ->orderByUserField("first_name") | ||||||
|             ->get(); |             ->get(); | ||||||
|   | |||||||
| @@ -12,15 +12,17 @@ use Illuminate\Http\Request; | |||||||
| use Illuminate\Http\Response as LaravelResponse; | use Illuminate\Http\Response as LaravelResponse; | ||||||
| use Illuminate\Validation\ValidationException; | use Illuminate\Validation\ValidationException; | ||||||
| use Inertia\Response; | 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\Enums\VacationType; | ||||||
| use Toby\Domain\States\VacationRequest\AcceptedByAdministrative; | use Toby\Domain\States\VacationRequest\AcceptedByAdministrative; | ||||||
| use Toby\Domain\States\VacationRequest\AcceptedByTechnical; | use Toby\Domain\States\VacationRequest\AcceptedByTechnical; | ||||||
| use Toby\Domain\States\VacationRequest\Cancelled; | use Toby\Domain\States\VacationRequest\Cancelled; | ||||||
| use Toby\Domain\States\VacationRequest\Rejected; | use Toby\Domain\States\VacationRequest\Rejected; | ||||||
| use Toby\Domain\VacationDaysCalculator; |  | ||||||
| use Toby\Domain\VacationRequestStateManager; |  | ||||||
| use Toby\Domain\VacationRequestStatesRetriever; | use Toby\Domain\VacationRequestStatesRetriever; | ||||||
| use Toby\Domain\Validation\VacationRequestValidator; |  | ||||||
| use Toby\Eloquent\Helpers\YearPeriodRetriever; | use Toby\Eloquent\Helpers\YearPeriodRetriever; | ||||||
| use Toby\Eloquent\Models\User; | use Toby\Eloquent\Models\User; | ||||||
| use Toby\Eloquent\Models\VacationRequest; | use Toby\Eloquent\Models\VacationRequest; | ||||||
| @@ -91,7 +93,12 @@ class VacationRequestController extends Controller | |||||||
|             ->with(["user", "vacations"]) |             ->with(["user", "vacations"]) | ||||||
|             ->where("year_period_id", $yearPeriod->id) |             ->where("year_period_id", $yearPeriod->id) | ||||||
|             ->when($user !== null, fn(Builder $query) => $query->where("user_id", $user)) |             ->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() |             ->latest() | ||||||
|             ->paginate(); |             ->paginate(); | ||||||
|  |  | ||||||
| @@ -179,12 +186,8 @@ class VacationRequestController extends Controller | |||||||
|      * @throws AuthorizationException |      * @throws AuthorizationException | ||||||
|      * @throws ValidationException |      * @throws ValidationException | ||||||
|      */ |      */ | ||||||
|     public function store( |     public function store(VacationRequestRequest $request, CreateAction $createAction): RedirectResponse | ||||||
|         VacationRequestRequest $request, |     { | ||||||
|         VacationRequestValidator $vacationRequestValidator, |  | ||||||
|         VacationRequestStateManager $stateManager, |  | ||||||
|         VacationDaysCalculator $vacationDaysCalculator, |  | ||||||
|     ): RedirectResponse { |  | ||||||
|         if ($request->createsOnBehalfOfEmployee()) { |         if ($request->createsOnBehalfOfEmployee()) { | ||||||
|             $this->authorize("createOnBehalfOfEmployee", VacationRequest::class); |             $this->authorize("createOnBehalfOfEmployee", VacationRequest::class); | ||||||
|         } |         } | ||||||
| @@ -193,27 +196,7 @@ class VacationRequestController extends Controller | |||||||
|             $this->authorize("skipFlow", VacationRequest::class); |             $this->authorize("skipFlow", VacationRequest::class); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         /** @var VacationRequest $vacationRequest */ |         $vacationRequest = $createAction->execute($request->data(), $request->user()); | ||||||
|         $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()); |  | ||||||
|  |  | ||||||
|         return redirect() |         return redirect() | ||||||
|             ->route("vacation.requests.show", $vacationRequest) |             ->route("vacation.requests.show", $vacationRequest) | ||||||
| @@ -226,11 +209,11 @@ class VacationRequestController extends Controller | |||||||
|     public function reject( |     public function reject( | ||||||
|         Request $request, |         Request $request, | ||||||
|         VacationRequest $vacationRequest, |         VacationRequest $vacationRequest, | ||||||
|         VacationRequestStateManager $stateManager, |         RejectAction $rejectAction, | ||||||
|     ): RedirectResponse { |     ): RedirectResponse { | ||||||
|         $this->authorize("reject", $vacationRequest); |         $this->authorize("reject", $vacationRequest); | ||||||
|  |  | ||||||
|         $stateManager->reject($vacationRequest, $request->user()); |         $rejectAction->execute($vacationRequest, $request->user()); | ||||||
|  |  | ||||||
|         return redirect()->back() |         return redirect()->back() | ||||||
|             ->with("success", __("Vacation request has been rejected.")); |             ->with("success", __("Vacation request has been rejected.")); | ||||||
| @@ -242,11 +225,11 @@ class VacationRequestController extends Controller | |||||||
|     public function cancel( |     public function cancel( | ||||||
|         Request $request, |         Request $request, | ||||||
|         VacationRequest $vacationRequest, |         VacationRequest $vacationRequest, | ||||||
|         VacationRequestStateManager $stateManager, |         CancelAction $cancelAction, | ||||||
|     ): RedirectResponse { |     ): RedirectResponse { | ||||||
|         $this->authorize("cancel", $vacationRequest); |         $this->authorize("cancel", $vacationRequest); | ||||||
|  |  | ||||||
|         $stateManager->cancel($vacationRequest, $request->user()); |         $cancelAction->execute($vacationRequest, $request->user()); | ||||||
|  |  | ||||||
|         return redirect()->back() |         return redirect()->back() | ||||||
|             ->with("success", __("Vacation request has been cancelled.")); |             ->with("success", __("Vacation request has been cancelled.")); | ||||||
| @@ -258,11 +241,11 @@ class VacationRequestController extends Controller | |||||||
|     public function acceptAsTechnical( |     public function acceptAsTechnical( | ||||||
|         Request $request, |         Request $request, | ||||||
|         VacationRequest $vacationRequest, |         VacationRequest $vacationRequest, | ||||||
|         VacationRequestStateManager $stateManager, |         AcceptAsTechnicalAction $acceptAsTechnicalAction, | ||||||
|     ): RedirectResponse { |     ): RedirectResponse { | ||||||
|         $this->authorize("acceptAsTechApprover", $vacationRequest); |         $this->authorize("acceptAsTechApprover", $vacationRequest); | ||||||
|  |  | ||||||
|         $stateManager->acceptAsTechnical($vacationRequest, $request->user()); |         $acceptAsTechnicalAction->execute($vacationRequest, $request->user()); | ||||||
|  |  | ||||||
|         return redirect()->back() |         return redirect()->back() | ||||||
|             ->with("success", __("Vacation request has been accepted.")); |             ->with("success", __("Vacation request has been accepted.")); | ||||||
| @@ -274,11 +257,11 @@ class VacationRequestController extends Controller | |||||||
|     public function acceptAsAdministrative( |     public function acceptAsAdministrative( | ||||||
|         Request $request, |         Request $request, | ||||||
|         VacationRequest $vacationRequest, |         VacationRequest $vacationRequest, | ||||||
|         VacationRequestStateManager $stateManager, |         AcceptAsAdministrativeAction $acceptAsAdministrativeAction, | ||||||
|     ): RedirectResponse { |     ): RedirectResponse { | ||||||
|         $this->authorize("acceptAsAdminApprover", $vacationRequest); |         $this->authorize("acceptAsAdminApprover", $vacationRequest); | ||||||
|  |  | ||||||
|         $stateManager->acceptAsAdministrative($vacationRequest, $request->user()); |         $acceptAsAdministrativeAction->execute($vacationRequest, $request->user()); | ||||||
|  |  | ||||||
|         return redirect()->back() |         return redirect()->back() | ||||||
|             ->with("success", __("Vacation request has been accepted.")); |             ->with("success", __("Vacation request has been accepted.")); | ||||||
|   | |||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | declare(strict_types=1); | ||||||
|  |  | ||||||
|  | use Illuminate\Database\Migrations\Migration; | ||||||
|  | use Illuminate\Database\Schema\Blueprint; | ||||||
|  | use Illuminate\Support\Facades\Schema; | ||||||
|  |  | ||||||
|  | return new class() extends Migration { | ||||||
|  |     public function up(): void | ||||||
|  |     { | ||||||
|  |         Schema::table("users", function (Blueprint $table): void { | ||||||
|  |             $table->dropColumn("avatar"); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function down(): void | ||||||
|  |     { | ||||||
|  |         Schema::table("users", function (Blueprint $table): void { | ||||||
|  |             $table->string("avatar")->nullable(); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | }; | ||||||
| @@ -18,14 +18,9 @@ | |||||||
|   "administrator": "Administrator", |   "administrator": "Administrator", | ||||||
|   "technical_approver": "Techniczny akceptujący", |   "technical_approver": "Techniczny akceptujący", | ||||||
|   "administrative_approver": "Administracyjny akceptujący", |   "administrative_approver": "Administracyjny akceptujący", | ||||||
|   "created": "Utworzony", |   "cancelled": "anulowany", | ||||||
|   "cancelled": "Anulowany", |   "rejected": "odrzucony", | ||||||
|   "rejected": "Odrzucony", |   "approved": "zatwierdzony", | ||||||
|   "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", |  | ||||||
|   "You have pending vacation request in this range.": "Masz oczekujący wniosek urlopowy w tym zakresie dat.", |   "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.", |   "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.", |   "Vacation limit has been exceeded.": "Limit urlopu został przekroczony.", | ||||||
| @@ -65,12 +60,8 @@ | |||||||
|   "Click here for details": "Kliknij, aby zobaczyć szczegóły", |   "Click here for details": "Kliknij, aby zobaczyć szczegóły", | ||||||
|   "Vacation request :title is waiting for your approval": "Wniosek urlopowy :title czeka na zaakceptowanie", |   "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ę.", |   "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", |   "Vacation request :title has been :status": "Wniosek urlopowy :title został :status", | ||||||
|   "The vacation request :title for user :requester has been approved.": "Wniosek urlopowy :title od użytkownika :requester został zatwierdzony.", |   "The vacation request :title for user :requester has been :status.": "Wniosek urlopowy :title od użytkownika :requester został :status.", | ||||||
|   "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 created on your behalf": "Wniosek urlopowy :title został utworzony w Twoim imieniu", |   "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." |   "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." | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,14 +6,11 @@ namespace Tests\Feature; | |||||||
|  |  | ||||||
| use Illuminate\Foundation\Testing\DatabaseMigrations; | use Illuminate\Foundation\Testing\DatabaseMigrations; | ||||||
| use Illuminate\Support\Carbon; | 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 Inertia\Testing\AssertableInertia as Assert; | ||||||
| use Tests\FeatureTestCase; | use Tests\FeatureTestCase; | ||||||
| use Toby\Domain\Enums\VacationType; | 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\PolishHolidaysRetriever; | ||||||
| use Toby\Domain\States\VacationRequest\Approved; | use Toby\Domain\States\VacationRequest\Approved; | ||||||
| use Toby\Domain\States\VacationRequest\Rejected; | use Toby\Domain\States\VacationRequest\Rejected; | ||||||
| @@ -34,6 +31,9 @@ class VacationRequestTest extends FeatureTestCase | |||||||
|     { |     { | ||||||
|         parent::setUp(); |         parent::setUp(); | ||||||
|  |  | ||||||
|  |         Bus::fake(); | ||||||
|  |         Notification::fake(); | ||||||
|  |  | ||||||
|         $this->polishHolidaysRetriever = $this->app->make(PolishHolidaysRetriever::class); |         $this->polishHolidaysRetriever = $this->app->make(PolishHolidaysRetriever::class); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -130,8 +130,6 @@ class VacationRequestTest extends FeatureTestCase | |||||||
|  |  | ||||||
|     public function testUserCanCreateVacationRequestOnEmployeeBehalfAndSkipAcceptanceFlow(): void |     public function testUserCanCreateVacationRequestOnEmployeeBehalfAndSkipAcceptanceFlow(): void | ||||||
|     { |     { | ||||||
|         Event::fake(VacationRequestApproved::class); |  | ||||||
|  |  | ||||||
|         $creator = User::factory()->admin()->createQuietly(); |         $creator = User::factory()->admin()->createQuietly(); | ||||||
|         $user = User::factory()->createQuietly(); |         $user = User::factory()->createQuietly(); | ||||||
|  |  | ||||||
| @@ -169,8 +167,6 @@ class VacationRequestTest extends FeatureTestCase | |||||||
|  |  | ||||||
|     public function testTechnicalApproverCanApproveVacationRequest(): void |     public function testTechnicalApproverCanApproveVacationRequest(): void | ||||||
|     { |     { | ||||||
|         Event::fake(VacationRequestAcceptedByTechnical::class); |  | ||||||
|  |  | ||||||
|         $user = User::factory()->createQuietly(); |         $user = User::factory()->createQuietly(); | ||||||
|         $technicalApprover = User::factory()->technicalApprover()->createQuietly(); |         $technicalApprover = User::factory()->technicalApprover()->createQuietly(); | ||||||
|         $currentYearPeriod = YearPeriod::current(); |         $currentYearPeriod = YearPeriod::current(); | ||||||
| @@ -187,13 +183,13 @@ class VacationRequestTest extends FeatureTestCase | |||||||
|             ->post("/vacation-requests/{$vacationRequest->id}/accept-as-technical") |             ->post("/vacation-requests/{$vacationRequest->id}/accept-as-technical") | ||||||
|             ->assertSessionHasNoErrors(); |             ->assertSessionHasNoErrors(); | ||||||
|  |  | ||||||
|         Event::assertDispatched(VacationRequestAcceptedByTechnical::class); |         $vacationRequest->refresh(); | ||||||
|  |  | ||||||
|  |         $this->assertTrue($vacationRequest->state->equals(WaitingForAdministrative::class)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function testAdministrativeApproverCanApproveVacationRequest(): void |     public function testAdministrativeApproverCanApproveVacationRequest(): void | ||||||
|     { |     { | ||||||
|         Event::fake(VacationRequestAcceptedByAdministrative::class); |  | ||||||
|  |  | ||||||
|         $user = User::factory()->createQuietly(); |         $user = User::factory()->createQuietly(); | ||||||
|         $administrativeApprover = User::factory()->administrativeApprover()->createQuietly(); |         $administrativeApprover = User::factory()->administrativeApprover()->createQuietly(); | ||||||
|  |  | ||||||
| @@ -210,13 +206,13 @@ class VacationRequestTest extends FeatureTestCase | |||||||
|             ->post("/vacation-requests/{$vacationRequest->id}/accept-as-administrative") |             ->post("/vacation-requests/{$vacationRequest->id}/accept-as-administrative") | ||||||
|             ->assertSessionHasNoErrors(); |             ->assertSessionHasNoErrors(); | ||||||
|  |  | ||||||
|         Event::assertDispatched(VacationRequestAcceptedByAdministrative::class); |         $vacationRequest->refresh(); | ||||||
|  |  | ||||||
|  |         $this->assertTrue($vacationRequest->state->equals(Approved::class)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function testTechnicalApproverCanRejectVacationRequest(): void |     public function testTechnicalApproverCanRejectVacationRequest(): void | ||||||
|     { |     { | ||||||
|         Event::fake(VacationRequestRejected::class); |  | ||||||
|  |  | ||||||
|         $user = User::factory()->createQuietly(); |         $user = User::factory()->createQuietly(); | ||||||
|         $technicalApprover = User::factory()->technicalApprover()->createQuietly(); |         $technicalApprover = User::factory()->technicalApprover()->createQuietly(); | ||||||
|         $currentYearPeriod = YearPeriod::current(); |         $currentYearPeriod = YearPeriod::current(); | ||||||
| @@ -228,6 +224,7 @@ class VacationRequestTest extends FeatureTestCase | |||||||
|             ->for($currentYearPeriod) |             ->for($currentYearPeriod) | ||||||
|             ->create(); |             ->create(); | ||||||
|  |  | ||||||
|  |         /** @var VacationRequest $vacationRequest */ | ||||||
|         $vacationRequest = VacationRequest::factory([ |         $vacationRequest = VacationRequest::factory([ | ||||||
|             "state" => WaitingForTechnical::class, |             "state" => WaitingForTechnical::class, | ||||||
|             "type" => VacationType::Vacation, |             "type" => VacationType::Vacation, | ||||||
| @@ -240,10 +237,9 @@ class VacationRequestTest extends FeatureTestCase | |||||||
|             ->post("/vacation-requests/{$vacationRequest->id}/reject") |             ->post("/vacation-requests/{$vacationRequest->id}/reject") | ||||||
|             ->assertSessionHasNoErrors(); |             ->assertSessionHasNoErrors(); | ||||||
|  |  | ||||||
|         Event::assertDispatched(VacationRequestRejected::class); |         $vacationRequest->refresh(); | ||||||
|         $this->assertDatabaseHas("vacation_requests", [ |  | ||||||
|             "state" => Rejected::$name, |         $this->assertTrue($vacationRequest->state->equals(Rejected::class)); | ||||||
|         ]); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public function testUserCannotCreateVacationRequestIfHeExceedsHisVacationLimit(): void |     public function testUserCannotCreateVacationRequestIfHeExceedsHisVacationLimit(): void | ||||||
|   | |||||||
| @@ -9,11 +9,14 @@ use Illuminate\Support\Carbon; | |||||||
| use Illuminate\Support\Facades\Notification; | use Illuminate\Support\Facades\Notification; | ||||||
| use Tests\TestCase; | use Tests\TestCase; | ||||||
| use Tests\Traits\InteractsWithYearPeriods; | 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\Role; | ||||||
| use Toby\Domain\Enums\VacationType; | 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\States\VacationRequest\Created; | ||||||
| use Toby\Domain\VacationRequestStateManager; | use Toby\Domain\States\VacationRequest\WaitingForTechnical; | ||||||
| use Toby\Eloquent\Models\User; | use Toby\Eloquent\Models\User; | ||||||
| use Toby\Eloquent\Models\VacationRequest; | use Toby\Eloquent\Models\VacationRequest; | ||||||
| use Toby\Eloquent\Models\YearPeriod; | use Toby\Eloquent\Models\YearPeriod; | ||||||
| @@ -23,14 +26,10 @@ class VacationRequestNotificationTest extends TestCase | |||||||
|     use DatabaseMigrations; |     use DatabaseMigrations; | ||||||
|     use InteractsWithYearPeriods; |     use InteractsWithYearPeriods; | ||||||
|  |  | ||||||
|     protected VacationRequestStateManager $stateManager; |  | ||||||
|  |  | ||||||
|     protected function setUp(): void |     protected function setUp(): void | ||||||
|     { |     { | ||||||
|         parent::setUp(); |         parent::setUp(); | ||||||
|  |  | ||||||
|         $this->stateManager = $this->app->make(VacationRequestStateManager::class); |  | ||||||
|  |  | ||||||
|         $this->createCurrentYearPeriod(); |         $this->createCurrentYearPeriod(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -47,6 +46,9 @@ class VacationRequestNotificationTest extends TestCase | |||||||
|         $administrativeApprover = User::factory([ |         $administrativeApprover = User::factory([ | ||||||
|             "role" => Role::AdministrativeApprover, |             "role" => Role::AdministrativeApprover, | ||||||
|         ])->createQuietly(); |         ])->createQuietly(); | ||||||
|  |         $admin = User::factory([ | ||||||
|  |             "role" => Role::Administrator, | ||||||
|  |         ])->createQuietly(); | ||||||
|  |  | ||||||
|         $currentYearPeriod = YearPeriod::current(); |         $currentYearPeriod = YearPeriod::current(); | ||||||
|  |  | ||||||
| @@ -62,9 +64,47 @@ class VacationRequestNotificationTest extends TestCase | |||||||
|             ->for($currentYearPeriod) |             ->for($currentYearPeriod) | ||||||
|             ->create(); |             ->create(); | ||||||
|  |  | ||||||
|         $this->stateManager->waitForTechnical($vacationRequest); |         $waitForTechApprovalAction = $this->app->make(WaitForTechApprovalAction::class); | ||||||
|  |  | ||||||
|         Notification::assertSentTo($technicalApprover, VacationRequestWaitsForTechApprovalNotification::class); |         $waitForTechApprovalAction->execute($vacationRequest); | ||||||
|         Notification::assertNotSentTo([$user, $administrativeApprover], VacationRequestWaitsForTechApprovalNotification::class); |  | ||||||
|  |         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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user