Skip to content

Commit

Permalink
#479 - number of working hours (#480)
Browse files Browse the repository at this point in the history
* #479 - feat: added working hours for specific month on calendar view

* #479 - fix: fixed user method

* #479 - feat: added config for employment contract working hours
  • Loading branch information
kamilpiech97 authored Aug 8, 2024
1 parent d20d356 commit a0d1e48
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 16 deletions.
25 changes: 25 additions & 0 deletions app/Domain/MonthWorkingHoursCalculator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Toby\Domain;

use Toby\Enums\VacationType;
use Toby\Models\User;

class MonthWorkingHoursCalculator
{
public function calculateHours(array $calendar, User $user): int
{
return collect($calendar)
->filter(
fn(array $day): bool => !$day["isWeekend"]
&& !$day["isHoliday"]
&& ((
isset($day["vacations"][$user->id])
&& in_array($day["vacations"][$user->id]["type"]->value, [VacationType::RemoteWork->value, VacationType::Delegation->value], true)
) || !isset($day["vacations"][$user->id])),
)
->count();
}
}
7 changes: 7 additions & 0 deletions app/Http/Controllers/VacationCalendarController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Illuminate\Support\Carbon;
use Inertia\Response;
use Toby\Domain\CalendarGenerator;
use Toby\Domain\MonthWorkingHoursCalculator;
use Toby\Enums\Month;
use Toby\Helpers\YearPeriodRetriever;
use Toby\Http\Resources\SimpleUserResource;
Expand All @@ -21,6 +22,7 @@ public function index(
Request $request,
YearPeriodRetriever $yearPeriodRetriever,
CalendarGenerator $calendarGenerator,
MonthWorkingHoursCalculator $monthWorkingHoursCalculator,
?string $month = null,
?int $year = null,
): Response|RedirectResponse {
Expand All @@ -29,6 +31,7 @@ public function index(
}

$month = Month::fromNameOrCurrent((string)$month);
/** @var User $currentUser */
$currentUser = $request->user();
$withTrashedUsers = $currentUser->canSeeInactiveUsers();

Expand All @@ -53,9 +56,13 @@ public function index(
$users->prepend($currentUser);

$calendar = $calendarGenerator->generate($carbonMonth);
$workingHours = $currentUser->isEmployedOnEmploymentForm()
? $monthWorkingHoursCalculator->calculateHours($calendar, $currentUser) * config("toby.number_of_hours_on_employment_contract.full_time")
: null;

return inertia("Calendar", [
"calendar" => $calendar,
"workingHours" => $workingHours,
"currentMonth" => Month::current(),
"currentYear" => Carbon::now()->year,
"selectedMonth" => $month->value,
Expand Down
6 changes: 6 additions & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Illuminate\Support\Facades\DB;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
use Toby\Enums\EmploymentForm;
use Toby\Enums\Role;
use Toby\Enums\UserHistoryType;
use Toby\Notifications\Notifiable as NotifiableInterface;
Expand Down Expand Up @@ -257,6 +258,11 @@ public function isWorkAnniversaryToday(): bool
return $workAnniversary?->isToday() ?? false;
}

public function isEmployedOnEmploymentForm(EmploymentForm $employmentForm = EmploymentForm::EmploymentContract): bool
{
return $this->profile->employment_form === $employmentForm;
}

protected static function newFactory(): UserFactory
{
return UserFactory::new();
Expand Down
9 changes: 9 additions & 0 deletions config/toby.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

return [
"number_of_hours_on_employment_contract" => [
"full_time" => 8,
],
];
50 changes: 34 additions & 16 deletions resources/js/Pages/Calendar.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<script setup>
import { ChevronLeftIcon, ChevronRightIcon, ChevronDoubleRightIcon, ChevronDoubleLeftIcon, ChevronUpDownIcon, ArrowUturnLeftIcon } from '@heroicons/vue/24/solid'
import {
ArrowUturnLeftIcon,
ChevronDoubleLeftIcon,
ChevronDoubleRightIcon,
ChevronLeftIcon,
ChevronRightIcon,
ChevronUpDownIcon,
} from '@heroicons/vue/24/solid'
import { computed, ref, watch } from 'vue'
import { useMonthInfo } from '@/Composables/monthInfo.js'
import VacationTypeCalendarIcon from '@/Shared/VacationTypeCalendarIcon.vue'
Expand All @@ -13,6 +20,7 @@ const props = defineProps({
users: Object,
auth: Object,
calendar: Object,
workingHours: Number,
currentMonth: String,
currentYear: Number,
selectedMonth: String,
Expand Down Expand Up @@ -173,23 +181,33 @@ function linkVacationRequest(user) {
</InertiaLink>
</div>
</div>
<div
class="flex mt-3 sm:mt-0"
>
<a
v-if="auth.can.manageRequestsAsAdministrativeApprover"
:href="`/vacation/timesheet/${selectedMonth.value}`"
class="block py-3 px-4 sm:ml-3 text-sm font-medium leading-4 text-center text-white bg-blumilk-600 hover:bg-blumilk-700 rounded-md border border-transparent focus:outline-none focus:ring-2 focus:ring-blumilk-500 focus:ring-offset-2 shadow-sm"
<div class="flex-row">
<div
class="flex items-center mt-3 sm:mt-0"
>
Pobierz plik Excel
</a>
<a
v-if="auth.can.manageOvertimeAsAdministrativeApprover"
:href="`/overtime/timesheet/${selectedMonth.value}`"
class="block py-3 px-4 ml-3 text-sm font-medium leading-4 text-center text-white bg-blumilk-600 hover:bg-blumilk-700 rounded-md border border-transparent focus:outline-none focus:ring-2 focus:ring-blumilk-500 focus:ring-offset-2 shadow-sm"
<a
v-if="auth.can.manageRequestsAsAdministrativeApprover"
:href="`/vacation/timesheet/${selectedMonth.value}`"
class="block py-3 px-4 sm:ml-3 text-sm font-medium leading-4 text-center text-white bg-blumilk-600 hover:bg-blumilk-700 rounded-md border border-transparent focus:outline-none focus:ring-2 focus:ring-blumilk-500 focus:ring-offset-2 shadow-sm"
>
Pobierz plik Excel
</a>
<a
v-if="auth.can.manageOvertimeAsAdministrativeApprover"
:href="`/overtime/timesheet/${selectedMonth.value}`"
class="block py-3 px-4 ml-3 text-sm font-medium leading-4 text-center text-white bg-blumilk-600 hover:bg-blumilk-700 rounded-md border border-transparent focus:outline-none focus:ring-2 focus:ring-blumilk-500 focus:ring-offset-2 shadow-sm"
>
Pobierz nadgodziny
</a>
</div>
<div
v-if="workingHours !== null"
class="flex items-center justify-start sm:justify-end mt-3 sm:mt-1"
>
Pobierz nadgodziny
</a>
<p>
Liczba przepracowanych godzin: <span class="font-bold">{{ workingHours }}</span>
</p>
</div>
</div>
</div>
<div class="overflow-x-auto">
Expand Down

0 comments on commit a0d1e48

Please sign in to comment.