Merge branch 'main' into #41-email-notifications

# Conflicts:
#	app/Domain/CalendarGenerator.php
#	app/Domain/Enums/VacationRequestState.php
#	app/Domain/VacationRequestStateManager.php
#	resources/js/Composables/statusInfo.js
#	resources/js/Pages/Calendar.vue
#	resources/js/Shared/MainMenu.vue
#	resources/lang/pl.json
#	tests/Feature/VacationRequestTest.php
#	tests/Unit/VacationRequestStatesTest.php
This commit is contained in:
EwelinaLasowy 2022-02-16 08:53:55 +01:00
commit 3c499e8be3
31 changed files with 256 additions and 175 deletions

View File

@ -73,7 +73,7 @@ class CalendarGenerator
{
return Vacation::query()
->whereBetween("date", [$period->start, $period->end])
->whereRelation("vacationRequest", "state", VacationRequestState::APPROVED->value)
->whereRelation("vacationRequest", "state", VacationRequestState::Approved->value)
->get()
->groupBy(fn(Vacation $vacation) => $vacation->date->toDateString());
}

View File

@ -6,10 +6,10 @@ namespace Toby\Domain\Enums;
enum EmploymentForm: string
{
case EMPLOYMENT_CONTRACT = "employment_contract";
case COMMISSION_CONTRACT = "commission_contract";
case B2B_CONTRACT = "b2b_contract";
case BOARD_MEMBER_CONTRACT = "board_member_contract";
case EmploymentContract = "employment_contract";
case ComissionContract = "commission_contract";
case B2bContract = "b2b_contract";
case BoardMemberContract = "board_member_contract";
public function label(): string
{

View File

@ -6,10 +6,10 @@ namespace Toby\Domain\Enums;
enum Role: string
{
case EMPLOYEE = "employee";
case ADMINISTRATOR = "administrator";
case TECHNICAL_APPROVER = "technical_approver";
case ADMINISTRATIVE_APPROVER = "administrative_approver";
case Employee = "employee";
case Administrator = "administrator";
case TechnicalApprover = "technical_approver";
case AdministrativeApprover = "administrative_approver";
public function label(): string
{

View File

@ -6,14 +6,14 @@ namespace Toby\Domain\Enums;
enum VacationRequestState: string
{
case CREATED = "created";
case CANCELED = "canceled";
case REJECTED = "rejected";
case APPROVED = "approved";
case WAITING_FOR_TECHNICAL = "waiting_for_technical";
case WAITING_FOR_ADMINISTRATIVE = "waiting_for_administrative";
case ACCEPTED_BY_TECHNICAL = "accepted_by_technical";
case ACCEPTED_BY_ADMINISTRATIVE = "accepted_by_administrative";
case Created = "created";
case Canceled = "canceled";
case Rejected = "rejected";
case Approved = "approved";
case WaitingForTechnical = "waiting_for_technical";
case WaitingForAdministrative = "waiting_for_administrative";
case AcceptedByTechnical = "accepted_by_technical";
case AcceptedByAdministrative = "accepted_by_administrative";
public function label(): string
{
@ -23,24 +23,24 @@ enum VacationRequestState: string
public static function pendingStates(): array
{
return [
self::CREATED,
self::WAITING_FOR_TECHNICAL,
self::WAITING_FOR_ADMINISTRATIVE,
self::ACCEPTED_BY_TECHNICAL,
self::ACCEPTED_BY_ADMINISTRATIVE,
self::Created,
self::WaitingForTechnical,
self::WaitingForAdministrative,
self::AcceptedByTechnical,
self::AcceptedByAdministrative,
];
}
public static function successStates(): array
{
return [self::APPROVED];
return [self::Approved];
}
public static function failedStates(): array
{
return [
self::REJECTED,
self::CANCELED,
self::Rejected,
self::Canceled,
];
}

View File

@ -6,15 +6,15 @@ namespace Toby\Domain\Enums;
enum VacationType: string
{
case VACATION = "vacation";
case VACATION_ON_REQUEST = "vacation_on_request";
case SPECIAL_VACATION = "special_vacation";
case CHILDCARE_VACATION = "childcare_vacation";
case TRAINING_VACATION = "training_vacation";
case UNPAID_VACATION = "unpaid_vacation";
case VOLUNTEERING_VACATION = "volunteering_vacation";
case TIME_IN_LIEU = "time_in_lieu";
case SICK_VACATION = "sick_vacation";
case Vacation = "vacation";
case OnRequest = "vacation_on_request";
case Special = "special_vacation";
case Childcare = "childcare_vacation";
case Training = "training_vacation";
case Unpaid = "unpaid_vacation";
case Volunteering = "volunteering_vacation";
case TimeInLieu = "time_in_lieu";
case Sick = "sick_vacation";
public function label(): string
{

View File

@ -23,50 +23,50 @@ class VacationRequestStateManager
public function markAsCreated(VacationRequest $vacationRequest): void
{
$this->changeState($vacationRequest, VacationRequestState::CREATED);
$this->changeState($vacationRequest, VacationRequestState::Created);
$this->dispatcher->dispatch(new VacationRequestCreated($vacationRequest));
}
public function approve(VacationRequest $vacationRequest): void
{
$this->changeState($vacationRequest, VacationRequestState::APPROVED);
$this->changeState($vacationRequest, VacationRequestState::Approved);
$this->dispatcher->dispatch(new VacationRequestApproved($vacationRequest));
}
public function reject(VacationRequest $vacationRequest): void
{
$this->changeState($vacationRequest, VacationRequestState::REJECTED);
$this->changeState($vacationRequest, VacationRequestState::Rejected);
}
public function cancel(VacationRequest $vacationRequest): void
{
$this->changeState($vacationRequest, VacationRequestState::CANCELED);
$this->changeState($vacationRequest, VacationRequestState::Canceled);
}
public function acceptAsTechnical(VacationRequest $vacationRequest): void
{
$this->changeState($vacationRequest, VacationRequestState::ACCEPTED_BY_TECHNICAL);
$this->changeState($vacationRequest, VacationRequestState::AcceptedByTechnical);
$this->dispatcher->dispatch(new VacationRequestAcceptedByTechnical($vacationRequest));
}
public function acceptAsAdministrative(VacationRequest $vacationRequest): void
{
$this->changeState($vacationRequest, VacationRequestState::ACCEPTED_BY_ADMINISTRATIVE);
$this->changeState($vacationRequest, VacationRequestState::AcceptedByAdministrative);
$this->dispatcher->dispatch(new VacationRequestAcceptedByAdministrative($vacationRequest));
}
public function waitForTechnical(VacationRequest $vacationRequest): void
{
$this->changeState($vacationRequest, VacationRequestState::WAITING_FOR_TECHNICAL);
$this->changeState($vacationRequest, VacationRequestState::WaitingForTechnical);
}
public function waitForAdministrative(VacationRequest $vacationRequest): void
{
$this->changeState($vacationRequest, VacationRequestState::WAITING_FOR_ADMINISTRATIVE);
$this->changeState($vacationRequest, VacationRequestState::WaitingForAdministrative);
}
protected function changeState(VacationRequest $vacationRequest, VacationRequestState $state): void

View File

@ -35,7 +35,7 @@ class HolidayController extends Controller
return redirect()
->route("holidays.index")
->with("success", __("Holiday has been created"));
->with("success", __("Holiday has been created."));
}
public function edit(Holiday $holiday): Response
@ -51,7 +51,7 @@ class HolidayController extends Controller
return redirect()
->route("holidays.index")
->with("success", __("Holiday has been updated"));
->with("success", __("Holiday has been updated."));
}
public function destroy(Holiday $holiday): RedirectResponse
@ -60,6 +60,6 @@ class HolidayController extends Controller
return redirect()
->route("holidays.index")
->with("success", __("Holiday has been deleted"));
->with("success", __("Holiday has been deleted."));
}
}

View File

@ -17,6 +17,6 @@ class SelectYearPeriodController extends Controller
return redirect()
->back()
->with("success", __("Selected year period has been changed"));
->with("success", __("Selected year period has been changed."));
}
}

View File

@ -46,7 +46,7 @@ class UserController extends Controller
return redirect()
->route("users.index")
->with("success", __("User has been created"));
->with("success", __("User has been created."));
}
public function edit(User $user): Response
@ -64,7 +64,7 @@ class UserController extends Controller
return redirect()
->route("users.index")
->with("success", __("User has been updated"));
->with("success", __("User has been updated."));
}
public function destroy(User $user): RedirectResponse
@ -73,7 +73,7 @@ class UserController extends Controller
return redirect()
->route("users.index")
->with("success", __("User has been deleted"));
->with("success", __("User has been deleted."));
}
public function restore(User $user): RedirectResponse
@ -82,6 +82,6 @@ class UserController extends Controller
return redirect()
->route("users.index")
->with("success", __("User has been restored"));
->with("success", __("User has been restored."));
}
}

View File

@ -35,6 +35,6 @@ class VacationLimitController extends Controller
return redirect()
->back()
->with("success", __("Vacation limits have been updated"));
->with("success", __("Vacation limits have been updated."));
}
}

View File

@ -95,7 +95,8 @@ class VacationRequestController extends Controller
$stateManager->markAsCreated($vacationRequest);
return redirect()
->route("vacation.requests.index");
->route("vacation.requests.show", $vacationRequest)
->with("success", __("Vacation request has been created."));
}
public function reject(
@ -104,7 +105,8 @@ class VacationRequestController extends Controller
): RedirectResponse {
$stateManager->reject($vacationRequest);
return redirect()->back();
return redirect()->back()
->with("success", __("Vacation request has been rejected."));
}
public function cancel(
@ -113,7 +115,8 @@ class VacationRequestController extends Controller
): RedirectResponse {
$stateManager->cancel($vacationRequest);
return redirect()->back();
return redirect()->back()
->with("success", __("Vacation request has been canceled."));
}
public function acceptAsTechnical(
@ -122,7 +125,8 @@ class VacationRequestController extends Controller
): RedirectResponse {
$stateManager->acceptAsTechnical($vacationRequest);
return redirect()->back();
return redirect()->back()
->with("success", __("Vacation request has been accepted."));
}
public function acceptAsAdministrative(
@ -131,6 +135,7 @@ class VacationRequestController extends Controller
): RedirectResponse {
$stateManager->acceptAsAdministrative($vacationRequest);
return redirect()->back();
return redirect()->back()
->with("success", __("Vacation request has been accepted."));
}
}

View File

@ -6,55 +6,55 @@ use Toby\Domain\Enums\VacationType;
use Toby\Domain\VacationTypeConfigRetriever;
return [
VacationType::VACATION->value => [
VacationType::Vacation->value => [
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
VacationTypeConfigRetriever::KEY_BILLABLE => true,
VacationTypeConfigRetriever::KEY_HAS_LIMIT => true,
],
VacationType::VACATION_ON_REQUEST->value => [
VacationType::OnRequest->value => [
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
VacationTypeConfigRetriever::KEY_BILLABLE => true,
VacationTypeConfigRetriever::KEY_HAS_LIMIT => true,
],
VacationType::TIME_IN_LIEU->value => [
VacationType::TimeInLieu->value => [
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => false,
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => false,
VacationTypeConfigRetriever::KEY_BILLABLE => true,
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
],
VacationType::SICK_VACATION->value => [
VacationType::Sick->value => [
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => false,
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
VacationTypeConfigRetriever::KEY_BILLABLE => true,
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
],
VacationType::UNPAID_VACATION->value => [
VacationType::Unpaid->value => [
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
VacationTypeConfigRetriever::KEY_BILLABLE => false,
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
],
VacationType::SPECIAL_VACATION->value => [
VacationType::Special->value => [
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
VacationTypeConfigRetriever::KEY_BILLABLE => false,
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
],
VacationType::CHILDCARE_VACATION->value => [
VacationType::Childcare->value => [
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
VacationTypeConfigRetriever::KEY_BILLABLE => false,
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
],
VacationType::TRAINING_VACATION->value => [
VacationType::Training->value => [
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
VacationTypeConfigRetriever::KEY_BILLABLE => true,
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
],
VacationType::VOLUNTEERING_VACATION->value => [
VacationType::Volunteering->value => [
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
VacationTypeConfigRetriever::KEY_BILLABLE => true,

View File

@ -23,7 +23,7 @@ class UserFactory extends Factory
"email" => $this->faker->unique()->safeEmail(),
"employment_form" => $this->faker->randomElement(EmploymentForm::cases()),
"position" => $this->faker->jobTitle(),
"role" => Role::EMPLOYEE,
"role" => Role::Employee,
"employment_date" => Carbon::createFromInterface($this->faker->dateTimeBetween("2020-10-27"))->toDateString(),
"remember_token" => Str::random(10),
];

View File

@ -16,7 +16,7 @@ return new class() extends Migration {
$table->string("last_name");
$table->string("email")->unique();
$table->string("avatar")->nullable();
$table->string("role")->default(Role::EMPLOYEE->value);
$table->string("role")->default(Role::Employee->value);
$table->string("position");
$table->string("employment_form");
$table->date("employment_date");

17
package-lock.json generated
View File

@ -25,7 +25,8 @@
"vue": "^3.2.26",
"vue-echarts": "^6.0.2",
"vue-flatpickr-component": "^9.0.5",
"vue-loader": "^17.0.0"
"vue-loader": "^17.0.0",
"vue-toastification": "^2.0.0-rc.5"
},
"devDependencies": {
"eslint": "^8.6.0",
@ -8943,6 +8944,14 @@
"resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
"integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ="
},
"node_modules/vue-toastification": {
"version": "2.0.0-rc.5",
"resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz",
"integrity": "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==",
"peerDependencies": {
"vue": "^3.0.2"
}
},
"node_modules/watchpack": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",
@ -16100,6 +16109,12 @@
}
}
},
"vue-toastification": {
"version": "2.0.0-rc.5",
"resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz",
"integrity": "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==",
"requires": {}
},
"watchpack": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",

View File

@ -32,7 +32,8 @@
"vue": "^3.2.26",
"vue-echarts": "^6.0.2",
"vue-flatpickr-component": "^9.0.5",
"vue-loader": "^17.0.0"
"vue-loader": "^17.0.0",
"vue-toastification": "^2.0.0-rc.5"
},
"devDependencies": {
"eslint": "^8.6.0",

View File

@ -1,4 +1,5 @@
@import 'flatpickr/dist/themes/light.css';
@import 'vue-toastification/dist/index.css';
@tailwind base;
@tailwind components;

View File

@ -0,0 +1,60 @@
const months = [
{
'name': 'Styczeń',
'value': 'january',
},
{
'name': 'Luty',
'value': 'february',
},
{
'name': 'Marzec',
'value': 'march',
},
{
'name': 'Kwiecień',
'value': 'april',
},
{
'name': 'Maj',
'value': 'may',
},
{
'name': 'Czerwiec',
'value': 'june',
},
{
'name': 'Lipiec',
'value': 'july',
},
{
'name': 'Sierpień',
'value': 'august',
},
{
'name': 'Wrzesień',
'value': 'september',
},
{
'name': 'Październik',
'value': 'october',
},
{
'name': 'Listopad',
'value': 'november',
},
{
'name': 'Grudzień',
'value': 'december',
},
]
export function useMonthInfo() {
const getMonths = () => months
const findMonth = value => months.find(month => month.value === value)
return {
getMonths,
findMonth,
}
}

View File

@ -31,7 +31,7 @@ const statuses = [
},
},
{
text: 'Czeka na akceptację od technicznego',
text: 'Czeka na akceptację od przełożonego technicznego',
value: 'waiting_for_technical',
outline: {
icon: OutlineClockIcon,
@ -44,7 +44,7 @@ const statuses = [
},
},
{
text: 'Czeka na akceptację od administracyjnego',
text: 'Czeka na akceptację od przełożonego administracyjnego',
value: 'waiting_for_administrative',
outline: {
icon: OutlineClockIcon,
@ -70,7 +70,7 @@ const statuses = [
},
},
{
text: 'Zaakceptowany przez technicznego',
text: 'Zaakceptowany przez przełożonego technicznego',
value: 'accepted_by_technical',
outline: {
icon: OutlineThumbUpIcon,
@ -83,7 +83,7 @@ const statuses = [
},
},
{
text: 'Zaakceptowany przez administracyjnego',
text: 'Zaakceptowany przez przełożonego administracyjnego',
value: 'accepted_by_administrative',
outline: {
icon: OutlineThumbUpIcon,

View File

@ -126,6 +126,7 @@
import {Menu, MenuButton, MenuItem, MenuItems} from '@headlessui/vue'
import {CheckIcon, ChevronDownIcon} from '@heroicons/vue/solid'
import {computed} from 'vue'
import {useMonthInfo} from '@/Composables/monthInfo'
export default {
name: 'VacationCalendar',
@ -152,58 +153,10 @@ export default {
},
},
setup(props) {
const months = [
{
'name': 'Styczeń',
'value': 'january',
},
{
'name': 'Luty',
'value': 'february',
},
{
'name': 'Marzec',
'value': 'march',
},
{
'name': 'Kwiecień',
'value': 'april',
},
{
'name': 'Maj',
'value': 'may',
},
{
'name': 'Czerwiec',
'value': 'june',
},
{
'name': 'Lipiec',
'value': 'july',
},
{
'name': 'Sierpień',
'value': 'august',
},
{
'name': 'Wrzesień',
'value': 'september',
},
{
'name': 'Październik',
'value': 'october',
},
{
'name': 'Listopad',
'value': 'november',
},
{
'name': 'Grudzień',
'value': 'december',
},
]
const {getMonths, findMonth} = useMonthInfo()
const months = getMonths()
const selectedMonth = computed(() => months.find(month => month.value === props.currentMonth))
const selectedMonth = computed(() => findMonth(props.currentMonth))
return {
months,

View File

@ -15,7 +15,7 @@
<div class="p-4">
<div class="flex items-center">
<div class="w-0 flex-1 flex justify-between">
<ExclamationIcon class="h-5 w-5 text-white" />
<ExclamationIcon class="h-5 w-5 mr-1 text-white" />
<p class="w-0 flex-1 text-sm font-medium text-white">
{{ errors.oauth }}
</p>

View File

@ -126,6 +126,7 @@
:href="`/vacation-requests/${request.id}/accept-as-technical`"
method="post"
as="button"
preserve-scroll
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
>
Zaakceptuj wniosek
@ -148,6 +149,7 @@
:href="`/vacation-requests/${request.id}/accept-as-administrative`"
method="post"
as="button"
preserve-scroll
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
>
Zaakceptuj wniosek
@ -170,6 +172,7 @@
:href="`/vacation-requests/${request.id}/reject`"
method="post"
as="button"
preserve-scroll
class="inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:text-sm"
>
Odrzuć wniosek
@ -192,6 +195,7 @@
:href="`/vacation-requests/${request.id}/cancel`"
method="post"
as="button"
preserve-scroll
class="inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:text-sm"
>
Anuluj wniosek

View File

@ -11,9 +11,36 @@
<script>
import MainMenu from '@/Shared/MainMenu'
import {useToast} from 'vue-toastification'
import {watch} from 'vue'
export default {
name: 'AppLayout',
components: {MainMenu},
components: {
MainMenu,
},
props: {
flash: {
type: Object,
default: () => null,
},
},
setup(props) {
const toast = useToast()
watch(() => props.flash, flash => {
if (flash.success) {
toast.success(flash.success)
}
if (flash.error) {
toast.error(flash.error)
}
}, {immediate:true})
return {
toast,
}
},
}
</script>

View File

@ -1,4 +1,3 @@
<template>
<div class="min-h-screen flex flex-col justify-center py-12 sm:px-6 lg:px-8 bg-blumilk-25">
<slot />

View File

@ -363,11 +363,11 @@ export default {
const navigation = [
{name: 'Strona główna', href: '/', icon: HomeIcon, current: true},
{name: 'Użytkownicy', href: '/users', icon: UserGroupIcon, current: false},
{name: 'Dostępne urlopy', href: '/vacation-limits', icon: SunIcon, current: false},
{name: 'Twoje wnioski', href: '/vacation-requests', icon: CollectionIcon, current: false},
{name: 'Dni wolne', href: '/holidays', icon: StarIcon, current: false},
{name: 'Wnioski urlopowe', href: '/vacation-requests', icon: CollectionIcon, current: false},
{name: 'Kalendarz urlopów', href: '/vacation-calendar', icon: CalendarIcon, current: false},
{name: 'Dni wolne', href: '/holidays', icon: StarIcon, current: false},
{name: 'Limity urlopów', href: '/vacation-limits', icon: SunIcon, current: false},
{name: 'Użytkownicy', href: '/users', icon: UserGroupIcon, current: false},
]
const userNavigation = [
{name: 'Your Profile', href: '#'},
@ -390,4 +390,4 @@ export default {
}
},
}
</script>
</script>

View File

@ -4,6 +4,7 @@ import {InertiaProgress} from '@inertiajs/progress'
import AppLayout from '@/Shared/Layout/AppLayout'
import Flatpickr from 'flatpickr'
import { Polish } from 'flatpickr/dist/l10n/pl.js'
import Toast from 'vue-toastification'
createInertiaApp({
resolve: name => {
@ -16,6 +17,11 @@ createInertiaApp({
setup({el, App, props, plugin}) {
createApp({render: () => h(App, props)})
.use(plugin)
.use(Toast, {
position: 'bottom-right',
maxToast: 5,
})
.component('InertiaLink', Link)
.component('InertiaHead', Head)
.mount(el)

View File

@ -31,6 +31,19 @@
"Vacation limit has been exceeded.": "Limit urlopu został przekroczony.",
"Vacation needs minimum one day.": "Urlop musi być co najmniej na jeden dzień.",
"The vacation request cannot be created at the turn of the year.": "Wniosek urlopowy nie może zostać złożony na przełomie roku.",
"User has been created.": "Użytkownik został utworzony.",
"User has been updated.": "Użytkownik został zaktualizowany.",
"User has been deleted.": "Użytkownik został usunięty.",
"User has been restored.": "Użytkownik został przywrócony.",
"Holiday has been created.": "Dzień wolny został utworzony.",
"Holiday has been updated.": "Dzień wolny został zaktualizowany.",
"Holiday has been deleted.": "Dzień wolny został usunięty.",
"Selected year period has been changed.": "Wybrany rok został zmieniony.",
"Vacation limits have been updated.": "Limity urlopów zostały zaktualizowane.",
"Vacation request has been created.": "Wniosek urlopowy został utworzony.",
"Vacation request has been accepted.": "Wniosek urlopowy został zaakceptowany.",
"Vacation request has been rejected.": "Wniosek urlopowy został odrzucony.",
"Vacation request has been canceled.": "Wniosek urlopowy został anulowany.",
"Hi :user!": "Cześć :user!",
"The vacation request :title has changed state to :state.": "Wniosek urlopowy :title zmienił status na :state.",
"Vacation request :title": "Wniosek urlopowy :title",

View File

@ -74,7 +74,7 @@
<h2>Wniosek o urlop</h2>
<p class="content">
Proszę o {{ mb_strtolower($vacationRequest->type->label()) }} w okresie od dnia {{ $vacationRequest->from->format("d.m.Y") }}
do dnia {{ $vacationRequest->to->format("d.m.Y") }} włącznie tj. {{ $vacationRequest->estimated_days }} dni roboczych za rok {{ $vacationRequest->yearPeriod->year }}.
do dnia {{ $vacationRequest->to->format("d.m.Y") }} włącznie tj. {{ $vacationRequest->vacations()->count() }} dni roboczych za rok {{ $vacationRequest->yearPeriod->year }}.
</p>
</div>

View File

@ -88,10 +88,10 @@ class UserTest extends FeatureTestCase
->post("/users", [
"firstName" => "John",
"lastName" => "Doe",
"role" => Role::EMPLOYEE->value,
"role" => Role::Employee->value,
"position" => "Test position",
"email" => "john.doe@example.com",
"employmentForm" => EmploymentForm::B2B_CONTRACT->value,
"employmentForm" => EmploymentForm::B2bContract->value,
"employmentDate" => Carbon::now()->toDateString(),
])
->assertSessionHasNoErrors();
@ -100,9 +100,9 @@ class UserTest extends FeatureTestCase
"first_name" => "John",
"last_name" => "Doe",
"email" => "john.doe@example.com",
"role" => Role::EMPLOYEE->value,
"role" => Role::Employee->value,
"position" => "Test position",
"employment_form" => EmploymentForm::B2B_CONTRACT->value,
"employment_form" => EmploymentForm::B2bContract->value,
"employment_date" => Carbon::now()->toDateString(),
]);
}
@ -127,9 +127,9 @@ class UserTest extends FeatureTestCase
"firstName" => "John",
"lastName" => "Doe",
"email" => "john.doe@example.com",
"role" => Role::EMPLOYEE->value,
"role" => Role::Employee->value,
"position" => "Test position",
"employmentForm" => EmploymentForm::B2B_CONTRACT->value,
"employmentForm" => EmploymentForm::B2bContract->value,
"employmentDate" => Carbon::now()->toDateString(),
])
->assertSessionHasNoErrors();
@ -138,9 +138,9 @@ class UserTest extends FeatureTestCase
"first_name" => "John",
"last_name" => "Doe",
"email" => "john.doe@example.com",
"role" => Role::EMPLOYEE->value,
"role" => Role::Employee->value,
"position" => "Test position",
"employment_form" => EmploymentForm::B2B_CONTRACT->value,
"employment_form" => EmploymentForm::B2bContract->value,
"employment_date" => Carbon::now()->toDateString(),
]);
}

View File

@ -65,7 +65,7 @@ class VacationRequestTest extends FeatureTestCase
$this->actingAs($user)
->post("/vacation-requests", [
"type" => VacationType::VACATION->value,
"type" => VacationType::Vacation->value,
"from" => Carbon::create($currentYearPeriod->year, 2, 7)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 11)->toDateString(),
"comment" => "Comment for the vacation request.",
@ -76,8 +76,8 @@ class VacationRequestTest extends FeatureTestCase
"user_id" => $user->id,
"year_period_id" => $currentYearPeriod->id,
"name" => "1/" . $currentYearPeriod->year,
"type" => VacationType::VACATION->value,
"state" => VacationRequestState::WAITING_FOR_TECHNICAL,
"type" => VacationType::Vacation->value,
"state" => VacationRequestState::WaitingForTechnical,
"from" => Carbon::create($currentYearPeriod->year, 2, 7)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 11)->toDateString(),
"comment" => "Comment for the vacation request.",
@ -91,8 +91,8 @@ class VacationRequestTest extends FeatureTestCase
$currentYearPeriod = YearPeriod::current();
$vacationRequest = VacationRequest::factory([
"state" => VacationRequestState::WAITING_FOR_TECHNICAL,
"type" => VacationType::VACATION,
"state" => VacationRequestState::WaitingForTechnical,
"type" => VacationType::Vacation,
])
->for($user)
->for($currentYearPeriod)
@ -103,7 +103,7 @@ class VacationRequestTest extends FeatureTestCase
->assertSessionHasNoErrors();
$this->assertDatabaseHas("vacation_requests", [
"state" => VacationRequestState::WAITING_FOR_ADMINISTRATIVE,
"state" => VacationRequestState::WaitingForAdministrative,
]);
}
@ -115,7 +115,7 @@ class VacationRequestTest extends FeatureTestCase
$currentYearPeriod = YearPeriod::current();
$vacationRequest = VacationRequest::factory([
"state" => VacationRequestState::WAITING_FOR_ADMINISTRATIVE,
"state" => VacationRequestState::WaitingForAdministrative,
])
->for($user)
->for($currentYearPeriod)
@ -126,7 +126,7 @@ class VacationRequestTest extends FeatureTestCase
->assertSessionHasNoErrors();
$this->assertDatabaseHas("vacation_requests", [
"state" => VacationRequestState::APPROVED,
"state" => VacationRequestState::Approved,
]);
}
@ -144,8 +144,8 @@ class VacationRequestTest extends FeatureTestCase
->create();
$vacationRequest = VacationRequest::factory([
"state" => VacationRequestState::WAITING_FOR_TECHNICAL,
"type" => VacationType::VACATION,
"state" => VacationRequestState::WaitingForTechnical,
"type" => VacationType::Vacation,
])
->for($user)
->for($currentYearPeriod)
@ -156,7 +156,7 @@ class VacationRequestTest extends FeatureTestCase
->assertSessionHasNoErrors();
$this->assertDatabaseHas("vacation_requests", [
"state" => VacationRequestState::REJECTED,
"state" => VacationRequestState::Rejected,
]);
}
@ -174,7 +174,7 @@ class VacationRequestTest extends FeatureTestCase
$this->actingAs($user)
->post("/vacation-requests", [
"type" => VacationType::VACATION->value,
"type" => VacationType::Vacation->value,
"from" => Carbon::create($currentYearPeriod->year, 2, 7)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 11)->toDateString(),
"comment" => "Comment for the vacation request.",
@ -198,7 +198,7 @@ class VacationRequestTest extends FeatureTestCase
$this->actingAs($user)
->post("/vacation-requests", [
"type" => VacationType::VACATION->value,
"type" => VacationType::Vacation->value,
"from" => Carbon::create($currentYearPeriod->year, 2, 5)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 6)->toDateString(),
"comment" => "Vacation at weekend.",
@ -229,7 +229,7 @@ class VacationRequestTest extends FeatureTestCase
$this->actingAs($user)
->post("/vacation-requests", [
"type" => VacationType::VACATION->value,
"type" => VacationType::Vacation->value,
"from" => Carbon::create($currentYearPeriod->year, 4, 18)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 4, 18)->toDateString(),
"comment" => "Vacation at holiday.",
@ -252,8 +252,8 @@ class VacationRequestTest extends FeatureTestCase
->create();
VacationRequest::factory([
"type" => VacationType::VACATION->value,
"state" => VacationRequestState::WAITING_FOR_TECHNICAL,
"type" => VacationType::Vacation->value,
"state" => VacationRequestState::WaitingForTechnical,
"from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
"comment" => "Comment for the vacation request.",
@ -264,7 +264,7 @@ class VacationRequestTest extends FeatureTestCase
$this->actingAs($user)
->post("/vacation-requests", [
"type" => VacationType::VACATION->value,
"type" => VacationType::Vacation->value,
"from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
"comment" => "Another comment for the another vacation request.",
@ -288,8 +288,8 @@ class VacationRequestTest extends FeatureTestCase
->create();
VacationRequest::factory([
"type" => VacationType::VACATION->value,
"state" => VacationRequestState::APPROVED,
"type" => VacationType::Vacation->value,
"state" => VacationRequestState::Approved,
"from" => Carbon::create($currentYearPeriod->year, 2, 2)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
"comment" => "Comment for the vacation request.",
@ -300,7 +300,7 @@ class VacationRequestTest extends FeatureTestCase
$this->actingAs($user)
->post("/vacation-requests", [
"type" => VacationType::VACATION->value,
"type" => VacationType::Vacation->value,
"from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
"comment" => "Another comment for the another vacation request.",
@ -316,7 +316,7 @@ class VacationRequestTest extends FeatureTestCase
$currentYearPeriod = YearPeriod::current();
$this->actingAs($user)
->post("/vacation-requests", [
"type" => VacationType::VACATION->value,
"type" => VacationType::Vacation->value,
"from" => Carbon::create($currentYearPeriod->year, 2, 7)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 6)->toDateString(),
"comment" => "Comment for the vacation request.",
@ -333,7 +333,7 @@ class VacationRequestTest extends FeatureTestCase
$nextYearPeriod = $this->createYearPeriod(Carbon::now()->year + 1);
$this->actingAs($user)
->post("/vacation-requests", [
"type" => VacationType::VACATION->value,
"type" => VacationType::Vacation->value,
"from" => Carbon::create($currentYearPeriod->year, 12, 27)->toDateString(),
"to" => Carbon::create($nextYearPeriod->year, 1, 2)->toDateString(),
"comment" => "Comment for the vacation request.",

View File

@ -5,14 +5,11 @@ declare(strict_types=1);
namespace Tests\Unit;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Carbon;
use Tests\TestCase;
use Tests\Traits\InteractsWithYearPeriods;
use Toby\Domain\Enums\Role;
use Toby\Domain\Enums\VacationRequestState;
use Toby\Domain\Enums\VacationType;
use Toby\Domain\Notifications\VacationRequestNotification;
use Toby\Domain\VacationRequestStateManager;
use Toby\Eloquent\Models\User;
use Toby\Eloquent\Models\VacationRequest;
@ -42,8 +39,8 @@ class VacationRequestStatesTest extends TestCase
/** @var VacationRequest $vacationRequest */
$vacationRequest = VacationRequest::factory([
"type" => VacationType::VACATION->value,
"state" => VacationRequestState::CREATED,
"type" => VacationType::Vacation->value,
"state" => VacationRequestState::Created,
"from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
"comment" => "Comment for the vacation request.",
@ -54,7 +51,7 @@ class VacationRequestStatesTest extends TestCase
$this->stateManager->waitForTechnical($vacationRequest);
$this->assertEquals(VacationRequestState::WAITING_FOR_TECHNICAL, $vacationRequest->state);
$this->assertEquals(VacationRequestState::WaitingForTechnical, $vacationRequest->state);
}
public function testAfterCreatingVacationRequestOfTypeSickVacationItTransitsToProperState(): void
@ -65,8 +62,8 @@ class VacationRequestStatesTest extends TestCase
/** @var VacationRequest $vacationRequest */
$vacationRequest = VacationRequest::factory([
"type" => VacationType::SICK_VACATION->value,
"state" => VacationRequestState::CREATED,
"type" => VacationType::Sick->value,
"state" => VacationRequestState::Created,
"from" => Carbon::create($currentYearPeriod->year, 2, 1)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 4)->toDateString(),
])
@ -76,7 +73,7 @@ class VacationRequestStatesTest extends TestCase
$this->stateManager->approve($vacationRequest);
$this->assertEquals(VacationRequestState::APPROVED, $vacationRequest->state);
$this->assertEquals(VacationRequestState::Approved, $vacationRequest->state);
}
public function testAfterCreatingVacationRequestOfTypeTimeInLieuItTransitsToProperState(): void
@ -87,8 +84,8 @@ class VacationRequestStatesTest extends TestCase
/** @var VacationRequest $vacationRequest */
$vacationRequest = VacationRequest::factory([
"type" => VacationType::TIME_IN_LIEU->value,
"state" => VacationRequestState::CREATED,
"type" => VacationType::TimeInLieu->value,
"state" => VacationRequestState::Created,
"from" => Carbon::create($currentYearPeriod->year, 2, 2)->toDateString(),
"to" => Carbon::create($currentYearPeriod->year, 2, 2)->toDateString(),
])
@ -98,6 +95,6 @@ class VacationRequestStatesTest extends TestCase
$this->stateManager->approve($vacationRequest);
$this->assertEquals(VacationRequestState::APPROVED, $vacationRequest->state);
$this->assertEquals(VacationRequestState::Approved, $vacationRequest->state);
}
}