diff --git a/app/Architecture/Providers/AppServiceProvider.php b/app/Architecture/Providers/AppServiceProvider.php index 59841af..d7e58c9 100644 --- a/app/Architecture/Providers/AppServiceProvider.php +++ b/app/Architecture/Providers/AppServiceProvider.php @@ -6,6 +6,7 @@ namespace Toby\Architecture\Providers; use Illuminate\Support\Carbon; use Illuminate\Support\ServiceProvider; +use Toby\Eloquent\Models\Holiday; use Toby\Eloquent\Models\VacationLimit; use Toby\Eloquent\Scopes\SelectedYearPeriodScope; @@ -15,6 +16,9 @@ class AppServiceProvider extends ServiceProvider { Carbon::macro("toDisplayString", fn() => $this->translatedFormat("j F Y")); - VacationLimit::addGlobalScope($this->app->make(SelectedYearPeriodScope::class)); + $selectedYearPeriodScope = $this->app->make(SelectedYearPeriodScope::class); + + VacationLimit::addGlobalScope($selectedYearPeriodScope); + Holiday::addGlobalScope($selectedYearPeriodScope); } } diff --git a/app/Domain/PolishHolidaysRetriever.php b/app/Domain/PolishHolidaysRetriever.php new file mode 100644 index 0000000..db574a4 --- /dev/null +++ b/app/Domain/PolishHolidaysRetriever.php @@ -0,0 +1,34 @@ +year); + + $holidays = $polishProvider->getHolidays(); + + return $this->prepareHolidays($holidays); + } + + protected function prepareHolidays(array $holidays): Collection + { + return collect($holidays)->map(fn(Holiday $holiday) => [ + "name" => $holiday->getName([static::LANG_KEY]), + "date" => Carbon::createFromTimestamp($holiday->getTimestamp()), + ])->values(); + } +} diff --git a/app/Eloquent/Models/Holiday.php b/app/Eloquent/Models/Holiday.php new file mode 100644 index 0000000..be8ae49 --- /dev/null +++ b/app/Eloquent/Models/Holiday.php @@ -0,0 +1,38 @@ + "date", + ]; + + public function yearPeriod(): BelongsTo + { + return $this->belongsTo(YearPeriod::class); + } + + protected static function newFactory(): HolidayFactory + { + return HolidayFactory::new(); + } +} diff --git a/app/Eloquent/Models/User.php b/app/Eloquent/Models/User.php index b76f347..d0ad551 100644 --- a/app/Eloquent/Models/User.php +++ b/app/Eloquent/Models/User.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Toby\Eloquent\Models; +use Database\Factories\UserFactory; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -34,7 +35,7 @@ class User extends Authenticatable protected $casts = [ "employment_form" => EmploymentForm::class, - "employment_date" => "datetime", + "employment_date" => "date", ]; protected $hidden = [ @@ -69,4 +70,9 @@ class User extends Authenticatable { return "{$this->first_name} {$this->last_name}"; } + + protected static function newFactory(): UserFactory + { + return UserFactory::new(); + } } diff --git a/app/Eloquent/Models/VacationLimit.php b/app/Eloquent/Models/VacationLimit.php index b1343ae..f7e3208 100644 --- a/app/Eloquent/Models/VacationLimit.php +++ b/app/Eloquent/Models/VacationLimit.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Toby\Eloquent\Models; +use Database\Factories\VacationLimitFactory; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -42,4 +43,9 @@ class VacationLimit extends Model return $query->orderBy($userQuery); } + + protected static function newFactory(): VacationLimitFactory + { + return VacationLimitFactory::new(); + } } diff --git a/app/Eloquent/Models/YearPeriod.php b/app/Eloquent/Models/YearPeriod.php index 31874da..ae57938 100644 --- a/app/Eloquent/Models/YearPeriod.php +++ b/app/Eloquent/Models/YearPeriod.php @@ -4,29 +4,34 @@ declare(strict_types=1); namespace Toby\Eloquent\Models; -use Carbon\Carbon; +use Database\Factories\YearPeriodFactory; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Support\Carbon; use Illuminate\Support\Collection; /** * @property int $id * @property int $year * @property Collection $vacationLimits + * @property Collection $holidays */ class YearPeriod extends Model { use HasFactory; - protected $fillable = [ - "year", - ]; + protected $guarded = []; public static function current(): ?static + { + return static::findByYear(Carbon::now()->year); + } + + public static function findByYear(int $year): ?static { /** @var YearPeriod $year */ - $year = static::query()->where("year", Carbon::now()->year)->first(); + $year = static::query()->where("year", $year)->first(); return $year; } @@ -35,4 +40,14 @@ class YearPeriod extends Model { return $this->hasMany(VacationLimit::class); } + + public function holidays(): HasMany + { + return $this->hasMany(Holiday::class); + } + + protected static function newFactory(): YearPeriodFactory + { + return YearPeriodFactory::new(); + } } diff --git a/app/Eloquent/Observers/YearPeriodObserver.php b/app/Eloquent/Observers/YearPeriodObserver.php index 6aa44af..e95210a 100644 --- a/app/Eloquent/Observers/YearPeriodObserver.php +++ b/app/Eloquent/Observers/YearPeriodObserver.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Toby\Eloquent\Observers; +use Toby\Domain\PolishHolidaysRetriever; use Toby\Eloquent\Helpers\UserAvatarGenerator; use Toby\Eloquent\Models\User; use Toby\Eloquent\Models\YearPeriod; @@ -12,10 +13,17 @@ class YearPeriodObserver { public function __construct( protected UserAvatarGenerator $generator, + protected PolishHolidaysRetriever $polishHolidaysRetriever, ) { } public function created(YearPeriod $yearPeriod): void + { + $this->createVacationLimitsFor($yearPeriod); + $this->createHolidaysFor($yearPeriod); + } + + protected function createVacationLimitsFor(YearPeriod $yearPeriod): void { $users = User::all(); @@ -25,4 +33,16 @@ class YearPeriodObserver ]); } } + + protected function createHolidaysFor(YearPeriod $yearPeriod): void + { + $holidays = $this->polishHolidaysRetriever->getForYearPeriod($yearPeriod); + + foreach ($holidays as $holiday) { + $yearPeriod->holidays()->create([ + "name" => $holiday["name"], + "date" => $holiday["date"], + ]); + } + } } diff --git a/app/Infrastructure/Http/Controllers/HolidayController.php b/app/Infrastructure/Http/Controllers/HolidayController.php new file mode 100644 index 0000000..e69a8ff --- /dev/null +++ b/app/Infrastructure/Http/Controllers/HolidayController.php @@ -0,0 +1,65 @@ +orderBy("date") + ->get(); + + return inertia("Holidays/Index", [ + "holidays" => HolidayResource::collection($holidays), + ]); + } + + public function create(): Response + { + return inertia("Holidays/Create"); + } + + public function store(HolidayRequest $request): RedirectResponse + { + Holiday::query()->create($request->data()); + + return redirect() + ->route("holidays.index") + ->with("success", __("Holiday has been created")); + } + + public function edit(Holiday $holiday): Response + { + return inertia("Holidays/Edit", [ + "holiday" => new HolidayFormDataResource($holiday), + ]); + } + + public function update(HolidayRequest $request, Holiday $holiday): RedirectResponse + { + $holiday->update($request->data()); + + return redirect() + ->route("holidays.index") + ->with("success", __("Holiday has been updated")); + } + + public function destroy(Holiday $holiday): RedirectResponse + { + $holiday->delete(); + + return redirect() + ->route("holidays.index") + ->with("success", __("Holiday has been deleted")); + } +} diff --git a/app/Infrastructure/Http/Requests/HolidayRequest.php b/app/Infrastructure/Http/Requests/HolidayRequest.php new file mode 100644 index 0000000..68619ce --- /dev/null +++ b/app/Infrastructure/Http/Requests/HolidayRequest.php @@ -0,0 +1,37 @@ + ["required", "min:3", "max:150"], + "date" => ["required", + "date_format:Y-m-d", + Rule::unique("holidays", "date")->ignore($this->holiday), + new YearPeriodExists(), + ], + ]; + } + + public function data(): array + { + $date = $this->get("date"); + + return [ + "name" => $this->get("name"), + "date" => $date, + "year_period_id" => YearPeriod::findByYear(Carbon::create($date)->year)->id, + ]; + } +} diff --git a/app/Infrastructure/Http/Requests/UserRequest.php b/app/Infrastructure/Http/Requests/UserRequest.php index 9321bc8..1d4a63a 100644 --- a/app/Infrastructure/Http/Requests/UserRequest.php +++ b/app/Infrastructure/Http/Requests/UserRequest.php @@ -18,7 +18,7 @@ class UserRequest extends FormRequest "lastName" => ["required", "min:3", "max:80"], "email" => ["required", "email", Rule::unique("users", "email")->ignore($this->user)], "employmentForm" => ["required", new Enum(EmploymentForm::class)], - "employmentDate" => ["required", "date"], + "employmentDate" => ["required", "date_format:Y-m-d"], ]; } diff --git a/app/Infrastructure/Http/Resources/HolidayFormDataResource.php b/app/Infrastructure/Http/Resources/HolidayFormDataResource.php new file mode 100644 index 0000000..365a051 --- /dev/null +++ b/app/Infrastructure/Http/Resources/HolidayFormDataResource.php @@ -0,0 +1,21 @@ + $this->id, + "name" => $this->name, + "date" => $this->date->toDateString(), + ]; + } +} diff --git a/app/Infrastructure/Http/Resources/HolidayResource.php b/app/Infrastructure/Http/Resources/HolidayResource.php new file mode 100644 index 0000000..c6f4e1a --- /dev/null +++ b/app/Infrastructure/Http/Resources/HolidayResource.php @@ -0,0 +1,22 @@ + $this->id, + "name" => $this->name, + "displayDate" => $this->date->toDisplayString(), + "dayOfWeek" => $this->date->dayName, + ]; + } +} diff --git a/app/Infrastructure/Http/Rules/YearPeriodExists.php b/app/Infrastructure/Http/Rules/YearPeriodExists.php new file mode 100644 index 0000000..d6f9677 --- /dev/null +++ b/app/Infrastructure/Http/Rules/YearPeriodExists.php @@ -0,0 +1,24 @@ +year); + + return $yearPeriod !== null; + } + + public function message(): string + { + return "The year period for given year doesn't exist."; + } +} diff --git a/composer.json b/composer.json index 3d13d3f..b464c21 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "require": { "php": "^8.1", "ext-pdo": "*", + "azuyalabs/yasumi": "^2.4", "fruitcake/laravel-cors": "^2.0", "guzzlehttp/guzzle": "^7.0.1", "inertiajs/inertia-laravel": "^0.5.1", diff --git a/composer.lock b/composer.lock index bc06f33..7984d2b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3412dd2a403927b829237ae4db36351a", + "content-hash": "e3c6ffae4c01db02d0471c52d2370b79", "packages": [ { "name": "asm89/stack-cors", @@ -62,6 +62,79 @@ }, "time": "2022-01-18T09:12:03+00:00" }, + { + "name": "azuyalabs/yasumi", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/azuyalabs/yasumi.git", + "reference": "083a0d0579fee17e68d688d463bc01098ac2691f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/azuyalabs/yasumi/zipball/083a0d0579fee17e68d688d463bc01098ac2691f", + "reference": "083a0d0579fee17e68d688d463bc01098ac2691f", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=7.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16", + "infection/infection": "^0.17 | ^0.22", + "mikey179/vfsstream": "^1.6", + "phan/phan": "^4.0", + "phpstan/phpstan": "^0.12.66", + "phpunit/phpunit": "^8.5 | ^9.4", + "vimeo/psalm": "^4" + }, + "suggest": { + "ext-calendar": "For calculating the date of Easter" + }, + "type": "library", + "autoload": { + "psr-4": { + "Yasumi\\": "src/Yasumi/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sacha Telgenhof", + "email": "me@sachatelgenhof.com", + "role": "Maintainer" + } + ], + "description": "The easy PHP Library for calculating holidays.", + "homepage": "https://www.yasumi.dev", + "keywords": [ + "Bank", + "calculation", + "calendar", + "celebration", + "date", + "holiday", + "holidays", + "national", + "time" + ], + "support": { + "docs": "https://www.yasumi.dev", + "issues": "https://github.com/azuyalabs/yasumi/issues", + "source": "https://github.com/azuyalabs/yasumi" + }, + "funding": [ + { + "url": "https://www.buymeacoffee.com/sachatelgenhof", + "type": "other" + } + ], + "time": "2021-05-09T09:03:34+00:00" + }, { "name": "brick/math", "version": "0.9.3", diff --git a/database/factories/HolidayFactory.php b/database/factories/HolidayFactory.php new file mode 100644 index 0000000..cab499a --- /dev/null +++ b/database/factories/HolidayFactory.php @@ -0,0 +1,23 @@ + $this->faker->word, + "date" => $this->faker->unique->date, + "year_period_id" => YearPeriod::current()->id, + ]; + } +} diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 426ec66..5bab4c5 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -5,11 +5,15 @@ declare(strict_types=1); namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; +use Illuminate\Support\Carbon; use Illuminate\Support\Str; -use Toby\Enums\EmploymentForm; +use Toby\Domain\EmploymentForm; +use Toby\Eloquent\Models\User; class UserFactory extends Factory { + protected $model = User::class; + public function definition(): array { return [ @@ -17,7 +21,7 @@ class UserFactory extends Factory "last_name" => $this->faker->lastName(), "email" => $this->faker->unique()->safeEmail(), "employment_form" => $this->faker->randomElement(EmploymentForm::cases()), - "employment_date" => $this->faker->dateTimeBetween("2020-10-27"), + "employment_date" => Carbon::createFromInterface($this->faker->dateTimeBetween("2020-10-27"))->toDateString(), "remember_token" => Str::random(10), ]; } diff --git a/database/factories/VacationLimitFactory.php b/database/factories/VacationLimitFactory.php index 543720a..f4fcc14 100644 --- a/database/factories/VacationLimitFactory.php +++ b/database/factories/VacationLimitFactory.php @@ -5,11 +5,14 @@ declare(strict_types=1); namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; -use Toby\Models\User; -use Toby\Models\YearPeriod; +use Toby\Eloquent\Models\User; +use Toby\Eloquent\Models\VacationLimit; +use Toby\Eloquent\Models\YearPeriod; class VacationLimitFactory extends Factory { + protected $model = VacationLimit::class; + public function definition(): array { $hasVacation = $this->faker->boolean(75); diff --git a/database/factories/YearPeriodFactory.php b/database/factories/YearPeriodFactory.php index 2437dd3..7e9eb37 100644 --- a/database/factories/YearPeriodFactory.php +++ b/database/factories/YearPeriodFactory.php @@ -5,13 +5,16 @@ declare(strict_types=1); namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; +use Toby\Eloquent\Models\YearPeriod; class YearPeriodFactory extends Factory { + protected $model = YearPeriod::class; + public function definition(): array { return [ - "year" => $this->faker->unique()->year, + "year" => (int)$this->faker->unique()->year, ]; } } diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index f1bc601..b782864 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -16,7 +16,7 @@ return new class() extends Migration { $table->string("email")->unique(); $table->string("avatar")->nullable(); $table->string("employment_form"); - $table->dateTime("employment_date"); + $table->date("employment_date"); $table->rememberToken(); $table->softDeletes(); $table->timestamps(); diff --git a/database/migrations/2022_01_19_140630_create_vacation_limits_table.php b/database/migrations/2022_01_19_140630_create_vacation_limits_table.php index c2b29d5..45d6fa6 100644 --- a/database/migrations/2022_01_19_140630_create_vacation_limits_table.php +++ b/database/migrations/2022_01_19_140630_create_vacation_limits_table.php @@ -5,8 +5,8 @@ declare(strict_types=1); use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -use Toby\Models\User; -use Toby\Models\YearPeriod; +use Toby\Eloquent\Models\User; +use Toby\Eloquent\Models\YearPeriod; return new class() extends Migration { public function up(): void diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2022_01_20_140544_create_holidays_table.php similarity index 53% rename from database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php rename to database/migrations/2022_01_20_140544_create_holidays_table.php index ee820cf..e7a9b58 100644 --- a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php +++ b/database/migrations/2022_01_20_140544_create_holidays_table.php @@ -5,23 +5,22 @@ declare(strict_types=1); use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; +use Toby\Eloquent\Models\YearPeriod; return new class() extends Migration { public function up(): void { - Schema::create("personal_access_tokens", function (Blueprint $table): void { + Schema::create("holidays", function (Blueprint $table): void { $table->id(); - $table->morphs("tokenable"); + $table->foreignIdFor(YearPeriod::class)->constrained()->cascadeOnDelete(); $table->string("name"); - $table->string("token", 64)->unique(); - $table->text("abilities")->nullable(); - $table->timestamp("last_used_at")->nullable(); + $table->date("date")->unique(); $table->timestamps(); }); } public function down(): void { - Schema::dropIfExists("personal_access_tokens"); + Schema::dropIfExists("holidays"); } }; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index d6a4f27..2c72709 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -7,10 +7,11 @@ namespace Database\Seeders; use Illuminate\Database\Seeder; use Illuminate\Support\Carbon; use Illuminate\Support\Collection; -use Toby\Helpers\UserAvatarGenerator; -use Toby\Models\User; -use Toby\Models\VacationLimit; -use Toby\Models\YearPeriod; +use Toby\Domain\PolishHolidaysRetriever; +use Toby\Eloquent\Helpers\UserAvatarGenerator; +use Toby\Eloquent\Models\User; +use Toby\Eloquent\Models\VacationLimit; +use Toby\Eloquent\Models\YearPeriod; class DatabaseSeeder extends Seeder { @@ -54,6 +55,16 @@ class DatabaseSeeder extends Seeder ->create(); } }) + ->afterCreating(function (YearPeriod $yearPeriod): void { + $polishHolidaysRetriever = new PolishHolidaysRetriever(); + + foreach ($polishHolidaysRetriever->getForYearPeriod($yearPeriod) as $holiday) { + $yearPeriod->holidays()->create([ + "name" => $holiday["name"], + "date" => $holiday["date"], + ]); + } + }) ->create(); } diff --git a/resources/js/Pages/Holidays/Create.vue b/resources/js/Pages/Holidays/Create.vue new file mode 100644 index 0000000..70b8bea --- /dev/null +++ b/resources/js/Pages/Holidays/Create.vue @@ -0,0 +1,106 @@ + + + diff --git a/resources/js/Pages/Holidays/Edit.vue b/resources/js/Pages/Holidays/Edit.vue new file mode 100644 index 0000000..5dbd100 --- /dev/null +++ b/resources/js/Pages/Holidays/Edit.vue @@ -0,0 +1,113 @@ + + + diff --git a/resources/js/Pages/Holidays/Index.vue b/resources/js/Pages/Holidays/Index.vue new file mode 100644 index 0000000..3999192 --- /dev/null +++ b/resources/js/Pages/Holidays/Index.vue @@ -0,0 +1,167 @@ + + + diff --git a/resources/js/Pages/Users/Create.vue b/resources/js/Pages/Users/Create.vue index 8f9bacd..1478b4e 100644 --- a/resources/js/Pages/Users/Create.vue +++ b/resources/js/Pages/Users/Create.vue @@ -211,7 +211,7 @@ export default { lastName: null, email: null, employmentForm: props.employmentForms[0], - employmentDate: new Date(), + employmentDate: null, }); return { form }; diff --git a/resources/js/Pages/Users/Edit.vue b/resources/js/Pages/Users/Edit.vue index 771c001..a58e49a 100644 --- a/resources/js/Pages/Users/Edit.vue +++ b/resources/js/Pages/Users/Edit.vue @@ -215,7 +215,7 @@ export default { lastName: props.user.lastName, email: props.user.email, employmentForm: props.employmentForms.find(form => form.value === props.user.employmentForm), - employmentDate: new Date(props.user.employmentDate), + employmentDate: props.user.employmentDate, }); return { form }; diff --git a/resources/js/Shared/MainMenu.vue b/resources/js/Shared/MainMenu.vue index 4966645..ac465eb 100644 --- a/resources/js/Shared/MainMenu.vue +++ b/resources/js/Shared/MainMenu.vue @@ -322,8 +322,7 @@ export default { {name: 'Strona główna', href: '/', current: true}, {name: 'Użytkownicy', href: '/users', current: false}, {name: 'Dostępne urlopy', href: '/vacation-limits', current: false}, - {name: 'Company Directory', href: '#', current: false}, - {name: 'Openings', href: '#', current: false}, + {name: 'Dni wolne', href: '/holidays', current: false}, ]; const userNavigation = [ {name: 'Your Profile', href: '#'}, diff --git a/routes/web.php b/routes/web.php index acd4d43..b30c103 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,18 +3,21 @@ declare(strict_types=1); use Illuminate\Support\Facades\Route; -use Toby\Http\Controllers\GoogleController; -use Toby\Http\Controllers\LogoutController; -use Toby\Http\Controllers\SelectYearPeriodController; -use Toby\Http\Controllers\UserController; -use Toby\Http\Controllers\VacationLimitController; +use Toby\Infrastructure\Http\Controllers\GoogleController; +use Toby\Infrastructure\Http\Controllers\HolidayController; +use Toby\Infrastructure\Http\Controllers\LogoutController; +use Toby\Infrastructure\Http\Controllers\SelectYearPeriodController; +use Toby\Infrastructure\Http\Controllers\UserController; +use Toby\Infrastructure\Http\Controllers\VacationLimitController; Route::middleware("auth")->group(function (): void { Route::get("/", fn() => inertia("Dashboard"))->name("dashboard"); Route::post("/logout", LogoutController::class); Route::resource("users", UserController::class); - Route::post("users/{user}/restore", [UserController::class, "restore"])->withTrashed(); + Route::post("/users/{user}/restore", [UserController::class, "restore"])->withTrashed(); + + Route::resource("holidays", HolidayController::class); Route::get("/vacation-limits", [VacationLimitController::class, "edit"])->name("vacation.limits"); Route::put("/vacation-limits", [VacationLimitController::class, "update"]); diff --git a/tests/Feature/HolidayTest.php b/tests/Feature/HolidayTest.php new file mode 100644 index 0000000..7f96a7f --- /dev/null +++ b/tests/Feature/HolidayTest.php @@ -0,0 +1,127 @@ +count(10)->create(); + $user = User::factory()->create(); + + $this->assertDatabaseCount("holidays", 10); + + $this->actingAs($user) + ->get("/holidays") + ->assertInertia( + fn(Assert $page) => $page + ->component("Holidays/Index") + ->has("holidays.data", 10), + ); + } + + public function testAdminCanCreateHoliday(): void + { + $admin = User::factory()->create(); + $currentYearPeriod = YearPeriod::current(); + + $this->actingAs($admin) + ->post("/holidays", [ + "name" => "Holiday 1", + "date" => Carbon::create($currentYearPeriod->year, 5, 20)->toDateString(), + ]) + ->assertSessionHasNoErrors(); + + $this->assertDatabaseHas("holidays", [ + "name" => "Holiday 1", + "date" => Carbon::create($currentYearPeriod->year, 5, 20), + "year_period_id" => YearPeriod::current()->id, + ]); + } + + public function testAdminCannotCreateHolidayForYearPeriodThatDoesntExist(): void + { + $admin = User::factory()->create(); + $year = YearPeriod::query()->max("year") + 1; + + $this->actingAs($admin) + ->post("/holidays", [ + "name" => "Holiday 1", + "date" => Carbon::create($year, 5, 20)->toDateString(), + ]) + ->assertSessionHasErrors(["date"]); + } + + public function testAdminCannotCreateHolidayIfGivenDataIsUsed(): void + { + $admin = User::factory()->create(); + $currentYearPeriod = YearPeriod::current(); + $sameDate = Carbon::create($currentYearPeriod->year, 5, 20)->toDateString(); + + Holiday::factory()->create([ + "name" => "Holiday", + "date" => $sameDate, + ]); + + $this->actingAs($admin) + ->post("/holidays", [ + "name" => "Holiday 1", + "date" => $sameDate, + ]) + ->assertSessionHasErrors(["date"]); + } + + public function testAdminCanEditHoliday(): void + { + $admin = User::factory()->create(); + $currentYearPeriod = YearPeriod::current(); + + $holiday = Holiday::factory()->create([ + "name" => "Name to change", + "date" => Carbon::create($currentYearPeriod->year, 5, 20), + ]); + + $this->assertDatabaseHas("holidays", [ + "name" => $holiday->name, + "date" => $holiday->date->toDateString(), + "year_period_id" => $currentYearPeriod->id, + ]); + + $this->actingAs($admin) + ->put("/holidays/{$holiday->id}", [ + "name" => "Holiday 1", + "date" => Carbon::create($currentYearPeriod->year, 10, 25)->toDateString(), + ]) + ->assertSessionHasNoErrors(); + + $this->assertDatabaseHas("holidays", [ + "name" => "Holiday 1", + "date" => Carbon::create($currentYearPeriod->year, 10, 25)->toDateString(), + "year_period_id" => $currentYearPeriod->id, + ]); + } + + public function testAdminCanDeleteHoliday(): void + { + $admin = User::factory()->create(); + $holiday = Holiday::factory()->create(); + + $this->actingAs($admin) + ->delete("/holidays/{$holiday->id}") + ->assertSessionHasNoErrors(); + + $this->assertDeleted($holiday); + } +} diff --git a/tests/Feature/UserTest.php b/tests/Feature/UserTest.php index 5738b51..2914c97 100644 --- a/tests/Feature/UserTest.php +++ b/tests/Feature/UserTest.php @@ -34,21 +34,21 @@ class UserTest extends FeatureTestCase public function testAdminCanSearchUsersList(): void { User::factory([ - "first_name" => "Test", - "last_name" => "User1", - ])->create(); + "first_name" => "Test", + "last_name" => "User1", + ])->create(); User::factory([ - "first_name" => "Test", - "last_name" => "User2", - ])->create(); + "first_name" => "Test", + "last_name" => "User2", + ])->create(); User::factory([ - "first_name" => "Test", - "last_name" => "User3", - ])->create(); + "first_name" => "Test", + "last_name" => "User3", + ])->create(); $admin = User::factory([ - "first_name" => "John", - "last_name" => "Doe", - ])->create(); + "first_name" => "John", + "last_name" => "Doe", + ])->create(); $this->assertDatabaseCount("users", 4); @@ -89,7 +89,7 @@ class UserTest extends FeatureTestCase "lastName" => "Doe", "email" => "john.doe@example.com", "employmentForm" => EmploymentForm::B2B_CONTRACT->value, - "employmentDate" => Carbon::now()->toDateTimeString(), + "employmentDate" => Carbon::now()->toDateString(), ]) ->assertSessionHasNoErrors(); @@ -98,7 +98,7 @@ class UserTest extends FeatureTestCase "last_name" => "Doe", "email" => "john.doe@example.com", "employment_form" => EmploymentForm::B2B_CONTRACT->value, - "employment_date" => Carbon::now()->toDateTimeString(), + "employment_date" => Carbon::now()->toDateString(), ]); } @@ -114,7 +114,7 @@ class UserTest extends FeatureTestCase "last_name" => $user->last_name, "email" => $user->email, "employment_form" => $user->employment_form->value, - "employment_date" => $user->employment_date->toDateTimeString(), + "employment_date" => $user->employment_date->toDateString(), ]); $this->actingAs($admin) @@ -123,7 +123,7 @@ class UserTest extends FeatureTestCase "lastName" => "Doe", "email" => "john.doe@example.com", "employmentForm" => EmploymentForm::B2B_CONTRACT->value, - "employmentDate" => Carbon::now()->toDateTimeString(), + "employmentDate" => Carbon::now()->toDateString(), ]) ->assertSessionHasNoErrors(); @@ -132,7 +132,7 @@ class UserTest extends FeatureTestCase "last_name" => "Doe", "email" => "john.doe@example.com", "employment_form" => EmploymentForm::B2B_CONTRACT->value, - "employment_date" => Carbon::now()->toDateTimeString(), + "employment_date" => Carbon::now()->toDateString(), ]); } diff --git a/tests/Traits/InteractsWithYearPeriods.php b/tests/Traits/InteractsWithYearPeriods.php index 982cc7f..6c84de2 100644 --- a/tests/Traits/InteractsWithYearPeriods.php +++ b/tests/Traits/InteractsWithYearPeriods.php @@ -16,7 +16,7 @@ trait InteractsWithYearPeriods public function createYearPeriod(int $year): YearPeriod { /** @var YearPeriod $yearPeriod */ - $yearPeriod = YearPeriod::factory()->create([ + $yearPeriod = YearPeriod::factory()->createQuietly([ "year" => $year, ]);