Skip to content

Commit a0d1e48

Browse files
authored
#479 - number of working hours (#480)
* #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
1 parent d20d356 commit a0d1e48

File tree

5 files changed

+81
-16
lines changed

5 files changed

+81
-16
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Toby\Domain;
6+
7+
use Toby\Enums\VacationType;
8+
use Toby\Models\User;
9+
10+
class MonthWorkingHoursCalculator
11+
{
12+
public function calculateHours(array $calendar, User $user): int
13+
{
14+
return collect($calendar)
15+
->filter(
16+
fn(array $day): bool => !$day["isWeekend"]
17+
&& !$day["isHoliday"]
18+
&& ((
19+
isset($day["vacations"][$user->id])
20+
&& in_array($day["vacations"][$user->id]["type"]->value, [VacationType::RemoteWork->value, VacationType::Delegation->value], true)
21+
) || !isset($day["vacations"][$user->id])),
22+
)
23+
->count();
24+
}
25+
}

app/Http/Controllers/VacationCalendarController.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Illuminate\Support\Carbon;
1010
use Inertia\Response;
1111
use Toby\Domain\CalendarGenerator;
12+
use Toby\Domain\MonthWorkingHoursCalculator;
1213
use Toby\Enums\Month;
1314
use Toby\Helpers\YearPeriodRetriever;
1415
use Toby\Http\Resources\SimpleUserResource;
@@ -21,6 +22,7 @@ public function index(
2122
Request $request,
2223
YearPeriodRetriever $yearPeriodRetriever,
2324
CalendarGenerator $calendarGenerator,
25+
MonthWorkingHoursCalculator $monthWorkingHoursCalculator,
2426
?string $month = null,
2527
?int $year = null,
2628
): Response|RedirectResponse {
@@ -29,6 +31,7 @@ public function index(
2931
}
3032

3133
$month = Month::fromNameOrCurrent((string)$month);
34+
/** @var User $currentUser */
3235
$currentUser = $request->user();
3336
$withTrashedUsers = $currentUser->canSeeInactiveUsers();
3437

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

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

5763
return inertia("Calendar", [
5864
"calendar" => $calendar,
65+
"workingHours" => $workingHours,
5966
"currentMonth" => Month::current(),
6067
"currentYear" => Carbon::now()->year,
6168
"selectedMonth" => $month->value,

app/Models/User.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Illuminate\Support\Facades\DB;
1818
use Laravel\Sanctum\HasApiTokens;
1919
use Spatie\Permission\Traits\HasRoles;
20+
use Toby\Enums\EmploymentForm;
2021
use Toby\Enums\Role;
2122
use Toby\Enums\UserHistoryType;
2223
use Toby\Notifications\Notifiable as NotifiableInterface;
@@ -257,6 +258,11 @@ public function isWorkAnniversaryToday(): bool
257258
return $workAnniversary?->isToday() ?? false;
258259
}
259260

261+
public function isEmployedOnEmploymentForm(EmploymentForm $employmentForm = EmploymentForm::EmploymentContract): bool
262+
{
263+
return $this->profile->employment_form === $employmentForm;
264+
}
265+
260266
protected static function newFactory(): UserFactory
261267
{
262268
return UserFactory::new();

config/toby.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
return [
6+
"number_of_hours_on_employment_contract" => [
7+
"full_time" => 8,
8+
],
9+
];

resources/js/Pages/Calendar.vue

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
<script setup>
2-
import { ChevronLeftIcon, ChevronRightIcon, ChevronDoubleRightIcon, ChevronDoubleLeftIcon, ChevronUpDownIcon, ArrowUturnLeftIcon } from '@heroicons/vue/24/solid'
2+
import {
3+
ArrowUturnLeftIcon,
4+
ChevronDoubleLeftIcon,
5+
ChevronDoubleRightIcon,
6+
ChevronLeftIcon,
7+
ChevronRightIcon,
8+
ChevronUpDownIcon,
9+
} from '@heroicons/vue/24/solid'
310
import { computed, ref, watch } from 'vue'
411
import { useMonthInfo } from '@/Composables/monthInfo.js'
512
import VacationTypeCalendarIcon from '@/Shared/VacationTypeCalendarIcon.vue'
@@ -13,6 +20,7 @@ const props = defineProps({
1320
users: Object,
1421
auth: Object,
1522
calendar: Object,
23+
workingHours: Number,
1624
currentMonth: String,
1725
currentYear: Number,
1826
selectedMonth: String,
@@ -173,23 +181,33 @@ function linkVacationRequest(user) {
173181
</InertiaLink>
174182
</div>
175183
</div>
176-
<div
177-
class="flex mt-3 sm:mt-0"
178-
>
179-
<a
180-
v-if="auth.can.manageRequestsAsAdministrativeApprover"
181-
:href="`/vacation/timesheet/${selectedMonth.value}`"
182-
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"
184+
<div class="flex-row">
185+
<div
186+
class="flex items-center mt-3 sm:mt-0"
183187
>
184-
Pobierz plik Excel
185-
</a>
186-
<a
187-
v-if="auth.can.manageOvertimeAsAdministrativeApprover"
188-
:href="`/overtime/timesheet/${selectedMonth.value}`"
189-
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"
188+
<a
189+
v-if="auth.can.manageRequestsAsAdministrativeApprover"
190+
:href="`/vacation/timesheet/${selectedMonth.value}`"
191+
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"
192+
>
193+
Pobierz plik Excel
194+
</a>
195+
<a
196+
v-if="auth.can.manageOvertimeAsAdministrativeApprover"
197+
:href="`/overtime/timesheet/${selectedMonth.value}`"
198+
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"
199+
>
200+
Pobierz nadgodziny
201+
</a>
202+
</div>
203+
<div
204+
v-if="workingHours !== null"
205+
class="flex items-center justify-start sm:justify-end mt-3 sm:mt-1"
190206
>
191-
Pobierz nadgodziny
192-
</a>
207+
<p>
208+
Liczba przepracowanych godzin: <span class="font-bold">{{ workingHours }}</span>
209+
</p>
210+
</div>
193211
</div>
194212
</div>
195213
<div class="overflow-x-auto">

0 commit comments

Comments
 (0)