diff --git a/app/Architecture/Providers/ObserverServiceProvider.php b/app/Architecture/Providers/ObserverServiceProvider.php index 3409e18..0a7dfa6 100644 --- a/app/Architecture/Providers/ObserverServiceProvider.php +++ b/app/Architecture/Providers/ObserverServiceProvider.php @@ -6,15 +6,12 @@ namespace Toby\Architecture\Providers; use Illuminate\Support\ServiceProvider; use Toby\Eloquent\Models\User; -use Toby\Eloquent\Models\YearPeriod; use Toby\Eloquent\Observers\UserObserver; -use Toby\Eloquent\Observers\YearPeriodObserver; class ObserverServiceProvider extends ServiceProvider { public function boot(): void { User::observe(UserObserver::class); - YearPeriod::observe(YearPeriodObserver::class); } } diff --git a/app/Domain/Actions/CreateUserAction.php b/app/Domain/Actions/CreateUserAction.php new file mode 100644 index 0000000..2107a1c --- /dev/null +++ b/app/Domain/Actions/CreateUserAction.php @@ -0,0 +1,33 @@ +save(); + + $this->createVacationLimitsFor($user); + + return $user; + } + + protected function createVacationLimitsFor(User $user): void + { + $yearPeriods = YearPeriod::all(); + + foreach ($yearPeriods as $yearPeriod) { + $user->vacationLimits()->create([ + "year_period_id" => $yearPeriod->id, + ]); + } + } +} diff --git a/app/Eloquent/Observers/YearPeriodObserver.php b/app/Domain/Actions/CreateYearPeriodAction.php similarity index 80% rename from app/Eloquent/Observers/YearPeriodObserver.php rename to app/Domain/Actions/CreateYearPeriodAction.php index b7f370b..8b38bb6 100644 --- a/app/Eloquent/Observers/YearPeriodObserver.php +++ b/app/Domain/Actions/CreateYearPeriodAction.php @@ -2,22 +2,30 @@ declare(strict_types=1); -namespace Toby\Eloquent\Observers; +namespace Toby\Domain\Actions; use Toby\Domain\PolishHolidaysRetriever; use Toby\Eloquent\Models\User; use Toby\Eloquent\Models\YearPeriod; -class YearPeriodObserver +class CreateYearPeriodAction { public function __construct( protected PolishHolidaysRetriever $polishHolidaysRetriever, ) {} - public function created(YearPeriod $yearPeriod): void + public function execute(int $year): YearPeriod { + $yearPeriod = new YearPeriod([ + "year" => $year, + ]); + + $yearPeriod->save(); + $this->createVacationLimitsFor($yearPeriod); $this->createHolidaysFor($yearPeriod); + + return $yearPeriod; } protected function createVacationLimitsFor(YearPeriod $yearPeriod): void diff --git a/app/Domain/CalendarGenerator.php b/app/Domain/CalendarGenerator.php index 61313cb..30d42b7 100644 --- a/app/Domain/CalendarGenerator.php +++ b/app/Domain/CalendarGenerator.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace Toby\Domain; use Carbon\CarbonPeriod; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Carbon; use Illuminate\Support\Collection; use Toby\Eloquent\Helpers\YearPeriodRetriever; @@ -55,7 +54,7 @@ class CalendarGenerator { return Vacation::query() ->whereBetween("date", [$period->start, $period->end]) - ->whereRelation("vacationRequest", fn(Builder $query) => $query->states(VacationRequestStatesRetriever::successStates())) + ->approved() ->with("vacationRequest") ->get() ->groupBy(fn(Vacation $vacation) => $vacation->date->toDateString()); diff --git a/app/Domain/TimesheetPerUserSheet.php b/app/Domain/TimesheetPerUserSheet.php index 8e0fa6d..e419463 100644 --- a/app/Domain/TimesheetPerUserSheet.php +++ b/app/Domain/TimesheetPerUserSheet.php @@ -25,7 +25,6 @@ use PhpOffice\PhpSpreadsheet\Style\Fill; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use Toby\Domain\Enums\VacationType; -use Toby\Domain\States\VacationRequest\Approved; use Toby\Eloquent\Models\Holiday; use Toby\Eloquent\Models\User; use Toby\Eloquent\Models\Vacation; @@ -189,7 +188,7 @@ class TimesheetPerUserSheet implements WithTitle, WithHeadings, WithEvents, With return $user->vacations() ->with("vacationRequest") ->whereBetween("date", [$period->start, $period->end]) - ->whereRelation("vacationRequest", "state", Approved::$name) + ->approved() ->get() ->groupBy( [ diff --git a/app/Domain/UserVacationStatsRetriever.php b/app/Domain/UserVacationStatsRetriever.php index 283399c..dcf8c99 100644 --- a/app/Domain/UserVacationStatsRetriever.php +++ b/app/Domain/UserVacationStatsRetriever.php @@ -88,7 +88,7 @@ class UserVacationStatsRetriever $limit = $user->vacationLimits() ->where("year_period_id", $yearPeriod->id) ->first() - ->days; + ?->days; return $limit ?? 0; } diff --git a/app/Eloquent/Models/User.php b/app/Eloquent/Models/User.php index 03e8b3f..0256927 100644 --- a/app/Eloquent/Models/User.php +++ b/app/Eloquent/Models/User.php @@ -71,18 +71,6 @@ class User extends Authenticatable return $this->hasMany(Vacation::class); } - public function scopeSearch(Builder $query, ?string $text): Builder - { - if ($text === null) { - return $query; - } - - return $query - ->where("first_name", "ILIKE", $text) - ->orWhere("last_name", "ILIKE", $text) - ->orWhere("email", "ILIKE", $text); - } - public function getAvatar(): string { return $this->getAvatarGenerator() @@ -108,6 +96,28 @@ class User extends Authenticatable ->exists(); } + public function scopeSearch(Builder $query, ?string $text): Builder + { + if ($text === null) { + return $query; + } + + return $query + ->where("first_name", "ILIKE", $text) + ->orWhere("last_name", "ILIKE", $text) + ->orWhere("email", "ILIKE", $text); + } + + public function scopeWithVacationLimitIn(Builder $query, YearPeriod $yearPeriod): Builder + { + return $query->whereRelation( + "vacationlimits", + fn(Builder $query) => $query + ->where("year_period_id", $yearPeriod->id) + ->whereNotNull("days"), + ); + } + protected function getAvatarName(): string { return mb_substr($this->first_name, 0, 1) . mb_substr($this->last_name, 0, 1); diff --git a/app/Eloquent/Models/Vacation.php b/app/Eloquent/Models/Vacation.php index c22cf76..65ac662 100644 --- a/app/Eloquent/Models/Vacation.php +++ b/app/Eloquent/Models/Vacation.php @@ -4,10 +4,12 @@ declare(strict_types=1); namespace Toby\Eloquent\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Support\Carbon; +use Toby\Domain\VacationRequestStatesRetriever; /** * @property int $id @@ -40,4 +42,12 @@ class Vacation extends Model { return $this->belongsTo(YearPeriod::class); } + + public function scopeApproved(Builder $query): Builder + { + return $query->whereRelation( + "vacationRequest", + fn(Builder $query) => $query->states(VacationRequestStatesRetriever::successStates()), + ); + } } diff --git a/app/Eloquent/Observers/UserObserver.php b/app/Eloquent/Observers/UserObserver.php index b241609..cec30e6 100644 --- a/app/Eloquent/Observers/UserObserver.php +++ b/app/Eloquent/Observers/UserObserver.php @@ -7,7 +7,6 @@ namespace Toby\Eloquent\Observers; use Illuminate\Contracts\Hashing\Hasher; use Illuminate\Support\Str; use Toby\Eloquent\Models\User; -use Toby\Eloquent\Models\YearPeriod; class UserObserver { @@ -23,15 +22,4 @@ class UserObserver */ $user->password = $this->hash->make(Str::random(40)); } - - public function created(User $user): void - { - $yearPeriods = YearPeriod::all(); - - foreach ($yearPeriods as $yearPeriod) { - $user->vacationLimits()->create([ - "year_period_id" => $yearPeriod->id, - ]); - } - } } diff --git a/app/Infrastructure/Http/Controllers/DashboardController.php b/app/Infrastructure/Http/Controllers/DashboardController.php index f215a93..1a94510 100644 --- a/app/Infrastructure/Http/Controllers/DashboardController.php +++ b/app/Infrastructure/Http/Controllers/DashboardController.php @@ -4,7 +4,6 @@ declare(strict_types=1); namespace Toby\Infrastructure\Http\Controllers; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; use Illuminate\Support\Carbon; use Inertia\Response; @@ -29,10 +28,7 @@ class DashboardController extends Controller $absences = Vacation::query() ->with(["user", "vacationRequest"]) ->whereDate("date", $now) - ->whereRelation( - "vacationRequest", - fn(Builder $query) => $query->states(VacationRequestStatesRetriever::successStates()), - ) + ->approved() ->get(); if ($user->can("listAll", VacationRequest::class)) { diff --git a/app/Infrastructure/Http/Controllers/MonthlyUsageController.php b/app/Infrastructure/Http/Controllers/MonthlyUsageController.php index c2ab9bd..6b7784b 100644 --- a/app/Infrastructure/Http/Controllers/MonthlyUsageController.php +++ b/app/Infrastructure/Http/Controllers/MonthlyUsageController.php @@ -4,7 +4,6 @@ declare(strict_types=1); namespace Toby\Infrastructure\Http\Controllers; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; use Inertia\Response; use Toby\Domain\Enums\Month; @@ -26,10 +25,7 @@ class MonthlyUsageController extends Controller $currentUser = $request->user(); $users = User::query() - ->whereRelation( - "vacationlimits", - fn(Builder $query) => $query->where("year_period_id", $currentYearPeriod->id)->whereNotNull("days"), - ) + ->withVacationLimitIn($currentYearPeriod) ->where("id", "!=", $currentUser->id) ->orderBy("last_name") ->orderBy("first_name") diff --git a/app/Infrastructure/Http/Controllers/UserController.php b/app/Infrastructure/Http/Controllers/UserController.php index 46557da..39c35b4 100644 --- a/app/Infrastructure/Http/Controllers/UserController.php +++ b/app/Infrastructure/Http/Controllers/UserController.php @@ -8,6 +8,7 @@ use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Inertia\Response; +use Toby\Domain\Actions\CreateUserAction; use Toby\Domain\Enums\EmploymentForm; use Toby\Domain\Enums\Role; use Toby\Eloquent\Models\User; @@ -54,11 +55,11 @@ class UserController extends Controller /** * @throws AuthorizationException */ - public function store(UserRequest $request): RedirectResponse + public function store(UserRequest $request, CreateUserAction $createUserAction): RedirectResponse { $this->authorize("manageUsers"); - User::query()->create($request->data()); + $createUserAction->execute($request->data()); return redirect() ->route("users.index") diff --git a/app/Infrastructure/Http/Controllers/VacationRequestController.php b/app/Infrastructure/Http/Controllers/VacationRequestController.php index a11c1de..1ea2e0f 100644 --- a/app/Infrastructure/Http/Controllers/VacationRequestController.php +++ b/app/Infrastructure/Http/Controllers/VacationRequestController.php @@ -103,10 +103,7 @@ class VacationRequestController extends Controller ->paginate(); $users = User::query() - ->whereRelation( - "vacationlimits", - fn(Builder $query) => $query->where("year_period_id", $yearPeriod->id)->whereNotNull("days"), - ) + ->withVacationLimitIn($yearPeriod) ->orderBy("last_name") ->orderBy("first_name") ->get(); @@ -164,10 +161,7 @@ class VacationRequestController extends Controller $yearPeriod = $yearPeriodRetriever->selected(); $users = User::query() - ->whereRelation( - "vacationlimits", - fn(Builder $query) => $query->where("year_period_id", $yearPeriod->id)->whereNotNull("days"), - ) + ->withVacationLimitIn($yearPeriod) ->orderBy("last_name") ->orderBy("first_name") ->get(); diff --git a/app/Infrastructure/Jobs/CheckYearPeriod.php b/app/Infrastructure/Jobs/CheckYearPeriod.php index 9922e01..62bf937 100644 --- a/app/Infrastructure/Jobs/CheckYearPeriod.php +++ b/app/Infrastructure/Jobs/CheckYearPeriod.php @@ -8,6 +8,7 @@ use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Support\Carbon; +use Toby\Domain\Actions\CreateYearPeriodAction; use Toby\Eloquent\Models\YearPeriod; class CheckYearPeriod implements ShouldQueue @@ -15,30 +16,17 @@ class CheckYearPeriod implements ShouldQueue use Dispatchable; use Queueable; - public function handle(): void + public function handle(CreateYearPeriodAction $createYearPeriodAction): void { $currentYearPeriod = YearPeriod::current(); + $now = Carbon::now(); if ($currentYearPeriod === null) { - $this->createCurrentYearPeriod(); + $createYearPeriodAction->execute($now->year); } - if (YearPeriod::query()->max("year") === Carbon::now()->year) { - $this->createNextYearPeriod(); + if (YearPeriod::query()->max("year") === $now->year) { + $createYearPeriodAction->execute($now->year + 1); } } - - protected function createCurrentYearPeriod(): void - { - YearPeriod::query()->create([ - "year" => Carbon::now()->year, - ]); - } - - protected function createNextYearPeriod(): void - { - YearPeriod::query()->create([ - "year" => Carbon::now()->year + 1, - ]); - } } diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 8d58909..581ecfd 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -17,10 +17,6 @@ class DatabaseSeeder extends Seeder { public function run(): void { - User::unsetEventDispatcher(); - YearPeriod::unsetEventDispatcher(); - VacationRequest::unsetEventDispatcher(); - User::factory(9)->create(); User::factory([ "email" => env("LOCAL_EMAIL_FOR_LOGIN_VIA_GOOGLE"), diff --git a/database/seeders/DemoSeeder.php b/database/seeders/DemoSeeder.php index 7c1bb3c..4d50271 100644 --- a/database/seeders/DemoSeeder.php +++ b/database/seeders/DemoSeeder.php @@ -29,10 +29,6 @@ class DemoSeeder extends Seeder { public function run(): void { - User::unsetEventDispatcher(); - YearPeriod::unsetEventDispatcher(); - VacationRequest::unsetEventDispatcher(); - $user = User::factory([ "first_name" => "Jan", "last_name" => "Kowalski", diff --git a/resources/js/Pages/Calendar.vue b/resources/js/Pages/Calendar.vue index 6014f57..954399f 100644 --- a/resources/js/Pages/Calendar.vue +++ b/resources/js/Pages/Calendar.vue @@ -46,7 +46,7 @@