Merge branch 'main' into #43-vacation-summary-for-employee
# Conflicts: # app/Infrastructure/Http/Controllers/HolidayController.php # app/Infrastructure/Http/Controllers/VacationLimitController.php # app/Infrastructure/Http/Controllers/VacationRequestController.php # composer.lock # resources/js/Pages/Holidays/Index.vue # resources/js/Pages/VacationRequest/Create.vue
This commit is contained in:
		@@ -5,13 +5,31 @@ declare(strict_types=1);
 | 
				
			|||||||
namespace Toby\Architecture\Providers;
 | 
					namespace Toby\Architecture\Providers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
 | 
					use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Gate;
 | 
				
			||||||
 | 
					use Toby\Domain\Enums\Role;
 | 
				
			||||||
 | 
					use Toby\Domain\Policies\VacationRequestPolicy;
 | 
				
			||||||
 | 
					use Toby\Eloquent\Models\User;
 | 
				
			||||||
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AuthServiceProvider extends ServiceProvider
 | 
					class AuthServiceProvider extends ServiceProvider
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    protected $policies = [];
 | 
					    protected $policies = [
 | 
				
			||||||
 | 
					        VacationRequest::class => VacationRequestPolicy::class,
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function boot(): void
 | 
					    public function boot(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->registerPolicies();
 | 
					        $this->registerPolicies();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Gate::before(function (User $user) {
 | 
				
			||||||
 | 
					            if ($user->role === Role::Administrator) {
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Gate::define("manageUsers", fn(User $user) => $user->role === Role::AdministrativeApprover);
 | 
				
			||||||
 | 
					        Gate::define("manageHolidays", fn(User $user) => $user->role === Role::AdministrativeApprover);
 | 
				
			||||||
 | 
					        Gate::define("manageVacationLimits", fn(User $user) => $user->role === Role::AdministrativeApprover);
 | 
				
			||||||
 | 
					        Gate::define("generateTimesheet", fn(User $user) => $user->role === Role::AdministrativeApprover);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,9 +5,9 @@ declare(strict_types=1);
 | 
				
			|||||||
namespace Toby\Domain;
 | 
					namespace Toby\Domain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Carbon\CarbonPeriod;
 | 
					use Carbon\CarbonPeriod;
 | 
				
			||||||
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Support\Carbon;
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
use Illuminate\Support\Collection;
 | 
					use Illuminate\Support\Collection;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					 | 
				
			||||||
use Toby\Eloquent\Helpers\YearPeriodRetriever;
 | 
					use Toby\Eloquent\Helpers\YearPeriodRetriever;
 | 
				
			||||||
use Toby\Eloquent\Models\Vacation;
 | 
					use Toby\Eloquent\Models\Vacation;
 | 
				
			||||||
use Toby\Eloquent\Models\YearPeriod;
 | 
					use Toby\Eloquent\Models\YearPeriod;
 | 
				
			||||||
@@ -54,7 +54,7 @@ class CalendarGenerator
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return Vacation::query()
 | 
					        return Vacation::query()
 | 
				
			||||||
            ->whereBetween("date", [$period->start, $period->end])
 | 
					            ->whereBetween("date", [$period->start, $period->end])
 | 
				
			||||||
            ->whereRelation("vacationRequest", "state", VacationRequestState::Approved->value)
 | 
					            ->whereRelation("vacationRequest", fn(Builder $query) => $query->states(VacationRequestStatesRetriever::successStates()))
 | 
				
			||||||
            ->get()
 | 
					            ->get()
 | 
				
			||||||
            ->groupBy(fn(Vacation $vacation) => $vacation->date->toDateString());
 | 
					            ->groupBy(fn(Vacation $vacation) => $vacation->date->toDateString());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,56 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
declare(strict_types=1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Toby\Domain\Enums;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum VacationRequestState: string
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    case Created = "created";
 | 
					 | 
				
			||||||
    case Cancelled = "cancelled";
 | 
					 | 
				
			||||||
    case Rejected = "rejected";
 | 
					 | 
				
			||||||
    case Approved = "approved";
 | 
					 | 
				
			||||||
    case WaitingForTechnical = "waiting_for_technical";
 | 
					 | 
				
			||||||
    case WaitingForAdministrative = "waiting_for_administrative";
 | 
					 | 
				
			||||||
    case AcceptedByTechnical = "accepted_by_technical";
 | 
					 | 
				
			||||||
    case AcceptedByAdministrative = "accepted_by_administrative";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function label(): string
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return __($this->value);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static function pendingStates(): array
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            self::Created,
 | 
					 | 
				
			||||||
            self::WaitingForTechnical,
 | 
					 | 
				
			||||||
            self::WaitingForAdministrative,
 | 
					 | 
				
			||||||
            self::AcceptedByTechnical,
 | 
					 | 
				
			||||||
            self::AcceptedByAdministrative,
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static function successStates(): array
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return [self::Approved];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static function failedStates(): array
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return [
 | 
					 | 
				
			||||||
            self::Rejected,
 | 
					 | 
				
			||||||
            self::Cancelled,
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static function filterByStatus(string $filter): array
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return match ($filter) {
 | 
					 | 
				
			||||||
            "pending" => VacationRequestState::pendingStates(),
 | 
					 | 
				
			||||||
            "success" => VacationRequestState::successStates(),
 | 
					 | 
				
			||||||
            "failed" => VacationRequestState::failedStates(),
 | 
					 | 
				
			||||||
            default => VacationRequestState::cases(),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -6,7 +6,7 @@ namespace Toby\Domain\Events;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use Illuminate\Foundation\Events\Dispatchable;
 | 
					use Illuminate\Foundation\Events\Dispatchable;
 | 
				
			||||||
use Illuminate\Queue\SerializesModels;
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					use Toby\Domain\States\VacationRequest\VacationRequestState;
 | 
				
			||||||
use Toby\Eloquent\Models\User;
 | 
					use Toby\Eloquent\Models\User;
 | 
				
			||||||
use Toby\Eloquent\Models\VacationRequest;
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										51
									
								
								app/Domain/Policies/VacationRequestPolicy.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								app/Domain/Policies/VacationRequestPolicy.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Toby\Domain\Policies;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Toby\Domain\Enums\Role;
 | 
				
			||||||
 | 
					use Toby\Eloquent\Models\User;
 | 
				
			||||||
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class VacationRequestPolicy
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function createOnBehalfOfEmployee(User $user): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $user->role === Role::AdministrativeApprover;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function acceptAsAdminApprover(User $user): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $user->role === Role::AdministrativeApprover;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function acceptAsTechApprover(User $user): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $user->role === Role::TechnicalApprover;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function skipFlow(User $user): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $user->role === Role::AdministrativeApprover;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function reject(User $user): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return in_array($user->role, [Role::AdministrativeApprover, Role::TechnicalApprover], true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function cancel(User $user): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $user->role === Role::AdministrativeApprover;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function show(User $user, VacationRequest $vacationRequest): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($vacationRequest->user->is($user)) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return in_array($user->role, [Role::TechnicalApprover, Role::AdministrativeApprover], true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Toby\Domain\States\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AcceptedByAdministrative extends VacationRequestState
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static string $name = "accepted_by_administrative";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								app/Domain/States/VacationRequest/AcceptedByTechnical.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/Domain/States/VacationRequest/AcceptedByTechnical.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Toby\Domain\States\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AcceptedByTechnical extends VacationRequestState
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static string $name = "accepted_by_technical";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								app/Domain/States/VacationRequest/Approved.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/Domain/States/VacationRequest/Approved.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Toby\Domain\States\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Approved extends VacationRequestState
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static string $name = "approved";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								app/Domain/States/VacationRequest/Cancelled.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/Domain/States/VacationRequest/Cancelled.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Toby\Domain\States\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Cancelled extends VacationRequestState
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static string $name = "cancelled";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								app/Domain/States/VacationRequest/Created.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/Domain/States/VacationRequest/Created.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Toby\Domain\States\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Created extends VacationRequestState
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static string $name = "created";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								app/Domain/States/VacationRequest/Rejected.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/Domain/States/VacationRequest/Rejected.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Toby\Domain\States\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Rejected extends VacationRequestState
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static string $name = "rejected";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										39
									
								
								app/Domain/States/VacationRequest/VacationRequestState.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/Domain/States/VacationRequest/VacationRequestState.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Toby\Domain\States\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Spatie\ModelStates\Exceptions\InvalidConfig;
 | 
				
			||||||
 | 
					use Spatie\ModelStates\State;
 | 
				
			||||||
 | 
					use Spatie\ModelStates\StateConfig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					abstract class VacationRequestState extends State
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws InvalidConfig
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static function config(): StateConfig
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return parent::config()
 | 
				
			||||||
 | 
					            ->default(Created::class)
 | 
				
			||||||
 | 
					            ->allowTransition(Created::class, Approved::class)
 | 
				
			||||||
 | 
					            ->allowTransition(Created::class, WaitingForTechnical::class)
 | 
				
			||||||
 | 
					            ->allowTransition(Created::class, WaitingForAdministrative::class)
 | 
				
			||||||
 | 
					            ->allowTransition(WaitingForTechnical::class, Rejected::class)
 | 
				
			||||||
 | 
					            ->allowTransition(WaitingForTechnical::class, AcceptedByTechnical::class)
 | 
				
			||||||
 | 
					            ->allowTransition(WaitingForAdministrative::class, Rejected::class)
 | 
				
			||||||
 | 
					            ->allowTransition(WaitingForAdministrative::class, AcceptedByAdministrative::class)
 | 
				
			||||||
 | 
					            ->allowTransition(AcceptedByTechnical::class, WaitingForAdministrative::class)
 | 
				
			||||||
 | 
					            ->allowTransition(AcceptedByTechnical::class, Approved::class)
 | 
				
			||||||
 | 
					            ->allowTransition(AcceptedByAdministrative::class, Approved::class)
 | 
				
			||||||
 | 
					            ->allowTransition([
 | 
				
			||||||
 | 
					                Created::class,
 | 
				
			||||||
 | 
					                WaitingForTechnical::class,
 | 
				
			||||||
 | 
					                WaitingForAdministrative::class,
 | 
				
			||||||
 | 
					                AcceptedByTechnical::class,
 | 
				
			||||||
 | 
					                AcceptedByAdministrative::class,
 | 
				
			||||||
 | 
					                Approved::class,
 | 
				
			||||||
 | 
					            ], Cancelled::class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Toby\Domain\States\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WaitingForAdministrative extends VacationRequestState
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static string $name = "waiting_for_administrative";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								app/Domain/States/VacationRequest/WaitingForTechnical.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/Domain/States/VacationRequest/WaitingForTechnical.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Toby\Domain\States\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WaitingForTechnical extends VacationRequestState
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static string $name = "waiting_for_technical";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -6,7 +6,6 @@ namespace Toby\Domain;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Collection;
 | 
					use Illuminate\Database\Eloquent\Collection;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					 | 
				
			||||||
use Toby\Domain\Enums\VacationType;
 | 
					use Toby\Domain\Enums\VacationType;
 | 
				
			||||||
use Toby\Eloquent\Models\User;
 | 
					use Toby\Eloquent\Models\User;
 | 
				
			||||||
use Toby\Eloquent\Models\YearPeriod;
 | 
					use Toby\Eloquent\Models\YearPeriod;
 | 
				
			||||||
@@ -26,7 +25,7 @@ class UserVacationStatsRetriever
 | 
				
			|||||||
                "vacationRequest",
 | 
					                "vacationRequest",
 | 
				
			||||||
                fn(Builder $query) => $query
 | 
					                fn(Builder $query) => $query
 | 
				
			||||||
                    ->whereIn("type", $this->getLimitableVacationTypes())
 | 
					                    ->whereIn("type", $this->getLimitableVacationTypes())
 | 
				
			||||||
                    ->states(VacationRequestState::successStates()),
 | 
					                    ->states(VacationRequestStatesRetriever::successStates()),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            ->count();
 | 
					            ->count();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -40,7 +39,7 @@ class UserVacationStatsRetriever
 | 
				
			|||||||
                "vacationRequest",
 | 
					                "vacationRequest",
 | 
				
			||||||
                fn(Builder $query) => $query
 | 
					                fn(Builder $query) => $query
 | 
				
			||||||
                    ->whereIn("type", $this->getLimitableVacationTypes())
 | 
					                    ->whereIn("type", $this->getLimitableVacationTypes())
 | 
				
			||||||
                    ->states(VacationRequestState::pendingStates()),
 | 
					                    ->states(VacationRequestStatesRetriever::pendingStates()),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            ->count();
 | 
					            ->count();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -54,7 +53,7 @@ class UserVacationStatsRetriever
 | 
				
			|||||||
                "vacationRequest",
 | 
					                "vacationRequest",
 | 
				
			||||||
                fn(Builder $query) => $query
 | 
					                fn(Builder $query) => $query
 | 
				
			||||||
                    ->whereIn("type", $this->getNotLimitableVacationTypes())
 | 
					                    ->whereIn("type", $this->getNotLimitableVacationTypes())
 | 
				
			||||||
                    ->states(VacationRequestState::successStates()),
 | 
					                    ->states(VacationRequestStatesRetriever::successStates()),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            ->count();
 | 
					            ->count();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,15 +6,24 @@ namespace Toby\Domain;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use Illuminate\Contracts\Auth\Factory as Auth;
 | 
					use Illuminate\Contracts\Auth\Factory as Auth;
 | 
				
			||||||
use Illuminate\Contracts\Events\Dispatcher;
 | 
					use Illuminate\Contracts\Events\Dispatcher;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					 | 
				
			||||||
use Toby\Domain\Events\VacationRequestAcceptedByAdministrative;
 | 
					use Toby\Domain\Events\VacationRequestAcceptedByAdministrative;
 | 
				
			||||||
use Toby\Domain\Events\VacationRequestAcceptedByTechnical;
 | 
					use Toby\Domain\Events\VacationRequestAcceptedByTechnical;
 | 
				
			||||||
use Toby\Domain\Events\VacationRequestApproved;
 | 
					use Toby\Domain\Events\VacationRequestApproved;
 | 
				
			||||||
use Toby\Domain\Events\VacationRequestCancelled;
 | 
					use Toby\Domain\Events\VacationRequestCancelled;
 | 
				
			||||||
use Toby\Domain\Events\VacationRequestCreated;
 | 
					use Toby\Domain\Events\VacationRequestCreated;
 | 
				
			||||||
use Toby\Domain\Events\VacationRequestRejected;
 | 
					use Toby\Domain\Events\VacationRequestRejected;
 | 
				
			||||||
 | 
					use Toby\Domain\Events\VacationRequestStateChanged;
 | 
				
			||||||
use Toby\Domain\Events\VacationRequestWaitsForAdminApproval;
 | 
					use Toby\Domain\Events\VacationRequestWaitsForAdminApproval;
 | 
				
			||||||
use Toby\Domain\Events\VacationRequestWaitsForTechApproval;
 | 
					use Toby\Domain\Events\VacationRequestWaitsForTechApproval;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\AcceptedByAdministrative;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\AcceptedByTechnical;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Approved;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Cancelled;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Rejected;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\VacationRequestState;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\WaitingForAdministrative;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\WaitingForTechnical;
 | 
				
			||||||
 | 
					use Toby\Eloquent\Models\User;
 | 
				
			||||||
use Toby\Eloquent\Models\VacationRequest;
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VacationRequestStateManager
 | 
					class VacationRequestStateManager
 | 
				
			||||||
@@ -24,64 +33,77 @@ class VacationRequestStateManager
 | 
				
			|||||||
        protected Dispatcher $dispatcher,
 | 
					        protected Dispatcher $dispatcher,
 | 
				
			||||||
    ) {}
 | 
					    ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function markAsCreated(VacationRequest $vacationRequest): void
 | 
					    public function markAsCreated(VacationRequest $vacationRequest, ?User $user = null): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->changeState($vacationRequest, VacationRequestState::Created);
 | 
					        $this->fireStateChangedEvent($vacationRequest, null, $vacationRequest->state, $user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->dispatcher->dispatch(new VacationRequestCreated($vacationRequest));
 | 
					        $this->dispatcher->dispatch(new VacationRequestCreated($vacationRequest));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function approve(VacationRequest $vacationRequest): void
 | 
					    public function approve(VacationRequest $vacationRequest, ?User $user = null): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->changeState($vacationRequest, VacationRequestState::Approved);
 | 
					        $this->changeState($vacationRequest, Approved::class, $user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->dispatcher->dispatch(new VacationRequestApproved($vacationRequest));
 | 
					        $this->dispatcher->dispatch(new VacationRequestApproved($vacationRequest));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function reject(VacationRequest $vacationRequest): void
 | 
					    public function reject(VacationRequest $vacationRequest, ?User $user = null): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->changeState($vacationRequest, VacationRequestState::Rejected);
 | 
					        $this->changeState($vacationRequest, Rejected::class, $user);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->dispatcher->dispatch(new VacationRequestRejected($vacationRequest));
 | 
					        $this->dispatcher->dispatch(new VacationRequestRejected($vacationRequest));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function cancel(VacationRequest $vacationRequest): void
 | 
					    public function cancel(VacationRequest $vacationRequest, ?User $user = null): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->changeState($vacationRequest, VacationRequestState::Cancelled);
 | 
					        $this->changeState($vacationRequest, Cancelled::class, $user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->dispatcher->dispatch(new VacationRequestCancelled($vacationRequest));
 | 
					        $this->dispatcher->dispatch(new VacationRequestCancelled($vacationRequest));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function acceptAsTechnical(VacationRequest $vacationRequest): void
 | 
					    public function acceptAsTechnical(VacationRequest $vacationRequest, ?User $user = null): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->changeState($vacationRequest, VacationRequestState::AcceptedByTechnical);
 | 
					        $this->changeState($vacationRequest, AcceptedByTechnical::class, $user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->dispatcher->dispatch(new VacationRequestAcceptedByTechnical($vacationRequest));
 | 
					        $this->dispatcher->dispatch(new VacationRequestAcceptedByTechnical($vacationRequest));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function acceptAsAdministrative(VacationRequest $vacationRequest): void
 | 
					    public function acceptAsAdministrative(VacationRequest $vacationRequest, ?User $user = null): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->changeState($vacationRequest, VacationRequestState::AcceptedByAdministrative);
 | 
					        $this->changeState($vacationRequest, AcceptedByAdministrative::class, $user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->dispatcher->dispatch(new VacationRequestAcceptedByAdministrative($vacationRequest));
 | 
					        $this->dispatcher->dispatch(new VacationRequestAcceptedByAdministrative($vacationRequest));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function waitForTechnical(VacationRequest $vacationRequest): void
 | 
					    public function waitForTechnical(VacationRequest $vacationRequest, ?User $user = null): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->changeState($vacationRequest, VacationRequestState::WaitingForTechnical);
 | 
					        $this->changeState($vacationRequest, WaitingForTechnical::class, $user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->dispatcher->dispatch(new VacationRequestWaitsForTechApproval($vacationRequest));
 | 
					        $this->dispatcher->dispatch(new VacationRequestWaitsForTechApproval($vacationRequest));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function waitForAdministrative(VacationRequest $vacationRequest): void
 | 
					    public function waitForAdministrative(VacationRequest $vacationRequest, ?User $user = null): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->changeState($vacationRequest, VacationRequestState::WaitingForAdministrative);
 | 
					        $this->changeState($vacationRequest, WaitingForAdministrative::class, $user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->dispatcher->dispatch(new VacationRequestWaitsForAdminApproval($vacationRequest));
 | 
					        $this->dispatcher->dispatch(new VacationRequestWaitsForAdminApproval($vacationRequest));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected function changeState(VacationRequest $vacationRequest, VacationRequestState $state): void
 | 
					    protected function changeState(VacationRequest $vacationRequest, string $state, ?User $user = null): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $vacationRequest->changeStateTo($state);
 | 
					        $previousState = $vacationRequest->state;
 | 
				
			||||||
 | 
					        $vacationRequest->state->transitionTo($state);
 | 
				
			||||||
 | 
					        $vacationRequest->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->fireStateChangedEvent($vacationRequest, $previousState, $vacationRequest->state, $user);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function fireStateChangedEvent(
 | 
				
			||||||
 | 
					        VacationRequest $vacationRequest,
 | 
				
			||||||
 | 
					        ?VacationRequestState $from,
 | 
				
			||||||
 | 
					        VacationRequestState $to,
 | 
				
			||||||
 | 
					        ?User $user = null,
 | 
				
			||||||
 | 
					    ): void {
 | 
				
			||||||
 | 
					        $event = new VacationRequestStateChanged($vacationRequest, $from, $to, $user);
 | 
				
			||||||
 | 
					        $this->dispatcher->dispatch($event);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										60
									
								
								app/Domain/VacationRequestStatesRetriever.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								app/Domain/VacationRequestStatesRetriever.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Toby\Domain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\AcceptedByAdministrative;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\AcceptedByTechnical;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Approved;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Cancelled;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Created;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Rejected;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\WaitingForAdministrative;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\WaitingForTechnical;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class VacationRequestStatesRetriever
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static function pendingStates(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            Created::class,
 | 
				
			||||||
 | 
					            WaitingForTechnical::class,
 | 
				
			||||||
 | 
					            WaitingForAdministrative::class,
 | 
				
			||||||
 | 
					            AcceptedByTechnical::class,
 | 
				
			||||||
 | 
					            AcceptedByAdministrative::class,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function successStates(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [Approved::class];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function failedStates(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            Rejected::class,
 | 
				
			||||||
 | 
					            Cancelled::class,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function all(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            ...self::pendingStates(),
 | 
				
			||||||
 | 
					            ...self::successStates(),
 | 
				
			||||||
 | 
					            ...self::failedStates(),
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static function filterByStatus(string $filter): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return match ($filter) {
 | 
				
			||||||
 | 
					            "pending" => self::pendingStates(),
 | 
				
			||||||
 | 
					            "success" => self::successStates(),
 | 
				
			||||||
 | 
					            "failed" => self::failedStates(),
 | 
				
			||||||
 | 
					            default => self::all(),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -6,9 +6,9 @@ namespace Toby\Domain\Validation\Rules;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Collection;
 | 
					use Illuminate\Database\Eloquent\Collection;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					 | 
				
			||||||
use Toby\Domain\Enums\VacationType;
 | 
					use Toby\Domain\Enums\VacationType;
 | 
				
			||||||
use Toby\Domain\VacationDaysCalculator;
 | 
					use Toby\Domain\VacationDaysCalculator;
 | 
				
			||||||
 | 
					use Toby\Domain\VacationRequestStatesRetriever;
 | 
				
			||||||
use Toby\Domain\VacationTypeConfigRetriever;
 | 
					use Toby\Domain\VacationTypeConfigRetriever;
 | 
				
			||||||
use Toby\Eloquent\Models\User;
 | 
					use Toby\Eloquent\Models\User;
 | 
				
			||||||
use Toby\Eloquent\Models\VacationRequest;
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
@@ -52,7 +52,7 @@ class DoesNotExceedLimitRule implements VacationRequestRule
 | 
				
			|||||||
                "vacationRequest",
 | 
					                "vacationRequest",
 | 
				
			||||||
                fn(Builder $query) => $query
 | 
					                fn(Builder $query) => $query
 | 
				
			||||||
                    ->whereIn("type", $this->getLimitableVacationTypes())
 | 
					                    ->whereIn("type", $this->getLimitableVacationTypes())
 | 
				
			||||||
                    ->noStates(VacationRequestState::failedStates()),
 | 
					                    ->noStates(VacationRequestStatesRetriever::failedStates()),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            ->count();
 | 
					            ->count();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Toby\Domain\Validation\Rules;
 | 
					namespace Toby\Domain\Validation\Rules;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					use Toby\Domain\VacationRequestStatesRetriever;
 | 
				
			||||||
use Toby\Eloquent\Models\VacationRequest;
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NoApprovedVacationRequestsInRange implements VacationRequestRule
 | 
					class NoApprovedVacationRequestsInRange implements VacationRequestRule
 | 
				
			||||||
@@ -15,7 +15,7 @@ class NoApprovedVacationRequestsInRange implements VacationRequestRule
 | 
				
			|||||||
            ->user
 | 
					            ->user
 | 
				
			||||||
            ->vacationRequests()
 | 
					            ->vacationRequests()
 | 
				
			||||||
            ->overlapsWith($vacationRequest)
 | 
					            ->overlapsWith($vacationRequest)
 | 
				
			||||||
            ->states(VacationRequestState::successStates())
 | 
					            ->states(VacationRequestStatesRetriever::successStates())
 | 
				
			||||||
            ->exists();
 | 
					            ->exists();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Toby\Domain\Validation\Rules;
 | 
					namespace Toby\Domain\Validation\Rules;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					use Toby\Domain\VacationRequestStatesRetriever;
 | 
				
			||||||
use Toby\Eloquent\Models\VacationRequest;
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NoPendingVacationRequestInRange implements VacationRequestRule
 | 
					class NoPendingVacationRequestInRange implements VacationRequestRule
 | 
				
			||||||
@@ -15,7 +15,7 @@ class NoPendingVacationRequestInRange implements VacationRequestRule
 | 
				
			|||||||
            ->user
 | 
					            ->user
 | 
				
			||||||
            ->vacationRequests()
 | 
					            ->vacationRequests()
 | 
				
			||||||
            ->overlapsWith($vacationRequest)
 | 
					            ->overlapsWith($vacationRequest)
 | 
				
			||||||
            ->states(VacationRequestState::pendingStates())
 | 
					            ->states(VacationRequestStatesRetriever::pendingStates())
 | 
				
			||||||
            ->exists();
 | 
					            ->exists();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,8 +12,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
 | 
				
			|||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
 | 
					use Illuminate\Database\Eloquent\Relations\HasMany;
 | 
				
			||||||
use Illuminate\Support\Carbon;
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
use Illuminate\Support\Collection;
 | 
					use Illuminate\Support\Collection;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					use Spatie\ModelStates\HasStates;
 | 
				
			||||||
use Toby\Domain\Enums\VacationType;
 | 
					use Toby\Domain\Enums\VacationType;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\VacationRequestState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @property int $id
 | 
					 * @property int $id
 | 
				
			||||||
@@ -34,6 +35,7 @@ use Toby\Domain\Enums\VacationType;
 | 
				
			|||||||
class VacationRequest extends Model
 | 
					class VacationRequest extends Model
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use HasFactory;
 | 
					    use HasFactory;
 | 
				
			||||||
 | 
					    use HasStates;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $guarded = [];
 | 
					    protected $guarded = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -69,26 +71,14 @@ class VacationRequest extends Model
 | 
				
			|||||||
        return $this->hasMany(Vacation::class);
 | 
					        return $this->hasMany(Vacation::class);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function changeStateTo(VacationRequestState $state): void
 | 
					    public function scopeStates(Builder $query, VacationRequestState|array $states): Builder
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->state = $state;
 | 
					        return $query->whereState("state", $states);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->save();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function hasFlowSkipped(): bool
 | 
					    public function scopeNoStates(Builder $query, VacationRequestState|array $states): Builder
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return $this->flow_skipped;
 | 
					        return $query->whereNotState("state", $states);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function scopeStates(Builder $query, array $states): Builder
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $query->whereIn("state", $states);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function scopeNoStates(Builder $query, array $states): Builder
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return $query->whereNotIn("state", $states);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function scopeOverlapsWith(Builder $query, self $vacationRequest): Builder
 | 
					    public function scopeOverlapsWith(Builder $query, self $vacationRequest): Builder
 | 
				
			||||||
@@ -97,6 +87,11 @@ class VacationRequest extends Model
 | 
				
			|||||||
            ->where("to", ">=", $vacationRequest->from);
 | 
					            ->where("to", ">=", $vacationRequest->from);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function hasFlowSkipped(): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->flow_skipped;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected static function newFactory(): VacationRequestFactory
 | 
					    protected static function newFactory(): VacationRequestFactory
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return VacationRequestFactory::new();
 | 
					        return VacationRequestFactory::new();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ use Database\Factories\VacationRequestActivityFactory;
 | 
				
			|||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
					use Illuminate\Database\Eloquent\Factories\HasFactory;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Model;
 | 
					use Illuminate\Database\Eloquent\Model;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
 | 
					use Illuminate\Database\Eloquent\Relations\BelongsTo;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					use Toby\Domain\States\VacationRequest\VacationRequestState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @property int $id
 | 
					 * @property int $id
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,9 +6,6 @@ namespace Toby\Eloquent\Observers;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use Illuminate\Contracts\Auth\Factory as Auth;
 | 
					use Illuminate\Contracts\Auth\Factory as Auth;
 | 
				
			||||||
use Illuminate\Contracts\Events\Dispatcher;
 | 
					use Illuminate\Contracts\Events\Dispatcher;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					 | 
				
			||||||
use Toby\Domain\Events\VacationRequestStateChanged;
 | 
					 | 
				
			||||||
use Toby\Eloquent\Models\User;
 | 
					 | 
				
			||||||
use Toby\Eloquent\Models\VacationRequest;
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VacationRequestObserver
 | 
					class VacationRequestObserver
 | 
				
			||||||
@@ -28,31 +25,4 @@ class VacationRequestObserver
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $vacationRequest->name = "{$vacationRequestNumber}/${year}";
 | 
					        $vacationRequest->name = "{$vacationRequestNumber}/${year}";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function saved(VacationRequest $vacationRequest): void
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if ($vacationRequest->isDirty("state")) {
 | 
					 | 
				
			||||||
            $previousState = $vacationRequest->getOriginal("state");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            $this->fireStateChangedEvent($vacationRequest, $previousState, $vacationRequest->state);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected function fireStateChangedEvent(
 | 
					 | 
				
			||||||
        VacationRequest $vacationRequest,
 | 
					 | 
				
			||||||
        ?VacationRequestState $from,
 | 
					 | 
				
			||||||
        VacationRequestState $to,
 | 
					 | 
				
			||||||
    ): void {
 | 
					 | 
				
			||||||
        $event = new VacationRequestStateChanged($vacationRequest, $from, $to, $this->getAuthUser());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->dispatcher->dispatch($event);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected function getAuthUser(): ?User
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        /** @var User $user */
 | 
					 | 
				
			||||||
        $user = $this->auth->guard()->user();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return $user;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,8 +8,8 @@ use Illuminate\Database\Eloquent\Builder;
 | 
				
			|||||||
use Illuminate\Http\Request;
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
use Illuminate\Support\Carbon;
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
use Inertia\Response;
 | 
					use Inertia\Response;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					 | 
				
			||||||
use Toby\Domain\UserVacationStatsRetriever;
 | 
					use Toby\Domain\UserVacationStatsRetriever;
 | 
				
			||||||
 | 
					use Toby\Domain\VacationRequestStatesRetriever;
 | 
				
			||||||
use Toby\Eloquent\Models\Holiday;
 | 
					use Toby\Eloquent\Models\Holiday;
 | 
				
			||||||
use Toby\Eloquent\Models\Vacation;
 | 
					use Toby\Eloquent\Models\Vacation;
 | 
				
			||||||
use Toby\Eloquent\Models\VacationRequest;
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
@@ -31,7 +31,7 @@ class DashboardController extends Controller
 | 
				
			|||||||
            ->whereDate("date", $now)
 | 
					            ->whereDate("date", $now)
 | 
				
			||||||
            ->whereRelation(
 | 
					            ->whereRelation(
 | 
				
			||||||
                "vacationRequest",
 | 
					                "vacationRequest",
 | 
				
			||||||
                fn(Builder $query) => $query->states(VacationRequestState::successStates()),
 | 
					                fn(Builder $query) => $query->states(VacationRequestStatesRetriever::successStates()),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            ->get();
 | 
					            ->get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,9 @@ declare(strict_types=1);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Toby\Infrastructure\Http\Controllers;
 | 
					namespace Toby\Infrastructure\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Auth\Access\AuthorizationException;
 | 
				
			||||||
use Illuminate\Http\RedirectResponse;
 | 
					use Illuminate\Http\RedirectResponse;
 | 
				
			||||||
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
use Inertia\Response;
 | 
					use Inertia\Response;
 | 
				
			||||||
use Toby\Eloquent\Helpers\YearPeriodRetriever;
 | 
					use Toby\Eloquent\Helpers\YearPeriodRetriever;
 | 
				
			||||||
use Toby\Eloquent\Models\Holiday;
 | 
					use Toby\Eloquent\Models\Holiday;
 | 
				
			||||||
@@ -14,7 +16,7 @@ use Toby\Infrastructure\Http\Resources\HolidayResource;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class HolidayController extends Controller
 | 
					class HolidayController extends Controller
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function index(YearPeriodRetriever $yearPeriodRetriever): Response
 | 
					    public function index(Request $request, YearPeriodRetriever $yearPeriodRetriever): Response
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $yearPeriod = $yearPeriodRetriever->selected();
 | 
					        $yearPeriod = $yearPeriodRetriever->selected();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -25,16 +27,29 @@ class HolidayController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return inertia("Holidays/Index", [
 | 
					        return inertia("Holidays/Index", [
 | 
				
			||||||
            "holidays" => HolidayResource::collection($holidays),
 | 
					            "holidays" => HolidayResource::collection($holidays),
 | 
				
			||||||
 | 
					            "can" => [
 | 
				
			||||||
 | 
					                "manageHolidays" => $request->user()->can("manageHolidays"),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function create(): Response
 | 
					    public function create(): Response
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageHolidays");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return inertia("Holidays/Create");
 | 
					        return inertia("Holidays/Create");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function store(HolidayRequest $request): RedirectResponse
 | 
					    public function store(HolidayRequest $request): RedirectResponse
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageHolidays");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Holiday::query()->create($request->data());
 | 
					        Holiday::query()->create($request->data());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()
 | 
					        return redirect()
 | 
				
			||||||
@@ -42,15 +57,25 @@ class HolidayController extends Controller
 | 
				
			|||||||
            ->with("success", __("Holiday has been created."));
 | 
					            ->with("success", __("Holiday has been created."));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function edit(Holiday $holiday): Response
 | 
					    public function edit(Holiday $holiday): Response
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageHolidays");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return inertia("Holidays/Edit", [
 | 
					        return inertia("Holidays/Edit", [
 | 
				
			||||||
            "holiday" => new HolidayFormDataResource($holiday),
 | 
					            "holiday" => new HolidayFormDataResource($holiday),
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function update(HolidayRequest $request, Holiday $holiday): RedirectResponse
 | 
					    public function update(HolidayRequest $request, Holiday $holiday): RedirectResponse
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageHolidays");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $holiday->update($request->data());
 | 
					        $holiday->update($request->data());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()
 | 
					        return redirect()
 | 
				
			||||||
@@ -58,8 +83,13 @@ class HolidayController extends Controller
 | 
				
			|||||||
            ->with("success", __("Holiday has been updated."));
 | 
					            ->with("success", __("Holiday has been updated."));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function destroy(Holiday $holiday): RedirectResponse
 | 
					    public function destroy(Holiday $holiday): RedirectResponse
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageHolidays");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $holiday->delete();
 | 
					        $holiday->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()
 | 
					        return redirect()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,8 @@ class TimesheetController extends Controller
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public function __invoke(Month $month, YearPeriodRetriever $yearPeriodRetriever): BinaryFileResponse
 | 
					    public function __invoke(Month $month, YearPeriodRetriever $yearPeriodRetriever): BinaryFileResponse
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("generateTimesheet");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $yearPeriod = $yearPeriodRetriever->selected();
 | 
					        $yearPeriod = $yearPeriodRetriever->selected();
 | 
				
			||||||
        $carbonMonth = Carbon::create($yearPeriod->year, $month->toCarbonNumber());
 | 
					        $carbonMonth = Carbon::create($yearPeriod->year, $month->toCarbonNumber());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Toby\Infrastructure\Http\Controllers;
 | 
					namespace Toby\Infrastructure\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Auth\Access\AuthorizationException;
 | 
				
			||||||
use Illuminate\Http\RedirectResponse;
 | 
					use Illuminate\Http\RedirectResponse;
 | 
				
			||||||
use Illuminate\Http\Request;
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
use Inertia\Response;
 | 
					use Inertia\Response;
 | 
				
			||||||
@@ -16,8 +17,13 @@ use Toby\Infrastructure\Http\Resources\UserResource;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class UserController extends Controller
 | 
					class UserController extends Controller
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function index(Request $request): Response
 | 
					    public function index(Request $request): Response
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageUsers");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $users = User::query()
 | 
					        $users = User::query()
 | 
				
			||||||
            ->withTrashed()
 | 
					            ->withTrashed()
 | 
				
			||||||
            ->search($request->query("search"))
 | 
					            ->search($request->query("search"))
 | 
				
			||||||
@@ -32,16 +38,26 @@ class UserController extends Controller
 | 
				
			|||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function create(): Response
 | 
					    public function create(): Response
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageUsers");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return inertia("Users/Create", [
 | 
					        return inertia("Users/Create", [
 | 
				
			||||||
            "employmentForms" => EmploymentForm::casesToSelect(),
 | 
					            "employmentForms" => EmploymentForm::casesToSelect(),
 | 
				
			||||||
            "roles" => Role::casesToSelect(),
 | 
					            "roles" => Role::casesToSelect(),
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function store(UserRequest $request): RedirectResponse
 | 
					    public function store(UserRequest $request): RedirectResponse
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageUsers");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        User::query()->create($request->data());
 | 
					        User::query()->create($request->data());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()
 | 
					        return redirect()
 | 
				
			||||||
@@ -49,8 +65,13 @@ class UserController extends Controller
 | 
				
			|||||||
            ->with("success", __("User has been created."));
 | 
					            ->with("success", __("User has been created."));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function edit(User $user): Response
 | 
					    public function edit(User $user): Response
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageUsers");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return inertia("Users/Edit", [
 | 
					        return inertia("Users/Edit", [
 | 
				
			||||||
            "user" => new UserFormDataResource($user),
 | 
					            "user" => new UserFormDataResource($user),
 | 
				
			||||||
            "employmentForms" => EmploymentForm::casesToSelect(),
 | 
					            "employmentForms" => EmploymentForm::casesToSelect(),
 | 
				
			||||||
@@ -58,8 +79,13 @@ class UserController extends Controller
 | 
				
			|||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function update(UserRequest $request, User $user): RedirectResponse
 | 
					    public function update(UserRequest $request, User $user): RedirectResponse
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageUsers");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $user->update($request->data());
 | 
					        $user->update($request->data());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()
 | 
					        return redirect()
 | 
				
			||||||
@@ -67,8 +93,13 @@ class UserController extends Controller
 | 
				
			|||||||
            ->with("success", __("User has been updated."));
 | 
					            ->with("success", __("User has been updated."));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function destroy(User $user): RedirectResponse
 | 
					    public function destroy(User $user): RedirectResponse
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageUsers");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $user->delete();
 | 
					        $user->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()
 | 
					        return redirect()
 | 
				
			||||||
@@ -76,8 +107,13 @@ class UserController extends Controller
 | 
				
			|||||||
            ->with("success", __("User has been deleted."));
 | 
					            ->with("success", __("User has been deleted."));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function restore(User $user): RedirectResponse
 | 
					    public function restore(User $user): RedirectResponse
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageUsers");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $user->restore();
 | 
					        $user->restore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()
 | 
					        return redirect()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Toby\Infrastructure\Http\Controllers;
 | 
					namespace Toby\Infrastructure\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
use Illuminate\Support\Carbon;
 | 
					use Illuminate\Support\Carbon;
 | 
				
			||||||
use Inertia\Response;
 | 
					use Inertia\Response;
 | 
				
			||||||
use Toby\Domain\CalendarGenerator;
 | 
					use Toby\Domain\CalendarGenerator;
 | 
				
			||||||
@@ -15,6 +16,7 @@ use Toby\Infrastructure\Http\Resources\UserResource;
 | 
				
			|||||||
class VacationCalendarController extends Controller
 | 
					class VacationCalendarController extends Controller
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function index(
 | 
					    public function index(
 | 
				
			||||||
 | 
					        Request $request,
 | 
				
			||||||
        YearPeriodRetriever $yearPeriodRetriever,
 | 
					        YearPeriodRetriever $yearPeriodRetriever,
 | 
				
			||||||
        CalendarGenerator $calendarGenerator,
 | 
					        CalendarGenerator $calendarGenerator,
 | 
				
			||||||
        ?string $month = null,
 | 
					        ?string $month = null,
 | 
				
			||||||
@@ -35,6 +37,9 @@ class VacationCalendarController extends Controller
 | 
				
			|||||||
            "calendar" => $calendar,
 | 
					            "calendar" => $calendar,
 | 
				
			||||||
            "currentMonth" => $month->value,
 | 
					            "currentMonth" => $month->value,
 | 
				
			||||||
            "users" => UserResource::collection($users),
 | 
					            "users" => UserResource::collection($users),
 | 
				
			||||||
 | 
					            "can" => [
 | 
				
			||||||
 | 
					                "generateTimesheet" => $request->user()->can("generateTimesheet"),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,8 @@ class VacationLimitController extends Controller
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public function edit(YearPeriodRetriever $yearPeriodRetriever, UserVacationStatsRetriever $statsRetriever): Response
 | 
					    public function edit(YearPeriodRetriever $yearPeriodRetriever, UserVacationStatsRetriever $statsRetriever): Response
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageVacationLimits");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $yearPeriod = $yearPeriodRetriever->selected();
 | 
					        $yearPeriod = $yearPeriodRetriever->selected();
 | 
				
			||||||
        $previousYearPeriod = YearPeriod::findByYear($yearPeriod->year - 1);
 | 
					        $previousYearPeriod = YearPeriod::findByYear($yearPeriod->year - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,6 +46,8 @@ class VacationLimitController extends Controller
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function update(VacationLimitRequest $request): RedirectResponse
 | 
					    public function update(VacationLimitRequest $request): RedirectResponse
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("manageVacationLimits");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $data = $request->data();
 | 
					        $data = $request->data();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($request->vacationLimits() as $limit) {
 | 
					        foreach ($request->vacationLimits() as $limit) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,15 +5,21 @@ declare(strict_types=1);
 | 
				
			|||||||
namespace Toby\Infrastructure\Http\Controllers;
 | 
					namespace Toby\Infrastructure\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Barryvdh\DomPDF\Facade\Pdf;
 | 
					use Barryvdh\DomPDF\Facade\Pdf;
 | 
				
			||||||
 | 
					use Illuminate\Auth\Access\AuthorizationException;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Builder;
 | 
					use Illuminate\Database\Eloquent\Builder;
 | 
				
			||||||
use Illuminate\Http\RedirectResponse;
 | 
					use Illuminate\Http\RedirectResponse;
 | 
				
			||||||
use Illuminate\Http\Request;
 | 
					use Illuminate\Http\Request;
 | 
				
			||||||
use Illuminate\Http\Response as LaravelResponse;
 | 
					use Illuminate\Http\Response as LaravelResponse;
 | 
				
			||||||
 | 
					use Illuminate\Validation\ValidationException;
 | 
				
			||||||
use Inertia\Response;
 | 
					use Inertia\Response;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					 | 
				
			||||||
use Toby\Domain\Enums\VacationType;
 | 
					use Toby\Domain\Enums\VacationType;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\AcceptedByAdministrative;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\AcceptedByTechnical;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Cancelled;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Rejected;
 | 
				
			||||||
use Toby\Domain\VacationDaysCalculator;
 | 
					use Toby\Domain\VacationDaysCalculator;
 | 
				
			||||||
use Toby\Domain\VacationRequestStateManager;
 | 
					use Toby\Domain\VacationRequestStateManager;
 | 
				
			||||||
 | 
					use Toby\Domain\VacationRequestStatesRetriever;
 | 
				
			||||||
use Toby\Domain\Validation\VacationRequestValidator;
 | 
					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;
 | 
				
			||||||
@@ -34,7 +40,7 @@ class VacationRequestController extends Controller
 | 
				
			|||||||
            ->with("vacations")
 | 
					            ->with("vacations")
 | 
				
			||||||
            ->where("year_period_id", $yearPeriodRetriever->selected()->id)
 | 
					            ->where("year_period_id", $yearPeriodRetriever->selected()->id)
 | 
				
			||||||
            ->latest()
 | 
					            ->latest()
 | 
				
			||||||
            ->states(VacationRequestState::filterByStatus($status))
 | 
					            ->states(VacationRequestStatesRetriever::filterByStatus($status))
 | 
				
			||||||
            ->paginate();
 | 
					            ->paginate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return inertia("VacationRequest/Index", [
 | 
					        return inertia("VacationRequest/Index", [
 | 
				
			||||||
@@ -45,16 +51,37 @@ class VacationRequestController extends Controller
 | 
				
			|||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function show(VacationRequest $vacationRequest): Response
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function show(Request $request, VacationRequest $vacationRequest): Response
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("show", $vacationRequest);
 | 
				
			||||||
 | 
					        $user = $request->user();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return inertia("VacationRequest/Show", [
 | 
					        return inertia("VacationRequest/Show", [
 | 
				
			||||||
            "request" => new VacationRequestResource($vacationRequest),
 | 
					            "request" => new VacationRequestResource($vacationRequest),
 | 
				
			||||||
            "activities" => VacationRequestActivityResource::collection($vacationRequest->activities),
 | 
					            "activities" => VacationRequestActivityResource::collection($vacationRequest->activities),
 | 
				
			||||||
 | 
					            "can" => [
 | 
				
			||||||
 | 
					                "acceptAsTechnical" => $vacationRequest->state->canTransitionTo(AcceptedByTechnical::class)
 | 
				
			||||||
 | 
					                    && $user->can("acceptAsTechApprover", $vacationRequest),
 | 
				
			||||||
 | 
					                "acceptAsAdministrative" => $vacationRequest->state->canTransitionTo(AcceptedByAdministrative::class)
 | 
				
			||||||
 | 
					                    && $user->can("acceptAsAdminApprover", $vacationRequest),
 | 
				
			||||||
 | 
					                "reject" => $vacationRequest->state->canTransitionTo(Rejected::class)
 | 
				
			||||||
 | 
					                    && $user->can("reject", $vacationRequest),
 | 
				
			||||||
 | 
					                "cancel" => $vacationRequest->state->canTransitionTo(Cancelled::class)
 | 
				
			||||||
 | 
					                    && $user->can("cancel", $vacationRequest),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function download(VacationRequest $vacationRequest): LaravelResponse
 | 
					    public function download(VacationRequest $vacationRequest): LaravelResponse
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $this->authorize("show", $vacationRequest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $pdf = PDF::loadView("pdf.vacation-request", [
 | 
					        $pdf = PDF::loadView("pdf.vacation-request", [
 | 
				
			||||||
            "vacationRequest" => $vacationRequest,
 | 
					            "vacationRequest" => $vacationRequest,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
@@ -62,7 +89,7 @@ class VacationRequestController extends Controller
 | 
				
			|||||||
        return $pdf->stream();
 | 
					        return $pdf->stream();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function create(YearPeriodRetriever $yearPeriodRetriever): Response
 | 
					    public function create(Request $request, YearPeriodRetriever $yearPeriodRetriever): Response
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $yearPeriod = $yearPeriodRetriever->selected();
 | 
					        $yearPeriod = $yearPeriodRetriever->selected();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -78,15 +105,31 @@ class VacationRequestController extends Controller
 | 
				
			|||||||
        return inertia("VacationRequest/Create", [
 | 
					        return inertia("VacationRequest/Create", [
 | 
				
			||||||
            "vacationTypes" => VacationType::casesToSelect(),
 | 
					            "vacationTypes" => VacationType::casesToSelect(),
 | 
				
			||||||
            "users" => UserResource::collection($users),
 | 
					            "users" => UserResource::collection($users),
 | 
				
			||||||
 | 
					            "can" => [
 | 
				
			||||||
 | 
					                "createOnBehalfOfEmployee" => $request->user()->can("createOnBehalfOfEmployee", VacationRequest::class),
 | 
				
			||||||
 | 
					                "skipFlow" => $request->user()->can("skipFlow", VacationRequest::class),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     * @throws ValidationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function store(
 | 
					    public function store(
 | 
				
			||||||
        VacationRequestRequest $request,
 | 
					        VacationRequestRequest $request,
 | 
				
			||||||
        VacationRequestValidator $vacationRequestValidator,
 | 
					        VacationRequestValidator $vacationRequestValidator,
 | 
				
			||||||
        VacationRequestStateManager $stateManager,
 | 
					        VacationRequestStateManager $stateManager,
 | 
				
			||||||
        VacationDaysCalculator $vacationDaysCalculator,
 | 
					        VacationDaysCalculator $vacationDaysCalculator,
 | 
				
			||||||
    ): RedirectResponse {
 | 
					    ): RedirectResponse {
 | 
				
			||||||
 | 
					        if ($request->createsOnBehalfOfEmployee()) {
 | 
				
			||||||
 | 
					            $this->authorize("createOnBehalfOfEmployee", VacationRequest::class);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($request->wantsSkipFlow()) {
 | 
				
			||||||
 | 
					            $this->authorize("skipFlow", VacationRequest::class);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /** @var VacationRequest $vacationRequest */
 | 
					        /** @var VacationRequest $vacationRequest */
 | 
				
			||||||
        $vacationRequest = $request->user()->createdVacationRequests()->make($request->data());
 | 
					        $vacationRequest = $request->user()->createdVacationRequests()->make($request->data());
 | 
				
			||||||
        $vacationRequestValidator->validate($vacationRequest);
 | 
					        $vacationRequestValidator->validate($vacationRequest);
 | 
				
			||||||
@@ -107,48 +150,72 @@ class VacationRequestController extends Controller
 | 
				
			|||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $stateManager->markAsCreated($vacationRequest);
 | 
					        $stateManager->markAsCreated($vacationRequest, $request->user());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()
 | 
					        return redirect()
 | 
				
			||||||
            ->route("vacation.requests.show", $vacationRequest)
 | 
					            ->route("vacation.requests.show", $vacationRequest)
 | 
				
			||||||
            ->with("success", __("Vacation request has been created."));
 | 
					            ->with("success", __("Vacation request has been created."));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function reject(
 | 
					    public function reject(
 | 
				
			||||||
 | 
					        Request $request,
 | 
				
			||||||
        VacationRequest $vacationRequest,
 | 
					        VacationRequest $vacationRequest,
 | 
				
			||||||
        VacationRequestStateManager $stateManager,
 | 
					        VacationRequestStateManager $stateManager,
 | 
				
			||||||
    ): RedirectResponse {
 | 
					    ): RedirectResponse {
 | 
				
			||||||
        $stateManager->reject($vacationRequest);
 | 
					        $this->authorize("reject", $vacationRequest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $stateManager->reject($vacationRequest, $request->user());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()->back()
 | 
					        return redirect()->back()
 | 
				
			||||||
            ->with("success", __("Vacation request has been rejected."));
 | 
					            ->with("success", __("Vacation request has been rejected."));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function cancel(
 | 
					    public function cancel(
 | 
				
			||||||
 | 
					        Request $request,
 | 
				
			||||||
        VacationRequest $vacationRequest,
 | 
					        VacationRequest $vacationRequest,
 | 
				
			||||||
        VacationRequestStateManager $stateManager,
 | 
					        VacationRequestStateManager $stateManager,
 | 
				
			||||||
    ): RedirectResponse {
 | 
					    ): RedirectResponse {
 | 
				
			||||||
        $stateManager->cancel($vacationRequest);
 | 
					        $this->authorize("cancel", $vacationRequest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $stateManager->cancel($vacationRequest, $request->user());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()->back()
 | 
					        return redirect()->back()
 | 
				
			||||||
            ->with("success", __("Vacation request has been cancelled."));
 | 
					            ->with("success", __("Vacation request has been cancelled."));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function acceptAsTechnical(
 | 
					    public function acceptAsTechnical(
 | 
				
			||||||
 | 
					        Request $request,
 | 
				
			||||||
        VacationRequest $vacationRequest,
 | 
					        VacationRequest $vacationRequest,
 | 
				
			||||||
        VacationRequestStateManager $stateManager,
 | 
					        VacationRequestStateManager $stateManager,
 | 
				
			||||||
    ): RedirectResponse {
 | 
					    ): RedirectResponse {
 | 
				
			||||||
        $stateManager->acceptAsTechnical($vacationRequest);
 | 
					        $this->authorize("acceptAsTechApprover", $vacationRequest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $stateManager->acceptAsTechnical($vacationRequest, $request->user());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()->back()
 | 
					        return redirect()->back()
 | 
				
			||||||
            ->with("success", __("Vacation request has been accepted."));
 | 
					            ->with("success", __("Vacation request has been accepted."));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @throws AuthorizationException
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public function acceptAsAdministrative(
 | 
					    public function acceptAsAdministrative(
 | 
				
			||||||
 | 
					        Request $request,
 | 
				
			||||||
        VacationRequest $vacationRequest,
 | 
					        VacationRequest $vacationRequest,
 | 
				
			||||||
        VacationRequestStateManager $stateManager,
 | 
					        VacationRequestStateManager $stateManager,
 | 
				
			||||||
    ): RedirectResponse {
 | 
					    ): RedirectResponse {
 | 
				
			||||||
        $stateManager->acceptAsAdministrative($vacationRequest);
 | 
					        $this->authorize("acceptAsAdminApprover", $vacationRequest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $stateManager->acceptAsAdministrative($vacationRequest, $request->user());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return redirect()->back()
 | 
					        return redirect()->back()
 | 
				
			||||||
            ->with("success", __("Vacation request has been accepted."));
 | 
					            ->with("success", __("Vacation request has been accepted."));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,10 @@ class HandleInertiaRequests extends Middleware
 | 
				
			|||||||
        return array_merge(parent::share($request), [
 | 
					        return array_merge(parent::share($request), [
 | 
				
			||||||
            "auth" => fn() => [
 | 
					            "auth" => fn() => [
 | 
				
			||||||
                "user" => $user ? new UserResource($user) : null,
 | 
					                "user" => $user ? new UserResource($user) : null,
 | 
				
			||||||
 | 
					                "can" => [
 | 
				
			||||||
 | 
					                    "manageVacationLimits" => $user ? $user->can("manageVacationLimits") : false,
 | 
				
			||||||
 | 
					                    "manageUsers" => $user ? $user->can("manageUsers") : false,
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "flash" => fn() => [
 | 
					            "flash" => fn() => [
 | 
				
			||||||
                "success" => $request->session()->get("success"),
 | 
					                "success" => $request->session()->get("success"),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,16 +27,29 @@ class VacationRequestRequest extends FormRequest
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function data(): array
 | 
					    public function data(): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $from = $this->get("from");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return [
 | 
					        return [
 | 
				
			||||||
            "user_id" => $this->get("user"),
 | 
					            "user_id" => $this->get("user"),
 | 
				
			||||||
            "type" => $this->get("type"),
 | 
					            "type" => $this->get("type"),
 | 
				
			||||||
            "from" => $from,
 | 
					            "from" => $this->get("from"),
 | 
				
			||||||
            "to" => $this->get("to"),
 | 
					            "to" => $this->get("to"),
 | 
				
			||||||
            "year_period_id" => YearPeriod::findByYear(Carbon::create($from)->year)->id,
 | 
					            "year_period_id" => $this->yearPeriod()->id,
 | 
				
			||||||
            "comment" => $this->get("comment"),
 | 
					            "comment" => $this->get("comment"),
 | 
				
			||||||
            "flow_skipped" => $this->boolean("flowSkipped"),
 | 
					            "flow_skipped" => $this->boolean("flowSkipped"),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function yearPeriod(): YearPeriod
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return YearPeriod::findByYear(Carbon::create($this->get("from"))->year);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function createsOnBehalfOfEmployee(): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->user()->id !== $this->get("user");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function wantsSkipFlow(): bool
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->boolean("flowSkipped");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,6 @@ class VacationRequestActivityResource extends JsonResource
 | 
				
			|||||||
            "time" => $this->created_at->format("H:i"),
 | 
					            "time" => $this->created_at->format("H:i"),
 | 
				
			||||||
            "user" => $this->user ? $this->user->fullName : __("System"),
 | 
					            "user" => $this->user ? $this->user->fullName : __("System"),
 | 
				
			||||||
            "state" => $this->to,
 | 
					            "state" => $this->to,
 | 
				
			||||||
            "text" => $this->to->label(),
 | 
					 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,8 +18,9 @@
 | 
				
			|||||||
        "laravel/telescope": "^4.6",
 | 
					        "laravel/telescope": "^4.6",
 | 
				
			||||||
        "laravel/tinker": "^2.5",
 | 
					        "laravel/tinker": "^2.5",
 | 
				
			||||||
        "lasserafn/php-initial-avatar-generator": "^4.2",
 | 
					        "lasserafn/php-initial-avatar-generator": "^4.2",
 | 
				
			||||||
        "maatwebsite/excel": "^3.1",
 | 
					        "spatie/laravel-google-calendar": "^3.5",
 | 
				
			||||||
        "spatie/laravel-google-calendar": "^3.5"
 | 
					        "spatie/laravel-model-states": "^2.1",
 | 
				
			||||||
 | 
					        "maatwebsite/excel": "^3.1"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "require-dev": {
 | 
					    "require-dev": {
 | 
				
			||||||
        "blumilksoftware/codestyle": "^0.10.0",
 | 
					        "blumilksoftware/codestyle": "^0.10.0",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										263
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										263
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
				
			|||||||
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
 | 
					        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
 | 
				
			||||||
        "This file is @generated automatically"
 | 
					        "This file is @generated automatically"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "content-hash": "1b7f51398015d1bd1a03e5910dc2d72c",
 | 
					    "content-hash": "d3f019c6e743a3249af78baefe7acb01",
 | 
				
			||||||
    "packages": [
 | 
					    "packages": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "asm89/stack-cors",
 | 
					            "name": "asm89/stack-cors",
 | 
				
			||||||
@@ -760,6 +760,59 @@
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
            "time": "2021-12-25T01:21:49+00:00"
 | 
					            "time": "2021-12-25T01:21:49+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "name": "facade/ignition-contracts",
 | 
				
			||||||
 | 
					            "version": "1.0.2",
 | 
				
			||||||
 | 
					            "source": {
 | 
				
			||||||
 | 
					                "type": "git",
 | 
				
			||||||
 | 
					                "url": "https://github.com/facade/ignition-contracts.git",
 | 
				
			||||||
 | 
					                "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "dist": {
 | 
				
			||||||
 | 
					                "type": "zip",
 | 
				
			||||||
 | 
					                "url": "https://api.github.com/repos/facade/ignition-contracts/zipball/3c921a1cdba35b68a7f0ccffc6dffc1995b18267",
 | 
				
			||||||
 | 
					                "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267",
 | 
				
			||||||
 | 
					                "shasum": ""
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require": {
 | 
				
			||||||
 | 
					                "php": "^7.3|^8.0"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require-dev": {
 | 
				
			||||||
 | 
					                "friendsofphp/php-cs-fixer": "^v2.15.8",
 | 
				
			||||||
 | 
					                "phpunit/phpunit": "^9.3.11",
 | 
				
			||||||
 | 
					                "vimeo/psalm": "^3.17.1"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "type": "library",
 | 
				
			||||||
 | 
					            "autoload": {
 | 
				
			||||||
 | 
					                "psr-4": {
 | 
				
			||||||
 | 
					                    "Facade\\IgnitionContracts\\": "src"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "notification-url": "https://packagist.org/downloads/",
 | 
				
			||||||
 | 
					            "license": [
 | 
				
			||||||
 | 
					                "MIT"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "authors": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "name": "Freek Van der Herten",
 | 
				
			||||||
 | 
					                    "email": "freek@spatie.be",
 | 
				
			||||||
 | 
					                    "homepage": "https://flareapp.io",
 | 
				
			||||||
 | 
					                    "role": "Developer"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "description": "Solution contracts for Ignition",
 | 
				
			||||||
 | 
					            "homepage": "https://github.com/facade/ignition-contracts",
 | 
				
			||||||
 | 
					            "keywords": [
 | 
				
			||||||
 | 
					                "contracts",
 | 
				
			||||||
 | 
					                "flare",
 | 
				
			||||||
 | 
					                "ignition"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "support": {
 | 
				
			||||||
 | 
					                "issues": "https://github.com/facade/ignition-contracts/issues",
 | 
				
			||||||
 | 
					                "source": "https://github.com/facade/ignition-contracts/tree/1.0.2"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "time": "2020-10-16T08:27:54+00:00"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "firebase/php-jwt",
 | 
					            "name": "firebase/php-jwt",
 | 
				
			||||||
            "version": "v5.5.1",
 | 
					            "version": "v5.5.1",
 | 
				
			||||||
@@ -4924,6 +4977,139 @@
 | 
				
			|||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "time": "2022-01-13T09:43:27+00:00"
 | 
					            "time": "2022-01-13T09:43:27+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "name": "spatie/laravel-model-states",
 | 
				
			||||||
 | 
					            "version": "2.1.4",
 | 
				
			||||||
 | 
					            "source": {
 | 
				
			||||||
 | 
					                "type": "git",
 | 
				
			||||||
 | 
					                "url": "https://github.com/spatie/laravel-model-states.git",
 | 
				
			||||||
 | 
					                "reference": "c9c4865abd2b5ec534214aede784631366bed7d4"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "dist": {
 | 
				
			||||||
 | 
					                "type": "zip",
 | 
				
			||||||
 | 
					                "url": "https://api.github.com/repos/spatie/laravel-model-states/zipball/c9c4865abd2b5ec534214aede784631366bed7d4",
 | 
				
			||||||
 | 
					                "reference": "c9c4865abd2b5ec534214aede784631366bed7d4",
 | 
				
			||||||
 | 
					                "shasum": ""
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require": {
 | 
				
			||||||
 | 
					                "ext-json": "*",
 | 
				
			||||||
 | 
					                "facade/ignition-contracts": "^1.0",
 | 
				
			||||||
 | 
					                "illuminate/contracts": "^8.73 | ^9.0",
 | 
				
			||||||
 | 
					                "illuminate/database": "^8.73 | ^9.0",
 | 
				
			||||||
 | 
					                "illuminate/support": "^8.73 | ^9.0",
 | 
				
			||||||
 | 
					                "php": "^7.4|^8.0",
 | 
				
			||||||
 | 
					                "spatie/laravel-package-tools": "^1.9"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require-dev": {
 | 
				
			||||||
 | 
					                "orchestra/testbench": "^6.23 | ^7.0",
 | 
				
			||||||
 | 
					                "phpunit/phpunit": "^9.4",
 | 
				
			||||||
 | 
					                "symfony/var-dumper": "^5.3 | ^6.0"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "type": "library",
 | 
				
			||||||
 | 
					            "extra": {
 | 
				
			||||||
 | 
					                "laravel": {
 | 
				
			||||||
 | 
					                    "providers": [
 | 
				
			||||||
 | 
					                        "Spatie\\ModelStates\\ModelStatesServiceProvider"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "autoload": {
 | 
				
			||||||
 | 
					                "psr-4": {
 | 
				
			||||||
 | 
					                    "Spatie\\ModelStates\\": "src"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "notification-url": "https://packagist.org/downloads/",
 | 
				
			||||||
 | 
					            "license": [
 | 
				
			||||||
 | 
					                "MIT"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "authors": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "name": "Brent Roose",
 | 
				
			||||||
 | 
					                    "email": "brent@spatie.be",
 | 
				
			||||||
 | 
					                    "homepage": "https://spatie.be",
 | 
				
			||||||
 | 
					                    "role": "Developer"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "description": "State support for Eloquent models",
 | 
				
			||||||
 | 
					            "homepage": "https://github.com/spatie/laravel-model-states",
 | 
				
			||||||
 | 
					            "keywords": [
 | 
				
			||||||
 | 
					                "spatie",
 | 
				
			||||||
 | 
					                "state"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "support": {
 | 
				
			||||||
 | 
					                "source": "https://github.com/spatie/laravel-model-states/tree/2.1.4"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "funding": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "url": "https://spatie.be/open-source/support-us",
 | 
				
			||||||
 | 
					                    "type": "custom"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "url": "https://github.com/spatie",
 | 
				
			||||||
 | 
					                    "type": "github"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "time": "2022-01-19T19:57:35+00:00"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "name": "spatie/laravel-package-tools",
 | 
				
			||||||
 | 
					            "version": "1.11.2",
 | 
				
			||||||
 | 
					            "source": {
 | 
				
			||||||
 | 
					                "type": "git",
 | 
				
			||||||
 | 
					                "url": "https://github.com/spatie/laravel-package-tools.git",
 | 
				
			||||||
 | 
					                "reference": "16a8de828e7f1f32d580c667e1de5bf2943abd6b"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "dist": {
 | 
				
			||||||
 | 
					                "type": "zip",
 | 
				
			||||||
 | 
					                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/16a8de828e7f1f32d580c667e1de5bf2943abd6b",
 | 
				
			||||||
 | 
					                "reference": "16a8de828e7f1f32d580c667e1de5bf2943abd6b",
 | 
				
			||||||
 | 
					                "shasum": ""
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require": {
 | 
				
			||||||
 | 
					                "illuminate/contracts": "^7.0|^8.0|^9.0",
 | 
				
			||||||
 | 
					                "php": "^7.4|^8.0"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "require-dev": {
 | 
				
			||||||
 | 
					                "mockery/mockery": "^1.4",
 | 
				
			||||||
 | 
					                "orchestra/testbench": "^5.0|^6.23|^7.0",
 | 
				
			||||||
 | 
					                "phpunit/phpunit": "^9.4",
 | 
				
			||||||
 | 
					                "spatie/test-time": "^1.2"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "type": "library",
 | 
				
			||||||
 | 
					            "autoload": {
 | 
				
			||||||
 | 
					                "psr-4": {
 | 
				
			||||||
 | 
					                    "Spatie\\LaravelPackageTools\\": "src"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "notification-url": "https://packagist.org/downloads/",
 | 
				
			||||||
 | 
					            "license": [
 | 
				
			||||||
 | 
					                "MIT"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "authors": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "name": "Freek Van der Herten",
 | 
				
			||||||
 | 
					                    "email": "freek@spatie.be",
 | 
				
			||||||
 | 
					                    "role": "Developer"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "description": "Tools for creating Laravel packages",
 | 
				
			||||||
 | 
					            "homepage": "https://github.com/spatie/laravel-package-tools",
 | 
				
			||||||
 | 
					            "keywords": [
 | 
				
			||||||
 | 
					                "laravel-package-tools",
 | 
				
			||||||
 | 
					                "spatie"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "support": {
 | 
				
			||||||
 | 
					                "issues": "https://github.com/spatie/laravel-package-tools/issues",
 | 
				
			||||||
 | 
					                "source": "https://github.com/spatie/laravel-package-tools/tree/1.11.2"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "funding": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "url": "https://github.com/spatie",
 | 
				
			||||||
 | 
					                    "type": "github"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "time": "2022-02-22T08:55:13+00:00"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "symfony/console",
 | 
					            "name": "symfony/console",
 | 
				
			||||||
            "version": "v6.0.5",
 | 
					            "version": "v6.0.5",
 | 
				
			||||||
@@ -7687,59 +7873,6 @@
 | 
				
			|||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "time": "2020-11-10T18:47:58+00:00"
 | 
					            "time": "2020-11-10T18:47:58+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            "name": "facade/ignition-contracts",
 | 
					 | 
				
			||||||
            "version": "1.0.2",
 | 
					 | 
				
			||||||
            "source": {
 | 
					 | 
				
			||||||
                "type": "git",
 | 
					 | 
				
			||||||
                "url": "https://github.com/facade/ignition-contracts.git",
 | 
					 | 
				
			||||||
                "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267"
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            "dist": {
 | 
					 | 
				
			||||||
                "type": "zip",
 | 
					 | 
				
			||||||
                "url": "https://api.github.com/repos/facade/ignition-contracts/zipball/3c921a1cdba35b68a7f0ccffc6dffc1995b18267",
 | 
					 | 
				
			||||||
                "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267",
 | 
					 | 
				
			||||||
                "shasum": ""
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            "require": {
 | 
					 | 
				
			||||||
                "php": "^7.3|^8.0"
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            "require-dev": {
 | 
					 | 
				
			||||||
                "friendsofphp/php-cs-fixer": "^v2.15.8",
 | 
					 | 
				
			||||||
                "phpunit/phpunit": "^9.3.11",
 | 
					 | 
				
			||||||
                "vimeo/psalm": "^3.17.1"
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            "type": "library",
 | 
					 | 
				
			||||||
            "autoload": {
 | 
					 | 
				
			||||||
                "psr-4": {
 | 
					 | 
				
			||||||
                    "Facade\\IgnitionContracts\\": "src"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            "notification-url": "https://packagist.org/downloads/",
 | 
					 | 
				
			||||||
            "license": [
 | 
					 | 
				
			||||||
                "MIT"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "authors": [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    "name": "Freek Van der Herten",
 | 
					 | 
				
			||||||
                    "email": "freek@spatie.be",
 | 
					 | 
				
			||||||
                    "homepage": "https://flareapp.io",
 | 
					 | 
				
			||||||
                    "role": "Developer"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "description": "Solution contracts for Ignition",
 | 
					 | 
				
			||||||
            "homepage": "https://github.com/facade/ignition-contracts",
 | 
					 | 
				
			||||||
            "keywords": [
 | 
					 | 
				
			||||||
                "contracts",
 | 
					 | 
				
			||||||
                "flare",
 | 
					 | 
				
			||||||
                "ignition"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "support": {
 | 
					 | 
				
			||||||
                "issues": "https://github.com/facade/ignition-contracts/issues",
 | 
					 | 
				
			||||||
                "source": "https://github.com/facade/ignition-contracts/tree/1.0.2"
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            "time": "2020-10-16T08:27:54+00:00"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "fakerphp/faker",
 | 
					            "name": "fakerphp/faker",
 | 
				
			||||||
            "version": "v1.19.0",
 | 
					            "version": "v1.19.0",
 | 
				
			||||||
@@ -10259,16 +10392,16 @@
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "spatie/flare-client-php",
 | 
					            "name": "spatie/flare-client-php",
 | 
				
			||||||
            "version": "1.0.4",
 | 
					            "version": "1.0.5",
 | 
				
			||||||
            "source": {
 | 
					            "source": {
 | 
				
			||||||
                "type": "git",
 | 
					                "type": "git",
 | 
				
			||||||
                "url": "https://github.com/spatie/flare-client-php.git",
 | 
					                "url": "https://github.com/spatie/flare-client-php.git",
 | 
				
			||||||
                "reference": "edf253c68fba62cdb29ad6b48e211e29691dcee8"
 | 
					                "reference": "8ada1e5f4d7a2869f491c5e75d1f689b69db423e"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "dist": {
 | 
					            "dist": {
 | 
				
			||||||
                "type": "zip",
 | 
					                "type": "zip",
 | 
				
			||||||
                "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/edf253c68fba62cdb29ad6b48e211e29691dcee8",
 | 
					                "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/8ada1e5f4d7a2869f491c5e75d1f689b69db423e",
 | 
				
			||||||
                "reference": "edf253c68fba62cdb29ad6b48e211e29691dcee8",
 | 
					                "reference": "8ada1e5f4d7a2869f491c5e75d1f689b69db423e",
 | 
				
			||||||
                "shasum": ""
 | 
					                "shasum": ""
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "require": {
 | 
					            "require": {
 | 
				
			||||||
@@ -10311,7 +10444,7 @@
 | 
				
			|||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "support": {
 | 
					            "support": {
 | 
				
			||||||
                "issues": "https://github.com/spatie/flare-client-php/issues",
 | 
					                "issues": "https://github.com/spatie/flare-client-php/issues",
 | 
				
			||||||
                "source": "https://github.com/spatie/flare-client-php/tree/1.0.4"
 | 
					                "source": "https://github.com/spatie/flare-client-php/tree/1.0.5"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "funding": [
 | 
					            "funding": [
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -10319,20 +10452,20 @@
 | 
				
			|||||||
                    "type": "github"
 | 
					                    "type": "github"
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "time": "2022-02-28T15:04:23+00:00"
 | 
					            "time": "2022-03-01T10:52:59+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "spatie/ignition",
 | 
					            "name": "spatie/ignition",
 | 
				
			||||||
            "version": "1.0.5",
 | 
					            "version": "1.1.0",
 | 
				
			||||||
            "source": {
 | 
					            "source": {
 | 
				
			||||||
                "type": "git",
 | 
					                "type": "git",
 | 
				
			||||||
                "url": "https://github.com/spatie/ignition.git",
 | 
					                "url": "https://github.com/spatie/ignition.git",
 | 
				
			||||||
                "reference": "6b7bb804f4834b080f5ac941f6ac6800a485011e"
 | 
					                "reference": "8ecde033600064e3ffdbf804deec0dcb05004387"
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "dist": {
 | 
					            "dist": {
 | 
				
			||||||
                "type": "zip",
 | 
					                "type": "zip",
 | 
				
			||||||
                "url": "https://api.github.com/repos/spatie/ignition/zipball/6b7bb804f4834b080f5ac941f6ac6800a485011e",
 | 
					                "url": "https://api.github.com/repos/spatie/ignition/zipball/8ecde033600064e3ffdbf804deec0dcb05004387",
 | 
				
			||||||
                "reference": "6b7bb804f4834b080f5ac941f6ac6800a485011e",
 | 
					                "reference": "8ecde033600064e3ffdbf804deec0dcb05004387",
 | 
				
			||||||
                "shasum": ""
 | 
					                "shasum": ""
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            "require": {
 | 
					            "require": {
 | 
				
			||||||
@@ -10390,7 +10523,7 @@
 | 
				
			|||||||
                    "type": "github"
 | 
					                    "type": "github"
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            "time": "2022-02-17T21:40:47+00:00"
 | 
					            "time": "2022-03-01T17:01:33+00:00"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            "name": "spatie/laravel-ignition",
 | 
					            "name": "spatie/laravel-ignition",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								config/model-states.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								config/model-states.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return [
 | 
				
			||||||
 | 
					    "default_transition" => Spatie\ModelStates\DefaultTransition::class,
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
@@ -28,4 +28,25 @@ class UserFactory extends Factory
 | 
				
			|||||||
            "remember_token" => Str::random(10),
 | 
					            "remember_token" => Str::random(10),
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function admin(): static
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->state([
 | 
				
			||||||
 | 
					            "role" => Role::Administrator,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function technicalApprover(): static
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->state([
 | 
				
			||||||
 | 
					            "role" => Role::TechnicalApprover,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function administrativeApprover(): static
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->state([
 | 
				
			||||||
 | 
					            "role" => Role::AdministrativeApprover,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,8 +6,8 @@ namespace Database\Factories;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use Carbon\CarbonImmutable;
 | 
					use Carbon\CarbonImmutable;
 | 
				
			||||||
use Illuminate\Database\Eloquent\Factories\Factory;
 | 
					use Illuminate\Database\Eloquent\Factories\Factory;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					 | 
				
			||||||
use Toby\Domain\Enums\VacationType;
 | 
					use Toby\Domain\Enums\VacationType;
 | 
				
			||||||
 | 
					use Toby\Domain\VacationRequestStatesRetriever;
 | 
				
			||||||
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;
 | 
				
			||||||
@@ -28,7 +28,7 @@ class VacationRequestFactory extends Factory
 | 
				
			|||||||
            "year_period_id" => YearPeriod::factory(),
 | 
					            "year_period_id" => YearPeriod::factory(),
 | 
				
			||||||
            "name" => fn(array $attributes): string => $this->generateName($attributes),
 | 
					            "name" => fn(array $attributes): string => $this->generateName($attributes),
 | 
				
			||||||
            "type" => $this->faker->randomElement(VacationType::cases()),
 | 
					            "type" => $this->faker->randomElement(VacationType::cases()),
 | 
				
			||||||
            "state" => $this->faker->randomElement(VacationRequestState::cases()),
 | 
					            "state" => $this->faker->randomElement(VacationRequestStatesRetriever::all()),
 | 
				
			||||||
            "from" => $from,
 | 
					            "from" => $from,
 | 
				
			||||||
            "to" => $from->addDays($days),
 | 
					            "to" => $from->addDays($days),
 | 
				
			||||||
            "comment" => $this->faker->boolean ? $this->faker->paragraph() : null,
 | 
					            "comment" => $this->faker->boolean ? $this->faker->paragraph() : null,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1486
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1486
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -7,7 +7,7 @@
 | 
				
			|||||||
          Kalendarz urlopów
 | 
					          Kalendarz urlopów
 | 
				
			||||||
        </h2>
 | 
					        </h2>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div>
 | 
					      <div v-if="can.generateTimesheet">
 | 
				
			||||||
        <a
 | 
					        <a
 | 
				
			||||||
          :href="`/timesheet/${selectedMonth.value}`"
 | 
					          :href="`/timesheet/${selectedMonth.value}`"
 | 
				
			||||||
          class="inline-flex items-center px-4 py-3 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
 | 
					          class="inline-flex items-center px-4 py-3 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
 | 
				
			||||||
@@ -164,6 +164,10 @@ export default {
 | 
				
			|||||||
      type: Object,
 | 
					      type: Object,
 | 
				
			||||||
      default: () => null,
 | 
					      default: () => null,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    can: {
 | 
				
			||||||
 | 
					      type: Object,
 | 
				
			||||||
 | 
					      default: () => null,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  setup(props) {
 | 
					  setup(props) {
 | 
				
			||||||
    const {getMonths, findMonth} = useMonthInfo()
 | 
					    const {getMonths, findMonth} = useMonthInfo()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@
 | 
				
			|||||||
          Lista dni wolnych od pracy w danym roku
 | 
					          Lista dni wolnych od pracy w danym roku
 | 
				
			||||||
        </p>
 | 
					        </p>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div>
 | 
					      <div v-if="can.manageHolidays">
 | 
				
			||||||
        <InertiaLink
 | 
					        <InertiaLink
 | 
				
			||||||
          href="holidays/create"
 | 
					          href="holidays/create"
 | 
				
			||||||
          class="inline-flex items-center px-4 py-3 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
 | 
					          class="inline-flex items-center px-4 py-3 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
 | 
				
			||||||
@@ -19,9 +19,10 @@
 | 
				
			|||||||
        </InertiaLink>
 | 
					        </InertiaLink>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="border-t border-gray-200">
 | 
				
			||||||
      <div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
 | 
					      <div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
 | 
				
			||||||
        <table class="min-w-full divide-y divide-gray-200">
 | 
					        <table class="min-w-full divide-y divide-gray-200">
 | 
				
			||||||
        <thead class="bg-gray-50">
 | 
					          <thead class="bg-gray-100">
 | 
				
			||||||
            <tr>
 | 
					            <tr>
 | 
				
			||||||
              <th
 | 
					              <th
 | 
				
			||||||
                scope="col"
 | 
					                scope="col"
 | 
				
			||||||
@@ -64,6 +65,7 @@
 | 
				
			|||||||
              </td>
 | 
					              </td>
 | 
				
			||||||
              <td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500 text-right">
 | 
					              <td class="px-4 py-4 whitespace-nowrap text-sm text-gray-500 text-right">
 | 
				
			||||||
                <Menu
 | 
					                <Menu
 | 
				
			||||||
 | 
					                  v-if="can.manageHolidays"
 | 
				
			||||||
                  as="div"
 | 
					                  as="div"
 | 
				
			||||||
                  class="relative inline-block text-left"
 | 
					                  class="relative inline-block text-left"
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
@@ -135,6 +137,7 @@
 | 
				
			|||||||
        </table>
 | 
					        </table>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
@@ -157,6 +160,10 @@ export default {
 | 
				
			|||||||
      type: Object,
 | 
					      type: Object,
 | 
				
			||||||
      default: () => null,
 | 
					      default: () => null,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    can: {
 | 
				
			||||||
 | 
					      type: Object,
 | 
				
			||||||
 | 
					      default: () => null,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  setup() {
 | 
					  setup() {
 | 
				
			||||||
    return {}
 | 
					    return {}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +1,18 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <InertiaHead title="Złóż wniosek urlopowy" />
 | 
					  <InertiaHead title="Złóż wniosek urlopowy" />
 | 
				
			||||||
  <div class="grid grid-cols-1 gap-4 items-start lg:grid-cols-3 lg:gap-8">
 | 
					  <div class="grid grid-cols-1 gap-4 items-start lg:grid-cols-3 lg:gap-8">
 | 
				
			||||||
    <div class="grid grid-cols-1 lg:col-span-2 bg-white shadow-md">
 | 
					    <div class="lg:col-span-2 h-full bg-white shadow-md flex flex-col">
 | 
				
			||||||
      <div class="p-4 sm:px-6">
 | 
					      <div class="p-4 sm:px-6">
 | 
				
			||||||
        <h2 class="text-lg leading-6 font-medium text-gray-900">
 | 
					        <h2 class="text-lg leading-6 font-medium text-gray-900">
 | 
				
			||||||
          Złóż wniosek urlopowy
 | 
					          Złóż wniosek urlopowy
 | 
				
			||||||
        </h2>
 | 
					        </h2>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <form
 | 
					      <form
 | 
				
			||||||
        class="border-t border-gray-200 px-6"
 | 
					        class="border-t border-gray-200 h-full px-6"
 | 
				
			||||||
        @submit.prevent="createForm"
 | 
					        @submit.prevent="createForm"
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
 | 
					        <div class="h-full flex flex-col justify-between">
 | 
				
			||||||
 | 
					          <div>
 | 
				
			||||||
            <div
 | 
					            <div
 | 
				
			||||||
              v-if="form.errors.vacationRequest"
 | 
					              v-if="form.errors.vacationRequest"
 | 
				
			||||||
              class="rounded-md bg-red-50 p-4 mt-2"
 | 
					              class="rounded-md bg-red-50 p-4 mt-2"
 | 
				
			||||||
@@ -30,6 +32,7 @@
 | 
				
			|||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <Listbox
 | 
					            <Listbox
 | 
				
			||||||
 | 
					              v-if="can.createOnBehalfOfEmployee"
 | 
				
			||||||
              v-model="form.user"
 | 
					              v-model="form.user"
 | 
				
			||||||
              as="div"
 | 
					              as="div"
 | 
				
			||||||
              class="sm:grid sm:grid-cols-3 py-4 items-center"
 | 
					              class="sm:grid sm:grid-cols-3 py-4 items-center"
 | 
				
			||||||
@@ -40,7 +43,7 @@
 | 
				
			|||||||
              <div class="mt-1 relative sm:mt-0 sm:col-span-2">
 | 
					              <div class="mt-1 relative sm:mt-0 sm:col-span-2">
 | 
				
			||||||
                <ListboxButton
 | 
					                <ListboxButton
 | 
				
			||||||
                  class="bg-white relative w-full max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:ring-1"
 | 
					                  class="bg-white relative w-full max-w-lg border rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default sm:text-sm focus:ring-1"
 | 
				
			||||||
              :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.user, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.user }"
 | 
					                  :class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.type, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.type }"
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                  <span class="flex items-center">
 | 
					                  <span class="flex items-center">
 | 
				
			||||||
                    <img
 | 
					                    <img
 | 
				
			||||||
@@ -69,9 +72,7 @@
 | 
				
			|||||||
                      as="template"
 | 
					                      as="template"
 | 
				
			||||||
                      :value="user"
 | 
					                      :value="user"
 | 
				
			||||||
                    >
 | 
					                    >
 | 
				
			||||||
                  <li
 | 
					                      <li :class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']">
 | 
				
			||||||
                    :class="[active ? 'text-white bg-blumilk-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9']"
 | 
					 | 
				
			||||||
                  >
 | 
					 | 
				
			||||||
                        <div class="flex items-center">
 | 
					                        <div class="flex items-center">
 | 
				
			||||||
                          <img
 | 
					                          <img
 | 
				
			||||||
                            :src="user.avatar"
 | 
					                            :src="user.avatar"
 | 
				
			||||||
@@ -234,7 +235,10 @@
 | 
				
			|||||||
                />
 | 
					                />
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        <div class="sm:grid sm:grid-cols-3 py-4 items-center">
 | 
					            <div
 | 
				
			||||||
 | 
					              v-if="can.skipFlow"
 | 
				
			||||||
 | 
					              class="sm:grid sm:grid-cols-3 py-4 items-center"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
              <label
 | 
					              <label
 | 
				
			||||||
                for="flowSkipped"
 | 
					                for="flowSkipped"
 | 
				
			||||||
                class="block text-sm font-medium text-gray-700"
 | 
					                class="block text-sm font-medium text-gray-700"
 | 
				
			||||||
@@ -253,6 +257,7 @@
 | 
				
			|||||||
                </Switch>
 | 
					                </Switch>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
          <div class="flex justify-end py-3">
 | 
					          <div class="flex justify-end py-3">
 | 
				
			||||||
            <div class="space-x-3">
 | 
					            <div class="space-x-3">
 | 
				
			||||||
              <InertiaLink
 | 
					              <InertiaLink
 | 
				
			||||||
@@ -270,10 +275,10 @@
 | 
				
			|||||||
              </button>
 | 
					              </button>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
      </form>
 | 
					      </form>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="grid grid-cols-1 bg-white shadow-md h-full">
 | 
					    <div class="bg-white shadow-md h-full">
 | 
				
			||||||
      <div>
 | 
					 | 
				
			||||||
      <div class="p-4 sm:px-6">
 | 
					      <div class="p-4 sm:px-6">
 | 
				
			||||||
        <h2 class="text-lg leading-6 font-medium text-gray-900">
 | 
					        <h2 class="text-lg leading-6 font-medium text-gray-900">
 | 
				
			||||||
          Urlop wypoczynkowy
 | 
					          Urlop wypoczynkowy
 | 
				
			||||||
@@ -284,7 +289,6 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
@@ -329,10 +333,16 @@ export default {
 | 
				
			|||||||
      type: Object,
 | 
					      type: Object,
 | 
				
			||||||
      default: () => null,
 | 
					      default: () => null,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    can: {
 | 
				
			||||||
 | 
					      type: Object,
 | 
				
			||||||
 | 
					      default: () => null,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  setup(props) {
 | 
					  setup(props) {
 | 
				
			||||||
    const form = useForm({
 | 
					    const form = useForm({
 | 
				
			||||||
      user: props.users.data.find(user => user.id === props.auth.user.id),
 | 
					      user: props.can.createOnBehalfOfEmployee
 | 
				
			||||||
 | 
					        ? props.users.data.find(user => user.id === props.auth.user.id)
 | 
				
			||||||
 | 
					        : props.auth.user,
 | 
				
			||||||
      from: null,
 | 
					      from: null,
 | 
				
			||||||
      to: null,
 | 
					      to: null,
 | 
				
			||||||
      type: props.vacationTypes[0],
 | 
					      type: props.vacationTypes[0],
 | 
				
			||||||
@@ -403,12 +413,6 @@ export default {
 | 
				
			|||||||
          .then(res => this.estimatedDays = res.data)
 | 
					          .then(res => this.estimatedDays = res.data)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    updateVacationStats(user) {
 | 
					 | 
				
			||||||
      console.log(user)
 | 
					 | 
				
			||||||
      axios.post('/api/get-vacations-stats')
 | 
					 | 
				
			||||||
        .then(res => this.stats = res.data)
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -110,7 +110,10 @@
 | 
				
			|||||||
          </dl>
 | 
					          </dl>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="bg-white shadow">
 | 
					      <div
 | 
				
			||||||
 | 
					        v-if="can.acceptAsTechnical"
 | 
				
			||||||
 | 
					        class="bg-white shadow"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
        <div class="px-4 py-5 sm:p-6">
 | 
					        <div class="px-4 py-5 sm:p-6">
 | 
				
			||||||
          <h3 class="text-lg leading-6 font-medium text-gray-900">
 | 
					          <h3 class="text-lg leading-6 font-medium text-gray-900">
 | 
				
			||||||
            Zaakceptuj wniosek jako osoba techniczna
 | 
					            Zaakceptuj wniosek jako osoba techniczna
 | 
				
			||||||
@@ -134,7 +137,10 @@
 | 
				
			|||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="bg-white shadow">
 | 
					      <div
 | 
				
			||||||
 | 
					        v-if="can.acceptAsAdministrative"
 | 
				
			||||||
 | 
					        class="bg-white shadow"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
        <div class="px-4 py-5 sm:p-6">
 | 
					        <div class="px-4 py-5 sm:p-6">
 | 
				
			||||||
          <h3 class="text-lg leading-6 font-medium text-gray-900">
 | 
					          <h3 class="text-lg leading-6 font-medium text-gray-900">
 | 
				
			||||||
            Zaakceptuj wniosek jako osoba administracyjna
 | 
					            Zaakceptuj wniosek jako osoba administracyjna
 | 
				
			||||||
@@ -157,7 +163,10 @@
 | 
				
			|||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="bg-white shadow">
 | 
					      <div
 | 
				
			||||||
 | 
					        v-if="can.reject"
 | 
				
			||||||
 | 
					        class="bg-white shadow"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
        <div class="px-4 py-5 sm:p-6">
 | 
					        <div class="px-4 py-5 sm:p-6">
 | 
				
			||||||
          <h3 class="text-lg leading-6 font-medium text-gray-900">
 | 
					          <h3 class="text-lg leading-6 font-medium text-gray-900">
 | 
				
			||||||
            Odrzuć wniosek
 | 
					            Odrzuć wniosek
 | 
				
			||||||
@@ -180,7 +189,10 @@
 | 
				
			|||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="bg-white shadow border border-red-500">
 | 
					      <div
 | 
				
			||||||
 | 
					        v-if="can.cancel"
 | 
				
			||||||
 | 
					        class="bg-white shadow border border-red-500"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
        <div class="px-4 py-5 sm:p-6">
 | 
					        <div class="px-4 py-5 sm:p-6">
 | 
				
			||||||
          <h3 class="text-lg leading-6 font-medium text-gray-900">
 | 
					          <h3 class="text-lg leading-6 font-medium text-gray-900">
 | 
				
			||||||
            Anuluj wniosek
 | 
					            Anuluj wniosek
 | 
				
			||||||
@@ -246,6 +258,10 @@ export default {
 | 
				
			|||||||
      type: Object,
 | 
					      type: Object,
 | 
				
			||||||
      default: () => null,
 | 
					      default: () => null,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    can: {
 | 
				
			||||||
 | 
					      type: Object,
 | 
				
			||||||
 | 
					      default: () => null,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    activities: {
 | 
					    activities: {
 | 
				
			||||||
      type: Object,
 | 
					      type: Object,
 | 
				
			||||||
      default: () => null,
 | 
					      default: () => null,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -213,12 +213,12 @@
 | 
				
			|||||||
              >
 | 
					              >
 | 
				
			||||||
                <img
 | 
					                <img
 | 
				
			||||||
                  class="h-8 w-8 rounded-full"
 | 
					                  class="h-8 w-8 rounded-full"
 | 
				
			||||||
                  :src="user.avatar"
 | 
					                  :src="auth.user.avatar"
 | 
				
			||||||
                  alt="Avatar"
 | 
					                  alt="Avatar"
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
                <span class="hidden ml-3 text-gray-700 text-sm font-medium lg:block">
 | 
					                <span class="hidden ml-3 text-gray-700 text-sm font-medium lg:block">
 | 
				
			||||||
                  <span class="sr-only">Open user menu for </span>
 | 
					                  <span class="sr-only">Open user menu for </span>
 | 
				
			||||||
                  {{ user.name }}
 | 
					                  {{ auth.user.name }}
 | 
				
			||||||
                </span>
 | 
					                </span>
 | 
				
			||||||
                <ChevronDownIcon
 | 
					                <ChevronDownIcon
 | 
				
			||||||
                  class="hidden flex-shrink-0 ml-1 h-5 w-5 text-gray-400 lg:block"
 | 
					                  class="hidden flex-shrink-0 ml-1 h-5 w-5 text-gray-400 lg:block"
 | 
				
			||||||
@@ -324,23 +324,24 @@ export default {
 | 
				
			|||||||
  setup() {
 | 
					  setup() {
 | 
				
			||||||
    const sidebarOpen = ref(false)
 | 
					    const sidebarOpen = ref(false)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const user = computed(() => usePage().props.value.auth.user)
 | 
					    const auth = computed(() => usePage().props.value.auth)
 | 
				
			||||||
    const years = computed(() => usePage().props.value.years)
 | 
					    const years = computed(() => usePage().props.value.years)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const navigation = [
 | 
					    const navigation = computed(() =>
 | 
				
			||||||
      {name: 'Wnioski urlopowe', href: '/vacation-requests', icon: CollectionIcon},
 | 
					      [
 | 
				
			||||||
      {name: 'Kalendarz urlopów', href: '/vacation-calendar', icon: CalendarIcon},
 | 
					        {name: 'Wnioski urlopowe', href: '/vacation-requests', icon: CollectionIcon, can: true},
 | 
				
			||||||
      {name: 'Dni wolne', href: '/holidays', icon: StarIcon},
 | 
					        {name: 'Kalendarz urlopów', href: '/vacation-calendar', icon: CalendarIcon, can: true},
 | 
				
			||||||
      {name: 'Limity urlopów', href: '/vacation-limits', icon: SunIcon},
 | 
					        {name: 'Dni wolne', href: '/holidays', icon: StarIcon, can: true},
 | 
				
			||||||
      {name: 'Użytkownicy', href: '/users', icon: UserGroupIcon},
 | 
					        {name: 'Limity urlopów', href: '/vacation-limits', icon: SunIcon, can: auth.value.can.manageVacationLimits},
 | 
				
			||||||
    ]
 | 
					        {name: 'Użytkownicy', href: '/users', icon: UserGroupIcon, can: auth.value.can.manageUsers},
 | 
				
			||||||
 | 
					      ].filter(item => item.can))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const userNavigation = [
 | 
					    const userNavigation = [
 | 
				
			||||||
      {name: 'Wyloguj się', href: '/logout', method: 'post', as: 'button'},
 | 
					      {name: 'Wyloguj się', href: '/logout', method: 'post', as: 'button'},
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      user,
 | 
					      auth,
 | 
				
			||||||
      years,
 | 
					      years,
 | 
				
			||||||
      navigation,
 | 
					      navigation,
 | 
				
			||||||
      userNavigation,
 | 
					      userNavigation,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <v-chart
 | 
					  <v-chart
 | 
				
			||||||
    style="height: 600px;"
 | 
					    style="height: 600px;"
 | 
				
			||||||
 | 
					    :autoresize="true"
 | 
				
			||||||
    :option="option"
 | 
					    :option="option"
 | 
				
			||||||
  />
 | 
					  />
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
@@ -60,10 +61,20 @@ export default {
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
          name: 'Urlop wypoczynkowy',
 | 
					          name: 'Urlop wypoczynkowy',
 | 
				
			||||||
          type: 'pie',
 | 
					          type: 'pie',
 | 
				
			||||||
 | 
					          itemStyle: {
 | 
				
			||||||
 | 
					            borderRadius: 10,
 | 
				
			||||||
 | 
					            borderColor: '#fff',
 | 
				
			||||||
 | 
					            borderWidth: 2,
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
          label: {
 | 
					          label: {
 | 
				
			||||||
            show: true,
 | 
					            show: true,
 | 
				
			||||||
            textStyle: {
 | 
					            position: 'inner',
 | 
				
			||||||
 | 
					            formatter: param => param.value !== 0 ? param.value : '' ,
 | 
				
			||||||
 | 
					            fontWeight: 'bold',
 | 
				
			||||||
            fontSize: 16,
 | 
					            fontSize: 16,
 | 
				
			||||||
 | 
					            color: '#FFFFFF',
 | 
				
			||||||
 | 
					            labelLine: {
 | 
				
			||||||
 | 
					              show: false,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          data: [
 | 
					          data: [
 | 
				
			||||||
@@ -72,23 +83,6 @@ export default {
 | 
				
			|||||||
            { value: props.stats.remaining, name: 'Pozostałe' },
 | 
					            { value: props.stats.remaining, name: 'Pozostałe' },
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
          radius: ['30%', '70%'],
 | 
					          radius: ['30%', '70%'],
 | 
				
			||||||
          itemStyle : {
 | 
					 | 
				
			||||||
            normal: {
 | 
					 | 
				
			||||||
              borderRadius: 10,
 | 
					 | 
				
			||||||
              borderColor: '#fff',
 | 
					 | 
				
			||||||
              borderWidth: 2,
 | 
					 | 
				
			||||||
              label: {
 | 
					 | 
				
			||||||
                position: 'inner',
 | 
					 | 
				
			||||||
                formatter: param => param.value !== 0 ? param.value : '' ,
 | 
					 | 
				
			||||||
                fontWeight: 'bold',
 | 
					 | 
				
			||||||
                fontSize: 16,
 | 
					 | 
				
			||||||
                color: '#FFFFFF',
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
              labelLine: {
 | 
					 | 
				
			||||||
                show: false,
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
    }))
 | 
					    }))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,7 +34,8 @@ class HolidayTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testAdminCanCreateHoliday(): void
 | 
					    public function testAdminCanCreateHoliday(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = User::factory()->create();
 | 
					        $admin = User::factory()->admin()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $currentYearPeriod = YearPeriod::current();
 | 
					        $currentYearPeriod = YearPeriod::current();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->actingAs($admin)
 | 
					        $this->actingAs($admin)
 | 
				
			||||||
@@ -53,7 +54,8 @@ class HolidayTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testAdminCannotCreateHolidayForYearPeriodThatDoesntExist(): void
 | 
					    public function testAdminCannotCreateHolidayForYearPeriodThatDoesntExist(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = User::factory()->create();
 | 
					        $admin = User::factory()->admin()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $year = YearPeriod::query()->max("year") + 1;
 | 
					        $year = YearPeriod::query()->max("year") + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->actingAs($admin)
 | 
					        $this->actingAs($admin)
 | 
				
			||||||
@@ -66,7 +68,8 @@ class HolidayTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testAdminCannotCreateHolidayIfGivenDataIsUsed(): void
 | 
					    public function testAdminCannotCreateHolidayIfGivenDataIsUsed(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = User::factory()->create();
 | 
					        $admin = User::factory()->admin()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $currentYearPeriod = YearPeriod::current();
 | 
					        $currentYearPeriod = YearPeriod::current();
 | 
				
			||||||
        $sameDate = Carbon::create($currentYearPeriod->year, 5, 20)->toDateString();
 | 
					        $sameDate = Carbon::create($currentYearPeriod->year, 5, 20)->toDateString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -85,7 +88,8 @@ class HolidayTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testAdminCanEditHoliday(): void
 | 
					    public function testAdminCanEditHoliday(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = User::factory()->create();
 | 
					        $admin = User::factory()->admin()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $currentYearPeriod = YearPeriod::current();
 | 
					        $currentYearPeriod = YearPeriod::current();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $holiday = Holiday::factory()->create([
 | 
					        $holiday = Holiday::factory()->create([
 | 
				
			||||||
@@ -115,7 +119,8 @@ class HolidayTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testAdminCanDeleteHoliday(): void
 | 
					    public function testAdminCanDeleteHoliday(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = User::factory()->create();
 | 
					        $admin = User::factory()->admin()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $holiday = Holiday::factory()->create();
 | 
					        $holiday = Holiday::factory()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->actingAs($admin)
 | 
					        $this->actingAs($admin)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,7 @@ class UserTest extends FeatureTestCase
 | 
				
			|||||||
    public function testAdminCanSeeUsersList(): void
 | 
					    public function testAdminCanSeeUsersList(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        User::factory()->count(10)->create();
 | 
					        User::factory()->count(10)->create();
 | 
				
			||||||
        $admin = User::factory()->create();
 | 
					        $admin = User::factory()->admin()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertDatabaseCount("users", 11);
 | 
					        $this->assertDatabaseCount("users", 11);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,18 +38,21 @@ class UserTest extends FeatureTestCase
 | 
				
			|||||||
            "first_name" => "Test",
 | 
					            "first_name" => "Test",
 | 
				
			||||||
            "last_name" => "User1",
 | 
					            "last_name" => "User1",
 | 
				
			||||||
        ])->create();
 | 
					        ])->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        User::factory([
 | 
					        User::factory([
 | 
				
			||||||
            "first_name" => "Test",
 | 
					            "first_name" => "Test",
 | 
				
			||||||
            "last_name" => "User2",
 | 
					            "last_name" => "User2",
 | 
				
			||||||
        ])->create();
 | 
					        ])->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        User::factory([
 | 
					        User::factory([
 | 
				
			||||||
            "first_name" => "Test",
 | 
					            "first_name" => "Test",
 | 
				
			||||||
            "last_name" => "User3",
 | 
					            "last_name" => "User3",
 | 
				
			||||||
        ])->create();
 | 
					        ])->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $admin = User::factory([
 | 
					        $admin = User::factory([
 | 
				
			||||||
            "first_name" => "John",
 | 
					            "first_name" => "John",
 | 
				
			||||||
            "last_name" => "Doe",
 | 
					            "last_name" => "Doe",
 | 
				
			||||||
        ])->create();
 | 
					        ])->admin()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertDatabaseCount("users", 4);
 | 
					        $this->assertDatabaseCount("users", 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -66,7 +69,7 @@ class UserTest extends FeatureTestCase
 | 
				
			|||||||
    public function testUserListIsPaginated(): void
 | 
					    public function testUserListIsPaginated(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        User::factory()->count(15)->create();
 | 
					        User::factory()->count(15)->create();
 | 
				
			||||||
        $admin = User::factory()->create();
 | 
					        $admin = User::factory()->admin()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertDatabaseCount("users", 16);
 | 
					        $this->assertDatabaseCount("users", 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -81,7 +84,7 @@ class UserTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testAdminCanCreateUser(): void
 | 
					    public function testAdminCanCreateUser(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = User::factory()->create();
 | 
					        $admin = User::factory()->admin()->create();
 | 
				
			||||||
        Carbon::setTestNow(Carbon::now());
 | 
					        Carbon::setTestNow(Carbon::now());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->actingAs($admin)
 | 
					        $this->actingAs($admin)
 | 
				
			||||||
@@ -109,7 +112,8 @@ class UserTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testAdminCanEditUser(): void
 | 
					    public function testAdminCanEditUser(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = User::factory()->create();
 | 
					        $admin = User::factory()->admin()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $user = User::factory()->create();
 | 
					        $user = User::factory()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Carbon::setTestNow();
 | 
					        Carbon::setTestNow();
 | 
				
			||||||
@@ -147,7 +151,8 @@ class UserTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testAdminCanDeleteUser(): void
 | 
					    public function testAdminCanDeleteUser(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = User::factory()->create();
 | 
					        $admin = User::factory()->admin()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $user = User::factory()->create();
 | 
					        $user = User::factory()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->actingAs($admin)
 | 
					        $this->actingAs($admin)
 | 
				
			||||||
@@ -159,7 +164,8 @@ class UserTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testAdminCanRestoreUser(): void
 | 
					    public function testAdminCanRestoreUser(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = User::factory()->create();
 | 
					        $admin = User::factory()->admin()->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $user = User::factory()->create();
 | 
					        $user = User::factory()->create();
 | 
				
			||||||
        $user->delete();
 | 
					        $user->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ class VacationLimitTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testAdminCanSeeVacationLimits(): void
 | 
					    public function testAdminCanSeeVacationLimits(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = User::factory()->createQuietly();
 | 
					        $admin = User::factory()->admin()->createQuietly();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        User::factory(10)->create();
 | 
					        User::factory(10)->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,7 +32,7 @@ class VacationLimitTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testAdminCanUpdateVacationLimits(): void
 | 
					    public function testAdminCanUpdateVacationLimits(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $admin = User::factory()->createQuietly();
 | 
					        $admin = User::factory()->admin()->createQuietly();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        User::factory(3)->create();
 | 
					        User::factory(3)->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,13 +9,16 @@ use Illuminate\Support\Carbon;
 | 
				
			|||||||
use Illuminate\Support\Facades\Event;
 | 
					use Illuminate\Support\Facades\Event;
 | 
				
			||||||
use Inertia\Testing\AssertableInertia as Assert;
 | 
					use Inertia\Testing\AssertableInertia as Assert;
 | 
				
			||||||
use Tests\FeatureTestCase;
 | 
					use Tests\FeatureTestCase;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					 | 
				
			||||||
use Toby\Domain\Enums\VacationType;
 | 
					use Toby\Domain\Enums\VacationType;
 | 
				
			||||||
use Toby\Domain\Events\VacationRequestAcceptedByAdministrative;
 | 
					use Toby\Domain\Events\VacationRequestAcceptedByAdministrative;
 | 
				
			||||||
use Toby\Domain\Events\VacationRequestAcceptedByTechnical;
 | 
					use Toby\Domain\Events\VacationRequestAcceptedByTechnical;
 | 
				
			||||||
use Toby\Domain\Events\VacationRequestApproved;
 | 
					use Toby\Domain\Events\VacationRequestApproved;
 | 
				
			||||||
use Toby\Domain\Events\VacationRequestRejected;
 | 
					use Toby\Domain\Events\VacationRequestRejected;
 | 
				
			||||||
use Toby\Domain\PolishHolidaysRetriever;
 | 
					use Toby\Domain\PolishHolidaysRetriever;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Approved;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Rejected;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\WaitingForAdministrative;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\WaitingForTechnical;
 | 
				
			||||||
use Toby\Eloquent\Models\User;
 | 
					use Toby\Eloquent\Models\User;
 | 
				
			||||||
use Toby\Eloquent\Models\VacationLimit;
 | 
					use Toby\Eloquent\Models\VacationLimit;
 | 
				
			||||||
use Toby\Eloquent\Models\VacationRequest;
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
@@ -83,7 +86,7 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
            "year_period_id" => $currentYearPeriod->id,
 | 
					            "year_period_id" => $currentYearPeriod->id,
 | 
				
			||||||
            "name" => "1/" . $currentYearPeriod->year,
 | 
					            "name" => "1/" . $currentYearPeriod->year,
 | 
				
			||||||
            "type" => VacationType::Vacation->value,
 | 
					            "type" => VacationType::Vacation->value,
 | 
				
			||||||
            "state" => VacationRequestState::WaitingForTechnical,
 | 
					            "state" => WaitingForTechnical::$name,
 | 
				
			||||||
            "from" => Carbon::create($currentYearPeriod->year, 2, 7)->toDateString(),
 | 
					            "from" => Carbon::create($currentYearPeriod->year, 2, 7)->toDateString(),
 | 
				
			||||||
            "to" => Carbon::create($currentYearPeriod->year, 2, 11)->toDateString(),
 | 
					            "to" => Carbon::create($currentYearPeriod->year, 2, 11)->toDateString(),
 | 
				
			||||||
            "comment" => "Comment for the vacation request.",
 | 
					            "comment" => "Comment for the vacation request.",
 | 
				
			||||||
@@ -92,7 +95,7 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function testUserCanCreateVacationRequestOnEmployeeBehalf(): void
 | 
					    public function testUserCanCreateVacationRequestOnEmployeeBehalf(): void
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $creator = User::factory()->createQuietly();
 | 
					        $creator = User::factory()->admin()->createQuietly();
 | 
				
			||||||
        $user = User::factory()->createQuietly();
 | 
					        $user = User::factory()->createQuietly();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $currentYearPeriod = YearPeriod::current();
 | 
					        $currentYearPeriod = YearPeriod::current();
 | 
				
			||||||
@@ -120,7 +123,7 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
            "year_period_id" => $currentYearPeriod->id,
 | 
					            "year_period_id" => $currentYearPeriod->id,
 | 
				
			||||||
            "name" => "1/" . $currentYearPeriod->year,
 | 
					            "name" => "1/" . $currentYearPeriod->year,
 | 
				
			||||||
            "type" => VacationType::Vacation->value,
 | 
					            "type" => VacationType::Vacation->value,
 | 
				
			||||||
            "state" => VacationRequestState::WaitingForTechnical,
 | 
					            "state" => WaitingForTechnical::$name,
 | 
				
			||||||
            "from" => Carbon::create($currentYearPeriod->year, 2, 7)->toDateString(),
 | 
					            "from" => Carbon::create($currentYearPeriod->year, 2, 7)->toDateString(),
 | 
				
			||||||
            "to" => Carbon::create($currentYearPeriod->year, 2, 11)->toDateString(),
 | 
					            "to" => Carbon::create($currentYearPeriod->year, 2, 11)->toDateString(),
 | 
				
			||||||
            "comment" => "Comment for the vacation request.",
 | 
					            "comment" => "Comment for the vacation request.",
 | 
				
			||||||
@@ -131,7 +134,7 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        Event::fake(VacationRequestApproved::class);
 | 
					        Event::fake(VacationRequestApproved::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $creator = User::factory()->createQuietly();
 | 
					        $creator = User::factory()->admin()->createQuietly();
 | 
				
			||||||
        $user = User::factory()->createQuietly();
 | 
					        $user = User::factory()->createQuietly();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $currentYearPeriod = YearPeriod::current();
 | 
					        $currentYearPeriod = YearPeriod::current();
 | 
				
			||||||
@@ -160,7 +163,7 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
            "year_period_id" => $currentYearPeriod->id,
 | 
					            "year_period_id" => $currentYearPeriod->id,
 | 
				
			||||||
            "name" => "1/" . $currentYearPeriod->year,
 | 
					            "name" => "1/" . $currentYearPeriod->year,
 | 
				
			||||||
            "type" => VacationType::Vacation->value,
 | 
					            "type" => VacationType::Vacation->value,
 | 
				
			||||||
            "state" => VacationRequestState::Approved,
 | 
					            "state" => Approved::$name,
 | 
				
			||||||
            "from" => Carbon::create($currentYearPeriod->year, 2, 7)->toDateString(),
 | 
					            "from" => Carbon::create($currentYearPeriod->year, 2, 7)->toDateString(),
 | 
				
			||||||
            "to" => Carbon::create($currentYearPeriod->year, 2, 11)->toDateString(),
 | 
					            "to" => Carbon::create($currentYearPeriod->year, 2, 11)->toDateString(),
 | 
				
			||||||
            "comment" => "Comment for the vacation request.",
 | 
					            "comment" => "Comment for the vacation request.",
 | 
				
			||||||
@@ -172,11 +175,11 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
        Event::fake(VacationRequestAcceptedByTechnical::class);
 | 
					        Event::fake(VacationRequestAcceptedByTechnical::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $user = User::factory()->createQuietly();
 | 
					        $user = User::factory()->createQuietly();
 | 
				
			||||||
        $technicalApprover = User::factory()->createQuietly();
 | 
					        $technicalApprover = User::factory()->technicalApprover()->createQuietly();
 | 
				
			||||||
        $currentYearPeriod = YearPeriod::current();
 | 
					        $currentYearPeriod = YearPeriod::current();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $vacationRequest = VacationRequest::factory([
 | 
					        $vacationRequest = VacationRequest::factory([
 | 
				
			||||||
            "state" => VacationRequestState::WaitingForTechnical,
 | 
					            "state" => WaitingForTechnical::class,
 | 
				
			||||||
            "type" => VacationType::Vacation,
 | 
					            "type" => VacationType::Vacation,
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
            ->for($user)
 | 
					            ->for($user)
 | 
				
			||||||
@@ -195,12 +198,12 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
        Event::fake(VacationRequestAcceptedByAdministrative::class);
 | 
					        Event::fake(VacationRequestAcceptedByAdministrative::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $user = User::factory()->createQuietly();
 | 
					        $user = User::factory()->createQuietly();
 | 
				
			||||||
        $administrativeApprover = User::factory()->createQuietly();
 | 
					        $administrativeApprover = User::factory()->administrativeApprover()->createQuietly();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $currentYearPeriod = YearPeriod::current();
 | 
					        $currentYearPeriod = YearPeriod::current();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $vacationRequest = VacationRequest::factory([
 | 
					        $vacationRequest = VacationRequest::factory([
 | 
				
			||||||
            "state" => VacationRequestState::WaitingForAdministrative,
 | 
					            "state" => WaitingForAdministrative::class,
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
            ->for($user)
 | 
					            ->for($user)
 | 
				
			||||||
            ->for($currentYearPeriod)
 | 
					            ->for($currentYearPeriod)
 | 
				
			||||||
@@ -218,7 +221,7 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
        Event::fake(VacationRequestRejected::class);
 | 
					        Event::fake(VacationRequestRejected::class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $user = User::factory()->createQuietly();
 | 
					        $user = User::factory()->createQuietly();
 | 
				
			||||||
        $technicalApprover = User::factory()->createQuietly();
 | 
					        $technicalApprover = User::factory()->technicalApprover()->createQuietly();
 | 
				
			||||||
        $currentYearPeriod = YearPeriod::current();
 | 
					        $currentYearPeriod = YearPeriod::current();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        VacationLimit::factory([
 | 
					        VacationLimit::factory([
 | 
				
			||||||
@@ -229,7 +232,7 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
            ->create();
 | 
					            ->create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $vacationRequest = VacationRequest::factory([
 | 
					        $vacationRequest = VacationRequest::factory([
 | 
				
			||||||
            "state" => VacationRequestState::WaitingForTechnical,
 | 
					            "state" => WaitingForTechnical::class,
 | 
				
			||||||
            "type" => VacationType::Vacation,
 | 
					            "type" => VacationType::Vacation,
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
            ->for($user)
 | 
					            ->for($user)
 | 
				
			||||||
@@ -241,6 +244,9 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
            ->assertSessionHasNoErrors();
 | 
					            ->assertSessionHasNoErrors();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Event::assertDispatched(VacationRequestRejected::class);
 | 
					        Event::assertDispatched(VacationRequestRejected::class);
 | 
				
			||||||
 | 
					        $this->assertDatabaseHas("vacation_requests", [
 | 
				
			||||||
 | 
					            "state" => Rejected::$name,
 | 
				
			||||||
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testUserCannotCreateVacationRequestIfHeExceedsHisVacationLimit(): void
 | 
					    public function testUserCannotCreateVacationRequestIfHeExceedsHisVacationLimit(): void
 | 
				
			||||||
@@ -339,7 +345,7 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        VacationRequest::factory([
 | 
					        VacationRequest::factory([
 | 
				
			||||||
            "type" => VacationType::Vacation->value,
 | 
					            "type" => VacationType::Vacation->value,
 | 
				
			||||||
            "state" => VacationRequestState::WaitingForTechnical,
 | 
					            "state" => WaitingForTechnical::class,
 | 
				
			||||||
            "from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
 | 
					            "from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
 | 
				
			||||||
            "to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
 | 
					            "to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
 | 
				
			||||||
            "comment" => "Comment for the vacation request.",
 | 
					            "comment" => "Comment for the vacation request.",
 | 
				
			||||||
@@ -358,8 +364,7 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
            ])
 | 
					            ])
 | 
				
			||||||
            ->assertSessionHasErrors([
 | 
					            ->assertSessionHasErrors([
 | 
				
			||||||
                "vacationRequest" => __("You have pending vacation request in this range."),
 | 
					                "vacationRequest" => __("You have pending vacation request in this range."),
 | 
				
			||||||
            ])
 | 
					            ]);
 | 
				
			||||||
        ;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testUserCannotCreateVacationRequestIfHeHasApprovedVacationRequestInThisRange(): void
 | 
					    public function testUserCannotCreateVacationRequestIfHeHasApprovedVacationRequestInThisRange(): void
 | 
				
			||||||
@@ -367,7 +372,7 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
        $user = User::factory()->createQuietly();
 | 
					        $user = User::factory()->createQuietly();
 | 
				
			||||||
        $currentYearPeriod = YearPeriod::current();
 | 
					        $currentYearPeriod = YearPeriod::current();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $vacationLimit = VacationLimit::factory([
 | 
					        VacationLimit::factory([
 | 
				
			||||||
            "days" => 20,
 | 
					            "days" => 20,
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
            ->for($user)
 | 
					            ->for($user)
 | 
				
			||||||
@@ -376,7 +381,7 @@ class VacationRequestTest extends FeatureTestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        VacationRequest::factory([
 | 
					        VacationRequest::factory([
 | 
				
			||||||
            "type" => VacationType::Vacation->value,
 | 
					            "type" => VacationType::Vacation->value,
 | 
				
			||||||
            "state" => VacationRequestState::Approved,
 | 
					            "state" => Approved::class,
 | 
				
			||||||
            "from" => Carbon::create($currentYearPeriod->year, 2, 2)->toDateString(),
 | 
					            "from" => Carbon::create($currentYearPeriod->year, 2, 2)->toDateString(),
 | 
				
			||||||
            "to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
 | 
					            "to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
 | 
				
			||||||
            "comment" => "Comment for the vacation request.",
 | 
					            "comment" => "Comment for the vacation request.",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,9 +10,9 @@ use Illuminate\Support\Facades\Notification;
 | 
				
			|||||||
use Tests\TestCase;
 | 
					use Tests\TestCase;
 | 
				
			||||||
use Tests\Traits\InteractsWithYearPeriods;
 | 
					use Tests\Traits\InteractsWithYearPeriods;
 | 
				
			||||||
use Toby\Domain\Enums\Role;
 | 
					use Toby\Domain\Enums\Role;
 | 
				
			||||||
use Toby\Domain\Enums\VacationRequestState;
 | 
					 | 
				
			||||||
use Toby\Domain\Enums\VacationType;
 | 
					use Toby\Domain\Enums\VacationType;
 | 
				
			||||||
use Toby\Domain\Notifications\VacationRequestWaitsForTechApprovalNotification;
 | 
					use Toby\Domain\Notifications\VacationRequestWaitsForTechApprovalNotification;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Created;
 | 
				
			||||||
use Toby\Domain\VacationRequestStateManager;
 | 
					use Toby\Domain\VacationRequestStateManager;
 | 
				
			||||||
use Toby\Eloquent\Models\User;
 | 
					use Toby\Eloquent\Models\User;
 | 
				
			||||||
use Toby\Eloquent\Models\VacationRequest;
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
@@ -53,7 +53,7 @@ class VacationRequestNotificationTest extends TestCase
 | 
				
			|||||||
        /** @var VacationRequest $vacationRequest */
 | 
					        /** @var VacationRequest $vacationRequest */
 | 
				
			||||||
        $vacationRequest = VacationRequest::factory([
 | 
					        $vacationRequest = VacationRequest::factory([
 | 
				
			||||||
            "type" => VacationType::Vacation->value,
 | 
					            "type" => VacationType::Vacation->value,
 | 
				
			||||||
            "state" => VacationRequestState::Created,
 | 
					            "state" => Created::class,
 | 
				
			||||||
            "from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
 | 
					            "from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
 | 
				
			||||||
            "to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
 | 
					            "to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
 | 
				
			||||||
            "comment" => "Comment for the vacation request.",
 | 
					            "comment" => "Comment for the vacation request.",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,8 +9,10 @@ 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\Enums\VacationRequestState;
 | 
					 | 
				
			||||||
use Toby\Domain\Enums\VacationType;
 | 
					use Toby\Domain\Enums\VacationType;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Approved;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\Created;
 | 
				
			||||||
 | 
					use Toby\Domain\States\VacationRequest\WaitingForTechnical;
 | 
				
			||||||
use Toby\Domain\VacationRequestStateManager;
 | 
					use Toby\Domain\VacationRequestStateManager;
 | 
				
			||||||
use Toby\Eloquent\Models\User;
 | 
					use Toby\Eloquent\Models\User;
 | 
				
			||||||
use Toby\Eloquent\Models\VacationRequest;
 | 
					use Toby\Eloquent\Models\VacationRequest;
 | 
				
			||||||
@@ -43,7 +45,7 @@ class VacationRequestStatesTest extends TestCase
 | 
				
			|||||||
        /** @var VacationRequest $vacationRequest */
 | 
					        /** @var VacationRequest $vacationRequest */
 | 
				
			||||||
        $vacationRequest = VacationRequest::factory([
 | 
					        $vacationRequest = VacationRequest::factory([
 | 
				
			||||||
            "type" => VacationType::Vacation->value,
 | 
					            "type" => VacationType::Vacation->value,
 | 
				
			||||||
            "state" => VacationRequestState::Created,
 | 
					            "state" => Created::class,
 | 
				
			||||||
            "from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
 | 
					            "from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
 | 
				
			||||||
            "to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
 | 
					            "to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
 | 
				
			||||||
            "comment" => "Comment for the vacation request.",
 | 
					            "comment" => "Comment for the vacation request.",
 | 
				
			||||||
@@ -54,7 +56,7 @@ class VacationRequestStatesTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->stateManager->waitForTechnical($vacationRequest);
 | 
					        $this->stateManager->waitForTechnical($vacationRequest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertEquals(VacationRequestState::WaitingForTechnical, $vacationRequest->state);
 | 
					        $this->assertTrue($vacationRequest->state->equals(WaitingForTechnical::class));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testAfterCreatingVacationRequestOfTypeSickVacationItTransitsToProperState(): void
 | 
					    public function testAfterCreatingVacationRequestOfTypeSickVacationItTransitsToProperState(): void
 | 
				
			||||||
@@ -66,7 +68,7 @@ class VacationRequestStatesTest extends TestCase
 | 
				
			|||||||
        /** @var VacationRequest $vacationRequest */
 | 
					        /** @var VacationRequest $vacationRequest */
 | 
				
			||||||
        $vacationRequest = VacationRequest::factory([
 | 
					        $vacationRequest = VacationRequest::factory([
 | 
				
			||||||
            "type" => VacationType::Sick->value,
 | 
					            "type" => VacationType::Sick->value,
 | 
				
			||||||
            "state" => VacationRequestState::Created,
 | 
					            "state" => Created::class,
 | 
				
			||||||
            "from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
 | 
					            "from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
 | 
				
			||||||
            "to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
 | 
					            "to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
@@ -76,7 +78,7 @@ class VacationRequestStatesTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->stateManager->approve($vacationRequest);
 | 
					        $this->stateManager->approve($vacationRequest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertEquals(VacationRequestState::Approved, $vacationRequest->state);
 | 
					        $this->assertTrue($vacationRequest->state->equals(Approved::class));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function testAfterCreatingVacationRequestOfTypeTimeInLieuItTransitsToProperState(): void
 | 
					    public function testAfterCreatingVacationRequestOfTypeTimeInLieuItTransitsToProperState(): void
 | 
				
			||||||
@@ -88,7 +90,7 @@ class VacationRequestStatesTest extends TestCase
 | 
				
			|||||||
        /** @var VacationRequest $vacationRequest */
 | 
					        /** @var VacationRequest $vacationRequest */
 | 
				
			||||||
        $vacationRequest = VacationRequest::factory([
 | 
					        $vacationRequest = VacationRequest::factory([
 | 
				
			||||||
            "type" => VacationType::TimeInLieu->value,
 | 
					            "type" => VacationType::TimeInLieu->value,
 | 
				
			||||||
            "state" => VacationRequestState::Created,
 | 
					            "state" => Created::class,
 | 
				
			||||||
            "from" => Carbon::create($currentYearPeriod->year, 2, 2)->toDateString(),
 | 
					            "from" => Carbon::create($currentYearPeriod->year, 2, 2)->toDateString(),
 | 
				
			||||||
            "to" => Carbon::create($currentYearPeriod->year, 2, 2)->toDateString(),
 | 
					            "to" => Carbon::create($currentYearPeriod->year, 2, 2)->toDateString(),
 | 
				
			||||||
        ])
 | 
					        ])
 | 
				
			||||||
@@ -98,6 +100,6 @@ class VacationRequestStatesTest extends TestCase
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        $this->stateManager->approve($vacationRequest);
 | 
					        $this->stateManager->approve($vacationRequest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->assertEquals(VacationRequestState::Approved, $vacationRequest->state);
 | 
					        $this->assertTrue($vacationRequest->state->equals(Approved::class));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user