vacations() ->whereBelongsTo($yearPeriod) ->whereRelation( "vacationRequest", fn(Builder $query): Builder => $query ->whereIn("type", $this->getLimitableVacationTypes()) ->states(VacationRequestStatesRetriever::successStates()), ) ->count(); } public function getUsedVacationDaysByMonth(User $user, YearPeriod $yearPeriod): Collection { return $user->vacations() ->whereBelongsTo($yearPeriod) ->whereRelation( "vacationRequest", fn(Builder $query): Builder => $query ->whereIn("type", $this->getLimitableVacationTypes()) ->states(VacationRequestStatesRetriever::successStates()), ) ->get() ->groupBy(fn(Vacation $vacation): string => strtolower($vacation->date->englishMonth)) ->map(fn(Collection $items): int => $items->count()); } public function getPendingVacationDays(User $user, YearPeriod $yearPeriod): int { return $user ->vacations() ->whereBelongsTo($yearPeriod) ->whereRelation( "vacationRequest", fn(Builder $query): Builder => $query ->whereIn("type", $this->getLimitableVacationTypes()) ->states(VacationRequestStatesRetriever::pendingStates()), ) ->count(); } public function getOtherApprovedVacationDays(User $user, YearPeriod $yearPeriod): int { return $user ->vacations() ->whereBelongsTo($yearPeriod) ->whereRelation( "vacationRequest", fn(Builder $query): Builder => $query ->whereIn("type", $this->getNotLimitableVacationTypes()) ->whereNot("type", VacationType::HomeOffice) ->states(VacationRequestStatesRetriever::successStates()), ) ->count(); } public function getHomeOfficeDays(User $user, YearPeriod $yearPeriod): int { return $user ->vacations() ->whereBelongsTo($yearPeriod) ->whereRelation("vacationRequest", "type", VacationType::HomeOffice) ->count(); } public function getRemainingVacationDays(User $user, YearPeriod $yearPeriod): int { $limit = $this->getVacationDaysLimit($user, $yearPeriod); $used = $this->getUsedVacationDays($user, $yearPeriod); $pending = $this->getPendingVacationDays($user, $yearPeriod); return $limit - $used - $pending; } public function getVacationDaysLimit(User $user, YearPeriod $yearPeriod): int { $limit = $user->vacationLimits() ->whereBelongsTo($yearPeriod) ->first() ?->days; return $limit ?? 0; } public function hasVacationDaysLimit(User $user, YearPeriod $yearPeriod): bool { $limit = $user->vacationLimits() ->whereBelongsTo($yearPeriod) ->first()?->days; return $limit !== null; } protected function getLimitableVacationTypes(): Collection { $types = VacationType::all(); return $types->filter(fn(VacationType $type): bool => $this->configRetriever->hasLimit($type)); } protected function getNotLimitableVacationTypes(): Collection { $types = VacationType::all(); return $types->filter(fn(VacationType $type): bool => !$this->configRetriever->hasLimit($type)); } }