toby/app/Domain/UserVacationStatsRetriever.php
Adrian Hopek c69866bb52
#116 - integration with slack (#129)
* wip

* wip

* wip

* wip

* fix

* wip

* wip

* fix

* fix

* cs fix

* #116 - fix

* #116 - changed home-office icon

* Apply suggestions from code review

Co-authored-by: Krzysztof Rewak <krzysztof.rewak@gmail.com>

* #116 - cr fix

* #116 - cs fix

* #116 - cs fix

* Apply suggestions from code review

Co-authored-by: Ewelina Lasowy <56546832+EwelinaLasowy@users.noreply.github.com>

* #5 - bump codestyle

Co-authored-by: EwelinaLasowy <ewelina.lasowy@blumilk.pl>
Co-authored-by: Krzysztof Rewak <krzysztof.rewak@gmail.com>
Co-authored-by: Ewelina Lasowy <56546832+EwelinaLasowy@users.noreply.github.com>
2022-04-27 09:57:13 +02:00

120 lines
3.9 KiB
PHP

<?php
declare(strict_types=1);
namespace Toby\Domain;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
use Toby\Domain\Enums\VacationType;
use Toby\Eloquent\Models\User;
use Toby\Eloquent\Models\Vacation;
use Toby\Eloquent\Models\YearPeriod;
class UserVacationStatsRetriever
{
public function __construct(
protected VacationTypeConfigRetriever $configRetriever,
) {}
public function getUsedVacationDays(User $user, YearPeriod $yearPeriod): int
{
return $user
->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;
}
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));
}
}