From 86f02dd937b02eb6c81177181e1adadbe25db23d Mon Sep 17 00:00:00 2001 From: EwelinaSkrzypacz Date: Thu, 5 Oct 2023 11:03:44 +0200 Subject: [PATCH] #354 - wip --- app/Domain/DailySummaryRetriever.php | 15 -- app/Eloquent/Models/User.php | 28 ++- .../EmployeesMilestonesController.php | 34 +++ .../Resources/EmployeeMilestoneResource.php | 32 +++ resources/js/Pages/EmployeesMilestones.vue | 206 ++++++++++++++++++ resources/js/Shared/MainMenu.vue | 9 + routes/web.php | 4 + 7 files changed, 310 insertions(+), 18 deletions(-) create mode 100644 app/Infrastructure/Http/Controllers/EmployeesMilestonesController.php create mode 100644 app/Infrastructure/Http/Resources/EmployeeMilestoneResource.php create mode 100644 resources/js/Pages/EmployeesMilestones.vue diff --git a/app/Domain/DailySummaryRetriever.php b/app/Domain/DailySummaryRetriever.php index 7bc0a3cd..7137cc7c 100644 --- a/app/Domain/DailySummaryRetriever.php +++ b/app/Domain/DailySummaryRetriever.php @@ -89,21 +89,6 @@ public function getUpcomingRemoteDays(Carbon $date): Collection ->get(); } - /** - * @return Collection - */ - public function getBirthdays(Carbon $date): Collection - { - return User::query() - ->whereRelation( - "profile", - fn(Builder $query): Builder => $query - ->whereMonth("birthday", $date->month) - ->whereDay("birthday", $date->day), - ) - ->get(); - } - /** * @return Collection */ diff --git a/app/Eloquent/Models/User.php b/app/Eloquent/Models/User.php index 0d403f30..63918daf 100644 --- a/app/Eloquent/Models/User.php +++ b/app/Eloquent/Models/User.php @@ -106,11 +106,11 @@ public function scopeSearch(Builder $query, ?string $text): Builder ); } - public function scopeOrderByProfileField(Builder $query, string $field): Builder + public function scopeOrderByProfileField(Builder $query, string $field, string $direction = 'asc'): Builder { $profileQuery = Profile::query()->select($field)->whereColumn("users.id", "profiles.user_id"); - return $query->orderBy($profileQuery); + return $query->orderBy($profileQuery, $direction); } public function scopeWithVacationLimitIn(Builder $query, YearPeriod $yearPeriod): Builder @@ -133,8 +133,12 @@ public function scopeStatus(Builder $query, ?string $status): Builder }; } - public function upcomingBirthday(): Carbon + public function upcomingBirthday(): ?Carbon { + if (!$this->profile->birthday) { + return null; + } + $today = Carbon::today(); $birthday = $this->profile->birthday->setYear($today->year); @@ -146,11 +150,29 @@ public function upcomingBirthday(): Carbon return $birthday; } + public function seniority(): string + { + return $this->profile->employment_date->longAbsoluteDiffForHumans(Carbon::today(), 2); + } + public function routeNotificationForSlack() { return $this->profile->slack_id; } + public function scopeSortForEmployeesMilestones(Builder $query, ?string $sort): Builder + { + return match ($sort) { +// "birthday-asc" TO DO +// "birthday-desc" TO DO + "seniority-asc" => $query->orderByProfileField('employment_date', 'asc'), + "seniority-desc" => $query->orderByProfileField('employment_date', 'desc'), + default => $query + ->orderByProfileField("last_name") + ->orderByProfileField("first_name"), + }; + } + protected static function newFactory(): UserFactory { return UserFactory::new(); diff --git a/app/Infrastructure/Http/Controllers/EmployeesMilestonesController.php b/app/Infrastructure/Http/Controllers/EmployeesMilestonesController.php new file mode 100644 index 00000000..25dd5b45 --- /dev/null +++ b/app/Infrastructure/Http/Controllers/EmployeesMilestonesController.php @@ -0,0 +1,34 @@ +query("search"); + $sort = $request->query("sort"); + + $users = User::query() + ->sortForEmployeesMilestones($sort) + ->search($searchText) + ->orderByProfileField("last_name") + ->orderByProfileField("first_name") + ->paginate() + ->withQueryString(); + + return inertia("EmployeesMilestones", [ + "users" => EmployeeMilestoneResource::collection($users), + "filters" => [ + "search" => $searchText, + ], + ]); + } +} diff --git a/app/Infrastructure/Http/Resources/EmployeeMilestoneResource.php b/app/Infrastructure/Http/Resources/EmployeeMilestoneResource.php new file mode 100644 index 00000000..02112326 --- /dev/null +++ b/app/Infrastructure/Http/Resources/EmployeeMilestoneResource.php @@ -0,0 +1,32 @@ +upcomingBirthday(); + $seniority = $this->seniority(); + + return [ + "user" => new SimpleUserResource($this->resource), + "birthdayDisplayDate" => $upcomingBirthday?->toDisplayString(), + "birthdayRelativeDate" => $upcomingBirthday?->isToday() + ? __("today") + : $upcomingBirthday?->diffForHumans( + Carbon::today(), + ["options" => CarbonInterface::ONE_DAY_WORDS, "syntax" => CarbonInterface::DIFF_RELATIVE_TO_NOW], + ), + "seniorityDisplayDate" => $seniority, + ]; + } +} diff --git a/resources/js/Pages/EmployeesMilestones.vue b/resources/js/Pages/EmployeesMilestones.vue new file mode 100644 index 00000000..dc32b4d7 --- /dev/null +++ b/resources/js/Pages/EmployeesMilestones.vue @@ -0,0 +1,206 @@ + + + \ No newline at end of file diff --git a/resources/js/Shared/MainMenu.vue b/resources/js/Shared/MainMenu.vue index 6b6a51c1..182dd254 100644 --- a/resources/js/Shared/MainMenu.vue +++ b/resources/js/Shared/MainMenu.vue @@ -28,8 +28,10 @@ import { GiftIcon, BanknotesIcon, DocumentDuplicateIcon, + CakeIcon, } from '@heroicons/vue/24/outline' import { CheckIcon, ChevronDownIcon } from '@heroicons/vue/24/solid' +import EmployeesMilestones from "@/Pages/EmployeesMilestones.vue"; const props = defineProps({ auth: Object, @@ -101,6 +103,13 @@ const miscNavigation = computed(() => [ icon: UserGroupIcon, can: props.auth.can.manageUsers, }, + { + name: 'Jubileusze', + href: '/employees-milestones', + section: 'EmployeesMilestones', + icon: CakeIcon, + can: true, + }, { name: 'Klucze', href: '/keys', diff --git a/routes/web.php b/routes/web.php index 6dd4ab64..fa7ebddc 100644 --- a/routes/web.php +++ b/routes/web.php @@ -8,6 +8,7 @@ use Toby\Infrastructure\Http\Controllers\BenefitController; use Toby\Infrastructure\Http\Controllers\BenefitsReportController; use Toby\Infrastructure\Http\Controllers\DashboardController; +use Toby\Infrastructure\Http\Controllers\EmployeesMilestonesController; use Toby\Infrastructure\Http\Controllers\GoogleController; use Toby\Infrastructure\Http\Controllers\HolidayController; use Toby\Infrastructure\Http\Controllers\KeysController; @@ -85,6 +86,9 @@ Route::post("/keys/{key}/give", [KeysController::class, "give"]); Route::post("/keys/{key}/leave-in-the-office", [KeysController::class, "leaveInTheOffice"]); + Route::get("/employees-milestones", [EmployeesMilestonesController::class, "index"]) + ->name("employees-milestones"); + Route::post("/year-periods/{yearPeriod}/select", SelectYearPeriodController::class) ->whereNumber("yearPeriod") ->name("year-periods.select");