From 5122b5b70be59ea605995b603de01ce4c45b5b7c Mon Sep 17 00:00:00 2001 From: Adrian Hopek Date: Tue, 5 Apr 2022 14:21:32 +0200 Subject: [PATCH] #108 - wip --- app/Domain/Enums/VacationType.php | 10 +++- app/Domain/UserVacationStatsRetriever.php | 4 +- app/Domain/VacationTypeConfigRetriever.php | 7 +++ .../Rules/DoesNotExceedLimitRule.php | 4 +- .../GetAvailableVacationTypesController.php | 33 +++++++++++ .../Controllers/VacationRequestController.php | 3 - .../Api/GetAvailableVacationTypesRequest.php | 17 ++++++ config/vacation_types.php | 48 ++++++++++++++++ resources/js/Pages/MonthlyUsage.vue | 2 +- resources/js/Pages/VacationLimits.vue | 2 +- resources/js/Pages/VacationRequest/Create.vue | 55 ++++++++++++------- resources/lang/pl.json | 1 + routes/api.php | 2 + 13 files changed, 157 insertions(+), 31 deletions(-) create mode 100644 app/Infrastructure/Http/Controllers/Api/GetAvailableVacationTypesController.php create mode 100644 app/Infrastructure/Http/Requests/Api/GetAvailableVacationTypesRequest.php diff --git a/app/Domain/Enums/VacationType.php b/app/Domain/Enums/VacationType.php index 63e2858..71bdd41 100644 --- a/app/Domain/Enums/VacationType.php +++ b/app/Domain/Enums/VacationType.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Toby\Domain\Enums; +use Illuminate\Support\Collection; + enum VacationType: string { case Vacation = "vacation"; @@ -15,6 +17,7 @@ enum VacationType: string case Volunteering = "volunteering_vacation"; case TimeInLieu = "time_in_lieu"; case Sick = "sick_vacation"; + case Absence = "absence"; public function label(): string { @@ -23,7 +26,7 @@ enum VacationType: string public static function casesToSelect(): array { - $cases = collect(VacationType::cases()); + $cases = VacationType::all(); return $cases->map( fn(VacationType $enum) => [ @@ -32,4 +35,9 @@ enum VacationType: string ], )->toArray(); } + + public static function all(): Collection + { + return new Collection(VacationType::cases()); + } } diff --git a/app/Domain/UserVacationStatsRetriever.php b/app/Domain/UserVacationStatsRetriever.php index dcf8c99..8d1e66d 100644 --- a/app/Domain/UserVacationStatsRetriever.php +++ b/app/Domain/UserVacationStatsRetriever.php @@ -95,14 +95,14 @@ class UserVacationStatsRetriever protected function getLimitableVacationTypes(): Collection { - $types = new Collection(VacationType::cases()); + $types = VacationType::all(); return $types->filter(fn(VacationType $type) => $this->configRetriever->hasLimit($type)); } protected function getNotLimitableVacationTypes(): Collection { - $types = new Collection(VacationType::cases()); + $types = VacationType::all(); return $types->filter(fn(VacationType $type) => !$this->configRetriever->hasLimit($type)); } diff --git a/app/Domain/VacationTypeConfigRetriever.php b/app/Domain/VacationTypeConfigRetriever.php index 47ed0ba..213fcc8 100644 --- a/app/Domain/VacationTypeConfigRetriever.php +++ b/app/Domain/VacationTypeConfigRetriever.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Toby\Domain; use Illuminate\Contracts\Config\Repository; +use Toby\Domain\Enums\EmploymentForm; use Toby\Domain\Enums\VacationType; class VacationTypeConfigRetriever @@ -13,6 +14,7 @@ class VacationTypeConfigRetriever public const KEY_ADMINISTRATIVE_APPROVAL = "administrative_approval"; public const KEY_BILLABLE = "billable"; public const KEY_HAS_LIMIT = "has_limit"; + public const KEY_AVAILABLE_FOR = "available_for"; public function __construct( protected Repository $config, @@ -38,6 +40,11 @@ class VacationTypeConfigRetriever return $this->getConfigFor($type)[static::KEY_HAS_LIMIT]; } + public function isAvailableFor(VacationType $type, EmploymentForm $employmentForm): bool + { + return in_array($employmentForm, $this->getConfigFor($type)[static::KEY_AVAILABLE_FOR], true); + } + protected function getConfigFor(VacationType $type): array { return $this->config->get("vacation_types.{$type->value}"); diff --git a/app/Domain/Validation/Rules/DoesNotExceedLimitRule.php b/app/Domain/Validation/Rules/DoesNotExceedLimitRule.php index 453c343..c835cf6 100644 --- a/app/Domain/Validation/Rules/DoesNotExceedLimitRule.php +++ b/app/Domain/Validation/Rules/DoesNotExceedLimitRule.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace Toby\Domain\Validation\Rules; use Illuminate\Database\Eloquent\Builder; -use Illuminate\Database\Eloquent\Collection; +use Illuminate\Support\Collection; use Toby\Domain\Enums\VacationType; use Toby\Domain\VacationDaysCalculator; use Toby\Domain\VacationRequestStatesRetriever; @@ -59,7 +59,7 @@ class DoesNotExceedLimitRule implements VacationRequestRule protected function getLimitableVacationTypes(): Collection { - $types = new Collection(VacationType::cases()); + $types = VacationType::all(); return $types->filter(fn(VacationType $type) => $this->configRetriever->hasLimit($type)); } diff --git a/app/Infrastructure/Http/Controllers/Api/GetAvailableVacationTypesController.php b/app/Infrastructure/Http/Controllers/Api/GetAvailableVacationTypesController.php new file mode 100644 index 0000000..20d923c --- /dev/null +++ b/app/Infrastructure/Http/Controllers/Api/GetAvailableVacationTypesController.php @@ -0,0 +1,33 @@ +find($request->get("user")); + + $types = VacationType::all() + ->filter(fn(VacationType $type) => $configRetriever->isAvailableFor($type, $user->employment_form)) + ->map(fn(VacationType $type) => [ + "label" => $type->label(), + "value" => $type->value, + ]) + ->values(); + + return new JsonResponse($types); + } +} diff --git a/app/Infrastructure/Http/Controllers/VacationRequestController.php b/app/Infrastructure/Http/Controllers/VacationRequestController.php index 6d1cf6d..4f3134e 100644 --- a/app/Infrastructure/Http/Controllers/VacationRequestController.php +++ b/app/Infrastructure/Http/Controllers/VacationRequestController.php @@ -158,10 +158,7 @@ class VacationRequestController extends Controller public function create(Request $request, YearPeriodRetriever $yearPeriodRetriever): Response { - $yearPeriod = $yearPeriodRetriever->selected(); - $users = User::query() - ->withVacationLimitIn($yearPeriod) ->orderBy("last_name") ->orderBy("first_name") ->get(); diff --git a/app/Infrastructure/Http/Requests/Api/GetAvailableVacationTypesRequest.php b/app/Infrastructure/Http/Requests/Api/GetAvailableVacationTypesRequest.php new file mode 100644 index 0000000..35f4bad --- /dev/null +++ b/app/Infrastructure/Http/Requests/Api/GetAvailableVacationTypesRequest.php @@ -0,0 +1,17 @@ + ["required", "exists:users,id"], + ]; + } +} diff --git a/config/vacation_types.php b/config/vacation_types.php index 45a5900..e9b4402 100644 --- a/config/vacation_types.php +++ b/config/vacation_types.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use Toby\Domain\Enums\EmploymentForm; use Toby\Domain\Enums\VacationType; use Toby\Domain\VacationTypeConfigRetriever; @@ -11,53 +12,100 @@ return [ VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true, VacationTypeConfigRetriever::KEY_BILLABLE => true, VacationTypeConfigRetriever::KEY_HAS_LIMIT => true, + VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [ + EmploymentForm::EmploymentContract, + ], ], VacationType::OnRequest->value => [ VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true, VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true, VacationTypeConfigRetriever::KEY_BILLABLE => true, VacationTypeConfigRetriever::KEY_HAS_LIMIT => true, + VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [ + EmploymentForm::EmploymentContract, + ], ], VacationType::TimeInLieu->value => [ VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => false, VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => false, VacationTypeConfigRetriever::KEY_BILLABLE => true, VacationTypeConfigRetriever::KEY_HAS_LIMIT => false, + VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [ + EmploymentForm::EmploymentContract, + ], ], VacationType::Sick->value => [ VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => false, VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true, VacationTypeConfigRetriever::KEY_BILLABLE => true, VacationTypeConfigRetriever::KEY_HAS_LIMIT => false, + VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [ + EmploymentForm::EmploymentContract, + ], ], VacationType::Unpaid->value => [ VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true, VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true, VacationTypeConfigRetriever::KEY_BILLABLE => false, VacationTypeConfigRetriever::KEY_HAS_LIMIT => false, + VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [ + EmploymentForm::EmploymentContract, + ], ], VacationType::Special->value => [ VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true, VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true, VacationTypeConfigRetriever::KEY_BILLABLE => false, VacationTypeConfigRetriever::KEY_HAS_LIMIT => false, + VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [ + EmploymentForm::EmploymentContract, + ], ], VacationType::Childcare->value => [ VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true, VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true, VacationTypeConfigRetriever::KEY_BILLABLE => false, VacationTypeConfigRetriever::KEY_HAS_LIMIT => false, + VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [ + EmploymentForm::EmploymentContract, + ], ], VacationType::Training->value => [ VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true, VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true, VacationTypeConfigRetriever::KEY_BILLABLE => true, VacationTypeConfigRetriever::KEY_HAS_LIMIT => false, + VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [ + EmploymentForm::EmploymentContract, + ], ], VacationType::Volunteering->value => [ VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true, VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true, VacationTypeConfigRetriever::KEY_BILLABLE => true, VacationTypeConfigRetriever::KEY_HAS_LIMIT => false, + VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [ + EmploymentForm::EmploymentContract, + ], + ], + VacationType::Volunteering->value => [ + VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true, + VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true, + VacationTypeConfigRetriever::KEY_BILLABLE => true, + VacationTypeConfigRetriever::KEY_HAS_LIMIT => false, + VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [ + EmploymentForm::EmploymentContract, + ], + ], + VacationType::Absence->value => [ + VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true, + VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => false, + VacationTypeConfigRetriever::KEY_BILLABLE => false, + VacationTypeConfigRetriever::KEY_HAS_LIMIT => false, + VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [ + EmploymentForm::CommissionContract, + EmploymentForm::B2bContract, + EmploymentForm::BoardMemberContract, + ], ], ]; diff --git a/resources/js/Pages/MonthlyUsage.vue b/resources/js/Pages/MonthlyUsage.vue index 3ef5e1d..0db17f2 100644 --- a/resources/js/Pages/MonthlyUsage.vue +++ b/resources/js/Pages/MonthlyUsage.vue @@ -4,7 +4,7 @@

- Wykorzystanie miesięczne urlopu wypoczynkowego + Wykorzystanie miesięczne urlopu

diff --git a/resources/js/Pages/VacationLimits.vue b/resources/js/Pages/VacationLimits.vue index 950c5d3..f525679 100644 --- a/resources/js/Pages/VacationLimits.vue +++ b/resources/js/Pages/VacationLimits.vue @@ -30,7 +30,7 @@ scope="col" class="py-3 px-4 text-xs font-semibold tracking-wider text-left text-gray-500 uppercase whitespace-nowrap" > - Posiada urlop? + Posiada limit?

- Złóż wniosek urlopowy + Złóż wniosek

- Rodzaj urlopu + Typ wniosku
- {{ form.vacationType.label }} - - - + + - + - Planowany urlop od + Data od
- Planowany urlop do + Data do
- Liczba dni urlopu + Liczba dni
@@ -303,10 +308,10 @@

- Urlop wypoczynkowy, dane dla: {{ form.user.name }} + Dane urlopowe dla: {{ form.user.name }} - Twoje dane o urlopie wypoczynkowym + Twoje dane o urlopie

@@ -330,7 +335,6 @@ import VacationChart from '@/Shared/VacationChart' const props = defineProps({ auth: Object, users: Object, - vacationTypes: Object, holidays: Object, can: Object, }) @@ -341,12 +345,13 @@ const form = useForm({ : props.auth.user, from: null, to: null, - vacationType: props.vacationTypes[0], + vacationType: null, comment: null, flowSkipped: false, }) const estimatedDays = ref([]) +const vacationTypes = ref([]) const stats = ref({ used: 0, @@ -372,8 +377,9 @@ const toInputConfig = reactive({ watch(() => form.user, user => { resetForm() - refreshVacationStats(user) + refreshAvailableTypes(user) refreshUnavailableDays(user) + refreshVacationStats(user) }, { immediate: true }) function createForm() { @@ -406,7 +412,7 @@ function onToChange(selectedDates, dateStr) { } function resetForm() { - form.reset('type', 'to', 'from', 'comment', 'flowSkipped') + form.reset('to', 'from', 'comment', 'flowSkipped') form.clearErrors() estimatedDays.value = [] } @@ -440,4 +446,11 @@ async function refreshUnavailableDays(user) { ] } +async function refreshAvailableTypes(user) { + const res = await axios.post('/api/vacation/get-available-vacation-types', { user: user.id }) + + vacationTypes.value = res.data + form.vacationType = vacationTypes.value[0] +} + diff --git a/resources/lang/pl.json b/resources/lang/pl.json index e4caa5e..ccb2c3d 100644 --- a/resources/lang/pl.json +++ b/resources/lang/pl.json @@ -14,6 +14,7 @@ "look_for_work_vacation": "Urlop na poszukiwanie pracy", "time_in_lieu": "Odbiór za święto", "sick_vacation": "Zwolnienie lekarskie", + "absence": "Nieobecność", "employee": "Pracownik", "administrator": "Administrator", "technical_approver": "Techniczny akceptujący", diff --git a/routes/api.php b/routes/api.php index db740ed..d76094c 100644 --- a/routes/api.php +++ b/routes/api.php @@ -6,9 +6,11 @@ use Illuminate\Support\Facades\Route; use Toby\Infrastructure\Http\Controllers\Api\CalculateUserUnavailableDaysController; use Toby\Infrastructure\Http\Controllers\Api\CalculateUserVacationStatsController; use Toby\Infrastructure\Http\Controllers\Api\CalculateVacationDaysController; +use Toby\Infrastructure\Http\Controllers\Api\GetAvailableVacationTypesController; Route::middleware("auth:sanctum")->group(function (): void { Route::post("vacation/calculate-days", CalculateVacationDaysController::class); Route::post("vacation/calculate-stats", CalculateUserVacationStatsController::class); Route::post("vacation/calculate-unavailable-days", CalculateUserUnavailableDaysController::class); + Route::post("vacation/get-available-vacation-types", GetAvailableVacationTypesController::class); });