* #108 - wip * #108 - add icon to absence * #108 - wip * #108 - fix * #108 - fix title Co-authored-by: EwelinaLasowy <ewelina.lasowy@blumilk.pl>
This commit is contained in:
parent
fa244b96cd
commit
6af4380fe6
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Toby\Domain\Enums;
|
namespace Toby\Domain\Enums;
|
||||||
|
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
enum VacationType: string
|
enum VacationType: string
|
||||||
{
|
{
|
||||||
case Vacation = "vacation";
|
case Vacation = "vacation";
|
||||||
@ -15,6 +17,7 @@ enum VacationType: string
|
|||||||
case Volunteering = "volunteering_vacation";
|
case Volunteering = "volunteering_vacation";
|
||||||
case TimeInLieu = "time_in_lieu";
|
case TimeInLieu = "time_in_lieu";
|
||||||
case Sick = "sick_vacation";
|
case Sick = "sick_vacation";
|
||||||
|
case Absence = "absence";
|
||||||
|
|
||||||
public function label(): string
|
public function label(): string
|
||||||
{
|
{
|
||||||
@ -23,7 +26,7 @@ enum VacationType: string
|
|||||||
|
|
||||||
public static function casesToSelect(): array
|
public static function casesToSelect(): array
|
||||||
{
|
{
|
||||||
$cases = collect(VacationType::cases());
|
$cases = VacationType::all();
|
||||||
|
|
||||||
return $cases->map(
|
return $cases->map(
|
||||||
fn(VacationType $enum) => [
|
fn(VacationType $enum) => [
|
||||||
@ -32,4 +35,9 @@ enum VacationType: string
|
|||||||
],
|
],
|
||||||
)->toArray();
|
)->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function all(): Collection
|
||||||
|
{
|
||||||
|
return new Collection(VacationType::cases());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,20 +4,21 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Toby\Domain;
|
namespace Toby\Domain;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
|
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
|
||||||
use Toby\Eloquent\Models\User;
|
use Toby\Eloquent\Models\User;
|
||||||
|
|
||||||
class TimesheetExport implements WithMultipleSheets
|
class TimesheetExport implements WithMultipleSheets
|
||||||
{
|
{
|
||||||
protected Collection $users;
|
protected Collection $users;
|
||||||
|
protected Collection $types;
|
||||||
protected Carbon $month;
|
protected Carbon $month;
|
||||||
|
|
||||||
public function sheets(): array
|
public function sheets(): array
|
||||||
{
|
{
|
||||||
return $this->users
|
return $this->users
|
||||||
->map(fn(User $user) => new TimesheetPerUserSheet($user, $this->month))
|
->map(fn(User $user) => new TimesheetPerUserSheet($user, $this->month, $this->types))
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,4 +35,11 @@ class TimesheetExport implements WithMultipleSheets
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function forVacationTypes(Collection $types): static
|
||||||
|
{
|
||||||
|
$this->types = $types;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ namespace Toby\Domain;
|
|||||||
use Carbon\CarbonInterface;
|
use Carbon\CarbonInterface;
|
||||||
use Carbon\CarbonPeriod;
|
use Carbon\CarbonPeriod;
|
||||||
use Generator;
|
use Generator;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Maatwebsite\Excel\Concerns\FromGenerator;
|
use Maatwebsite\Excel\Concerns\FromGenerator;
|
||||||
@ -40,6 +41,7 @@ class TimesheetPerUserSheet implements WithTitle, WithHeadings, WithEvents, With
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
protected User $user,
|
protected User $user,
|
||||||
protected Carbon $month,
|
protected Carbon $month,
|
||||||
|
protected Collection $types,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public function title(): string
|
public function title(): string
|
||||||
@ -49,8 +51,6 @@ class TimesheetPerUserSheet implements WithTitle, WithHeadings, WithEvents, With
|
|||||||
|
|
||||||
public function headings(): array
|
public function headings(): array
|
||||||
{
|
{
|
||||||
$types = VacationType::cases();
|
|
||||||
|
|
||||||
$headings = [
|
$headings = [
|
||||||
__("Date"),
|
__("Date"),
|
||||||
__("Day of week"),
|
__("Day of week"),
|
||||||
@ -59,7 +59,7 @@ class TimesheetPerUserSheet implements WithTitle, WithHeadings, WithEvents, With
|
|||||||
__("Worked hours"),
|
__("Worked hours"),
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($types as $type) {
|
foreach ($this->types as $type) {
|
||||||
$headings[] = $type->label();
|
$headings[] = $type->label();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +187,7 @@ class TimesheetPerUserSheet implements WithTitle, WithHeadings, WithEvents, With
|
|||||||
{
|
{
|
||||||
return $user->vacations()
|
return $user->vacations()
|
||||||
->with("vacationRequest")
|
->with("vacationRequest")
|
||||||
|
->whereRelation("vacationRequest", fn(Builder $query) => $query->whereIn("type", $this->types))
|
||||||
->whereBetween("date", [$period->start, $period->end])
|
->whereBetween("date", [$period->start, $period->end])
|
||||||
->approved()
|
->approved()
|
||||||
->get()
|
->get()
|
||||||
|
@ -95,14 +95,14 @@ class UserVacationStatsRetriever
|
|||||||
|
|
||||||
protected function getLimitableVacationTypes(): Collection
|
protected function getLimitableVacationTypes(): Collection
|
||||||
{
|
{
|
||||||
$types = new Collection(VacationType::cases());
|
$types = VacationType::all();
|
||||||
|
|
||||||
return $types->filter(fn(VacationType $type) => $this->configRetriever->hasLimit($type));
|
return $types->filter(fn(VacationType $type) => $this->configRetriever->hasLimit($type));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getNotLimitableVacationTypes(): Collection
|
protected function getNotLimitableVacationTypes(): Collection
|
||||||
{
|
{
|
||||||
$types = new Collection(VacationType::cases());
|
$types = VacationType::all();
|
||||||
|
|
||||||
return $types->filter(fn(VacationType $type) => !$this->configRetriever->hasLimit($type));
|
return $types->filter(fn(VacationType $type) => !$this->configRetriever->hasLimit($type));
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace Toby\Domain;
|
namespace Toby\Domain;
|
||||||
|
|
||||||
use Illuminate\Contracts\Config\Repository;
|
use Illuminate\Contracts\Config\Repository;
|
||||||
|
use Toby\Domain\Enums\EmploymentForm;
|
||||||
use Toby\Domain\Enums\VacationType;
|
use Toby\Domain\Enums\VacationType;
|
||||||
|
|
||||||
class VacationTypeConfigRetriever
|
class VacationTypeConfigRetriever
|
||||||
@ -13,6 +14,7 @@ class VacationTypeConfigRetriever
|
|||||||
public const KEY_ADMINISTRATIVE_APPROVAL = "administrative_approval";
|
public const KEY_ADMINISTRATIVE_APPROVAL = "administrative_approval";
|
||||||
public const KEY_BILLABLE = "billable";
|
public const KEY_BILLABLE = "billable";
|
||||||
public const KEY_HAS_LIMIT = "has_limit";
|
public const KEY_HAS_LIMIT = "has_limit";
|
||||||
|
public const KEY_AVAILABLE_FOR = "available_for";
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected Repository $config,
|
protected Repository $config,
|
||||||
@ -38,6 +40,11 @@ class VacationTypeConfigRetriever
|
|||||||
return $this->getConfigFor($type)[static::KEY_HAS_LIMIT];
|
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
|
protected function getConfigFor(VacationType $type): array
|
||||||
{
|
{
|
||||||
return $this->config->get("vacation_types.{$type->value}");
|
return $this->config->get("vacation_types.{$type->value}");
|
||||||
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace Toby\Domain\Validation\Rules;
|
namespace Toby\Domain\Validation\Rules;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Toby\Domain\Enums\VacationType;
|
use Toby\Domain\Enums\VacationType;
|
||||||
use Toby\Domain\VacationDaysCalculator;
|
use Toby\Domain\VacationDaysCalculator;
|
||||||
use Toby\Domain\VacationRequestStatesRetriever;
|
use Toby\Domain\VacationRequestStatesRetriever;
|
||||||
@ -59,7 +59,7 @@ class DoesNotExceedLimitRule implements VacationRequestRule
|
|||||||
|
|
||||||
protected function getLimitableVacationTypes(): Collection
|
protected function getLimitableVacationTypes(): Collection
|
||||||
{
|
{
|
||||||
$types = new Collection(VacationType::cases());
|
$types = VacationType::all();
|
||||||
|
|
||||||
return $types->filter(fn(VacationType $type) => $this->configRetriever->hasLimit($type));
|
return $types->filter(fn(VacationType $type) => $this->configRetriever->hasLimit($type));
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Toby\Infrastructure\Http\Controllers\Api;
|
||||||
|
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Toby\Domain\Enums\VacationType;
|
||||||
|
use Toby\Domain\VacationTypeConfigRetriever;
|
||||||
|
use Toby\Eloquent\Models\User;
|
||||||
|
use Toby\Infrastructure\Http\Controllers\Controller;
|
||||||
|
use Toby\Infrastructure\Http\Requests\Api\GetAvailableVacationTypesRequest;
|
||||||
|
|
||||||
|
class GetAvailableVacationTypesController extends Controller
|
||||||
|
{
|
||||||
|
public function __invoke(
|
||||||
|
GetAvailableVacationTypesRequest $request,
|
||||||
|
VacationTypeConfigRetriever $configRetriever,
|
||||||
|
): JsonResponse {
|
||||||
|
/** @var User $user */
|
||||||
|
$user = User::query()->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);
|
||||||
|
}
|
||||||
|
}
|
@ -7,30 +7,43 @@ namespace Toby\Infrastructure\Http\Controllers;
|
|||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Maatwebsite\Excel\Facades\Excel;
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
|
use Toby\Domain\Enums\EmploymentForm;
|
||||||
use Toby\Domain\Enums\Month;
|
use Toby\Domain\Enums\Month;
|
||||||
|
use Toby\Domain\Enums\VacationType;
|
||||||
use Toby\Domain\TimesheetExport;
|
use Toby\Domain\TimesheetExport;
|
||||||
|
use Toby\Domain\VacationTypeConfigRetriever;
|
||||||
use Toby\Eloquent\Helpers\YearPeriodRetriever;
|
use Toby\Eloquent\Helpers\YearPeriodRetriever;
|
||||||
use Toby\Eloquent\Models\User;
|
use Toby\Eloquent\Models\User;
|
||||||
|
|
||||||
class TimesheetController extends Controller
|
class TimesheetController extends Controller
|
||||||
{
|
{
|
||||||
public function __invoke(Month $month, YearPeriodRetriever $yearPeriodRetriever): BinaryFileResponse
|
public function __invoke(
|
||||||
{
|
Month $month,
|
||||||
|
YearPeriodRetriever $yearPeriodRetriever,
|
||||||
|
VacationTypeConfigRetriever $configRetriever,
|
||||||
|
): BinaryFileResponse {
|
||||||
$this->authorize("generateTimesheet");
|
$this->authorize("generateTimesheet");
|
||||||
|
|
||||||
$yearPeriod = $yearPeriodRetriever->selected();
|
$yearPeriod = $yearPeriodRetriever->selected();
|
||||||
$carbonMonth = Carbon::create($yearPeriod->year, $month->toCarbonNumber());
|
$carbonMonth = Carbon::create($yearPeriod->year, $month->toCarbonNumber());
|
||||||
|
|
||||||
$users = User::query()
|
$users = User::query()
|
||||||
|
->where("employment_form", EmploymentForm::EmploymentContract)
|
||||||
->orderBy("last_name")
|
->orderBy("last_name")
|
||||||
->orderBy("first_name")
|
->orderBy("first_name")
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
$types = VacationType::all()
|
||||||
|
->filter(
|
||||||
|
fn(VacationType $type) => $configRetriever->isAvailableFor($type, EmploymentForm::EmploymentContract),
|
||||||
|
);
|
||||||
|
|
||||||
$filename = "{$carbonMonth->translatedFormat("F Y")}.xlsx";
|
$filename = "{$carbonMonth->translatedFormat("F Y")}.xlsx";
|
||||||
|
|
||||||
$timesheet = (new TimesheetExport())
|
$timesheet = (new TimesheetExport())
|
||||||
->forMonth($carbonMonth)
|
->forMonth($carbonMonth)
|
||||||
->forUsers($users);
|
->forUsers($users)
|
||||||
|
->forVacationTypes($types);
|
||||||
|
|
||||||
return Excel::download($timesheet, $filename);
|
return Excel::download($timesheet, $filename);
|
||||||
}
|
}
|
||||||
|
@ -158,10 +158,7 @@ class VacationRequestController extends Controller
|
|||||||
|
|
||||||
public function create(Request $request, YearPeriodRetriever $yearPeriodRetriever): Response
|
public function create(Request $request, YearPeriodRetriever $yearPeriodRetriever): Response
|
||||||
{
|
{
|
||||||
$yearPeriod = $yearPeriodRetriever->selected();
|
|
||||||
|
|
||||||
$users = User::query()
|
$users = User::query()
|
||||||
->withVacationLimitIn($yearPeriod)
|
|
||||||
->orderBy("last_name")
|
->orderBy("last_name")
|
||||||
->orderBy("first_name")
|
->orderBy("first_name")
|
||||||
->get();
|
->get();
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Toby\Infrastructure\Http\Requests\Api;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class GetAvailableVacationTypesRequest extends FormRequest
|
||||||
|
{
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
"user" => ["required", "exists:users,id"],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Toby\Domain\Enums\EmploymentForm;
|
||||||
use Toby\Domain\Enums\VacationType;
|
use Toby\Domain\Enums\VacationType;
|
||||||
use Toby\Domain\VacationTypeConfigRetriever;
|
use Toby\Domain\VacationTypeConfigRetriever;
|
||||||
|
|
||||||
@ -11,53 +12,100 @@ return [
|
|||||||
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
||||||
VacationTypeConfigRetriever::KEY_HAS_LIMIT => true,
|
VacationTypeConfigRetriever::KEY_HAS_LIMIT => true,
|
||||||
|
VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [
|
||||||
|
EmploymentForm::EmploymentContract,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
VacationType::OnRequest->value => [
|
VacationType::OnRequest->value => [
|
||||||
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
||||||
VacationTypeConfigRetriever::KEY_HAS_LIMIT => true,
|
VacationTypeConfigRetriever::KEY_HAS_LIMIT => true,
|
||||||
|
VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [
|
||||||
|
EmploymentForm::EmploymentContract,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
VacationType::TimeInLieu->value => [
|
VacationType::TimeInLieu->value => [
|
||||||
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => false,
|
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => false,
|
||||||
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => false,
|
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => false,
|
||||||
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
||||||
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
||||||
|
VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [
|
||||||
|
EmploymentForm::EmploymentContract,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
VacationType::Sick->value => [
|
VacationType::Sick->value => [
|
||||||
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => false,
|
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => false,
|
||||||
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
||||||
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
||||||
|
VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [
|
||||||
|
EmploymentForm::EmploymentContract,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
VacationType::Unpaid->value => [
|
VacationType::Unpaid->value => [
|
||||||
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_BILLABLE => false,
|
VacationTypeConfigRetriever::KEY_BILLABLE => false,
|
||||||
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
||||||
|
VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [
|
||||||
|
EmploymentForm::EmploymentContract,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
VacationType::Special->value => [
|
VacationType::Special->value => [
|
||||||
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_BILLABLE => false,
|
VacationTypeConfigRetriever::KEY_BILLABLE => false,
|
||||||
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
||||||
|
VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [
|
||||||
|
EmploymentForm::EmploymentContract,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
VacationType::Childcare->value => [
|
VacationType::Childcare->value => [
|
||||||
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_BILLABLE => false,
|
VacationTypeConfigRetriever::KEY_BILLABLE => false,
|
||||||
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
||||||
|
VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [
|
||||||
|
EmploymentForm::EmploymentContract,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
VacationType::Training->value => [
|
VacationType::Training->value => [
|
||||||
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
||||||
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
||||||
|
VacationTypeConfigRetriever::KEY_AVAILABLE_FOR => [
|
||||||
|
EmploymentForm::EmploymentContract,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
VacationType::Volunteering->value => [
|
VacationType::Volunteering->value => [
|
||||||
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_TECHNICAL_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
VacationTypeConfigRetriever::KEY_ADMINISTRATIVE_APPROVAL => true,
|
||||||
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
VacationTypeConfigRetriever::KEY_BILLABLE => true,
|
||||||
VacationTypeConfigRetriever::KEY_HAS_LIMIT => false,
|
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,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@ -7,6 +7,7 @@ import CurrencyUsdOffIcon from 'vue-material-design-icons/CurrencyUsdOff.vue'
|
|||||||
import HandHeartOutlineIcon from 'vue-material-design-icons/HandHeartOutline.vue'
|
import HandHeartOutlineIcon from 'vue-material-design-icons/HandHeartOutline.vue'
|
||||||
import CalendarCheckIcon from 'vue-material-design-icons/CalendarCheck.vue'
|
import CalendarCheckIcon from 'vue-material-design-icons/CalendarCheck.vue'
|
||||||
import MedicalBagIcon from 'vue-material-design-icons/MedicalBag.vue'
|
import MedicalBagIcon from 'vue-material-design-icons/MedicalBag.vue'
|
||||||
|
import CalendarRemoveIcon from 'vue-material-design-icons/CalendarRemove.vue'
|
||||||
|
|
||||||
const types = [
|
const types = [
|
||||||
{
|
{
|
||||||
@ -63,6 +64,12 @@ const types = [
|
|||||||
icon: MedicalBagIcon,
|
icon: MedicalBagIcon,
|
||||||
color: 'text-rose-500',
|
color: 'text-rose-500',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: 'Nieobecność',
|
||||||
|
value: 'absence',
|
||||||
|
icon: CalendarRemoveIcon,
|
||||||
|
color: 'text-cyan-500',
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export default function useVacationTypeInfo() {
|
export default function useVacationTypeInfo() {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<h2 class="text-lg font-medium leading-6 text-gray-900">
|
<h2 class="text-lg font-medium leading-6 text-gray-900">
|
||||||
Wykorzystanie miesięczne urlopu wypoczynkowego
|
Wykorzystanie miesięczne urlopu
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
scope="col"
|
scope="col"
|
||||||
class="py-3 px-4 text-xs font-semibold tracking-wider text-left text-gray-500 uppercase whitespace-nowrap"
|
class="py-3 px-4 text-xs font-semibold tracking-wider text-left text-gray-500 uppercase whitespace-nowrap"
|
||||||
>
|
>
|
||||||
Posiada urlop?
|
Posiada limit?
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<InertiaHead title="Złóż wniosek urlopowy" />
|
<InertiaHead title="Złóż wniosek" />
|
||||||
<div class="grid grid-cols-1 gap-4 items-start xl:grid-cols-3 xl:gap-8">
|
<div class="grid grid-cols-1 gap-4 items-start xl:grid-cols-3 xl:gap-8">
|
||||||
<div class="flex flex-col h-full bg-white shadow-md xl:col-span-2">
|
<div class="flex flex-col h-full bg-white shadow-md xl:col-span-2">
|
||||||
<div class="p-4 sm:px-6">
|
<div class="p-4 sm:px-6">
|
||||||
<h2 class="text-lg font-medium leading-6 text-gray-900">
|
<h2 class="text-lg font-medium leading-6 text-gray-900">
|
||||||
Złóż wniosek urlopowy
|
Złóż wniosek
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<form
|
<form
|
||||||
@ -42,8 +42,8 @@
|
|||||||
</ListboxLabel>
|
</ListboxLabel>
|
||||||
<div class="relative mt-1 sm:col-span-2 sm:mt-0">
|
<div class="relative mt-1 sm:col-span-2 sm:mt-0">
|
||||||
<ListboxButton
|
<ListboxButton
|
||||||
class="relative py-2 pr-10 pl-3 w-full max-w-lg text-left bg-white rounded-md border focus:ring-1 shadow-sm cursor-default sm:text-sm"
|
class="relative py-2 pr-10 pl-3 w-full max-w-lg text-left bg-white rounded-md border focus:outline-none focus:ring-1 shadow-sm cursor-default sm:text-sm"
|
||||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.user, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.user }"
|
:class="{ 'border-red-300 text-red-900 focus:ring-red-500 focus:border-red-500': form.errors.user, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.user }"
|
||||||
>
|
>
|
||||||
<span class="flex items-center">
|
<span class="flex items-center">
|
||||||
<img
|
<img
|
||||||
@ -63,7 +63,7 @@
|
|||||||
leave-to-class="opacity-0"
|
leave-to-class="opacity-0"
|
||||||
>
|
>
|
||||||
<ListboxOptions
|
<ListboxOptions
|
||||||
class="overflow-auto absolute z-10 py-1 mt-1 w-full max-w-lg max-h-60 text-base bg-white rounded-md focus:outline-none ring-1 ring-black ring-opacity-5 shadow-lg sm:text-sm"
|
class="overflow-auto absolute z-10 py-1 mt-1 w-full max-w-lg max-h-60 text-base bg-white rounded-md focus:outline-none ring-1 focus:ring-blumilk-500 ring-opacity-5 shadow-lg sm:text-sm"
|
||||||
>
|
>
|
||||||
<ListboxOption
|
<ListboxOption
|
||||||
v-for="user in users.data"
|
v-for="user in users.data"
|
||||||
@ -134,24 +134,29 @@
|
|||||||
class="items-center py-4 sm:grid sm:grid-cols-3"
|
class="items-center py-4 sm:grid sm:grid-cols-3"
|
||||||
>
|
>
|
||||||
<ListboxLabel class="block text-sm font-medium text-gray-700">
|
<ListboxLabel class="block text-sm font-medium text-gray-700">
|
||||||
Rodzaj urlopu
|
Typ wniosku
|
||||||
</ListboxLabel>
|
</ListboxLabel>
|
||||||
<div class="relative mt-1 sm:col-span-2 sm:mt-0">
|
<div class="relative mt-1 sm:col-span-2 sm:mt-0">
|
||||||
<ListboxButton
|
<ListboxButton
|
||||||
class="relative py-2 pr-10 pl-3 w-full max-w-lg text-left bg-white rounded-md border focus:ring-1 shadow-sm cursor-default sm:text-sm"
|
class="relative py-2 pr-10 pl-3 w-full max-w-lg text-left bg-white rounded-md border focus:outline-none focus:ring-1 shadow-sm cursor-default sm:text-sm"
|
||||||
:class="{ 'border-red-300 text-red-900 focus:outline-none focus:ring-red-500 focus:border-red-500': form.errors.type, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.type }"
|
:class="{ 'border-red-300 text-red-900 focus:ring-red-500 focus:border-red-500': form.errors.type, 'focus:ring-blumilk-500 focus:border-blumilk-500 sm:text-sm border-gray-300': !form.errors.type }"
|
||||||
>
|
>
|
||||||
<span class="block truncate">{{ form.vacationType.label }}</span>
|
<template v-if="form.vacationType">
|
||||||
<span class="flex absolute inset-y-0 right-0 items-center pr-2 pointer-events-none">
|
<span class="block truncate">{{ form.vacationType.label }}</span>
|
||||||
<SelectorIcon class="w-5 h-5 text-gray-400" />
|
<span class="flex absolute inset-y-0 right-0 items-center pr-2 pointer-events-none">
|
||||||
</span>
|
<SelectorIcon class="w-5 h-5 text-gray-400" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
Ładowanie...
|
||||||
|
</template>
|
||||||
</ListboxButton>
|
</ListboxButton>
|
||||||
<transition
|
<transition
|
||||||
leave-active-class="transition ease-in duration-100"
|
leave-active-class="transition ease-in duration-100"
|
||||||
leave-from-class="opacity-100"
|
leave-from-class="opacity-100"
|
||||||
leave-to-class="opacity-0"
|
leave-to-class="opacity-0"
|
||||||
>
|
>
|
||||||
<ListboxOptions class="overflow-auto absolute z-10 py-1 mt-1 w-full max-w-lg max-h-60 text-base bg-white rounded-md focus:outline-none ring-1 ring-black ring-opacity-5 shadow-lg sm:text-sm">
|
<ListboxOptions class="overflow-auto absolute z-10 py-1 mt-1 w-full max-w-lg max-h-60 text-base bg-white rounded-md focus:outline-none ring-1 focus:ring-blumilk-500 ring-opacity-5 shadow-lg sm:text-sm">
|
||||||
<ListboxOption
|
<ListboxOption
|
||||||
v-for="vacationType in vacationTypes"
|
v-for="vacationType in vacationTypes"
|
||||||
:key="vacationType.value"
|
:key="vacationType.value"
|
||||||
@ -187,7 +192,7 @@
|
|||||||
for="date_from"
|
for="date_from"
|
||||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||||
>
|
>
|
||||||
Planowany urlop od
|
Data od
|
||||||
</label>
|
</label>
|
||||||
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
||||||
<FlatPickr
|
<FlatPickr
|
||||||
@ -212,7 +217,7 @@
|
|||||||
for="date_from"
|
for="date_from"
|
||||||
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
class="block text-sm font-medium text-gray-700 sm:mt-px"
|
||||||
>
|
>
|
||||||
Planowany urlop do
|
Data do
|
||||||
</label>
|
</label>
|
||||||
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
<div class="mt-1 sm:col-span-2 sm:mt-0">
|
||||||
<FlatPickr
|
<FlatPickr
|
||||||
@ -233,7 +238,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="items-center py-4 sm:grid sm:grid-cols-3">
|
<div class="items-center py-4 sm:grid sm:grid-cols-3">
|
||||||
<span class="block text-sm font-medium text-gray-700 sm:mt-px">Liczba dni urlopu</span>
|
<span class="block text-sm font-medium text-gray-700 sm:mt-px">Liczba dni</span>
|
||||||
<div
|
<div
|
||||||
class="inline-flex items-center py-2 px-4 mt-1 w-full max-w-lg text-gray-500 bg-gray-50 rounded-md border border-gray-300 sm:col-span-2 sm:mt-0 sm:text-sm"
|
class="inline-flex items-center py-2 px-4 mt-1 w-full max-w-lg text-gray-500 bg-gray-50 rounded-md border border-gray-300 sm:col-span-2 sm:mt-0 sm:text-sm"
|
||||||
>
|
>
|
||||||
@ -303,10 +308,10 @@
|
|||||||
<div class="p-4 sm:px-6">
|
<div class="p-4 sm:px-6">
|
||||||
<h2 class="text-lg font-medium leading-6 text-gray-900">
|
<h2 class="text-lg font-medium leading-6 text-gray-900">
|
||||||
<span v-if="auth.user.id !== form.user.id">
|
<span v-if="auth.user.id !== form.user.id">
|
||||||
Urlop wypoczynkowy, dane dla: {{ form.user.name }}
|
Dane urlopowe dla: {{ form.user.name }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
Twoje dane o urlopie wypoczynkowym
|
Twoje dane o urlopie
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
@ -330,7 +335,6 @@ import VacationChart from '@/Shared/VacationChart'
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
auth: Object,
|
auth: Object,
|
||||||
users: Object,
|
users: Object,
|
||||||
vacationTypes: Object,
|
|
||||||
holidays: Object,
|
holidays: Object,
|
||||||
can: Object,
|
can: Object,
|
||||||
})
|
})
|
||||||
@ -341,12 +345,13 @@ const form = useForm({
|
|||||||
: props.auth.user,
|
: props.auth.user,
|
||||||
from: null,
|
from: null,
|
||||||
to: null,
|
to: null,
|
||||||
vacationType: props.vacationTypes[0],
|
vacationType: null,
|
||||||
comment: null,
|
comment: null,
|
||||||
flowSkipped: false,
|
flowSkipped: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const estimatedDays = ref([])
|
const estimatedDays = ref([])
|
||||||
|
const vacationTypes = ref([])
|
||||||
|
|
||||||
const stats = ref({
|
const stats = ref({
|
||||||
used: 0,
|
used: 0,
|
||||||
@ -372,8 +377,9 @@ const toInputConfig = reactive({
|
|||||||
|
|
||||||
watch(() => form.user, user => {
|
watch(() => form.user, user => {
|
||||||
resetForm()
|
resetForm()
|
||||||
refreshVacationStats(user)
|
refreshAvailableTypes(user)
|
||||||
refreshUnavailableDays(user)
|
refreshUnavailableDays(user)
|
||||||
|
refreshVacationStats(user)
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
function createForm() {
|
function createForm() {
|
||||||
@ -406,7 +412,7 @@ function onToChange(selectedDates, dateStr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function resetForm() {
|
function resetForm() {
|
||||||
form.reset('type', 'to', 'from', 'comment', 'flowSkipped')
|
form.reset('to', 'from', 'comment', 'flowSkipped')
|
||||||
form.clearErrors()
|
form.clearErrors()
|
||||||
estimatedDays.value = []
|
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]
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<InertiaHead title="Moje wnioski urlopowe" />
|
<InertiaHead title="Moje wnioski" />
|
||||||
<div class="bg-white shadow-md">
|
<div class="bg-white shadow-md">
|
||||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||||
<h2 class="text-lg font-medium leading-6 text-gray-900">
|
<h2 class="text-lg font-medium leading-6 text-gray-900">
|
||||||
Moje wnioski urlopowe
|
Moje wnioski
|
||||||
</h2>
|
</h2>
|
||||||
<div>
|
<div>
|
||||||
<InertiaLink
|
<InertiaLink
|
||||||
@ -102,7 +102,7 @@
|
|||||||
scope="col"
|
scope="col"
|
||||||
class="py-3 px-4 text-xs font-semibold tracking-wider text-left text-gray-500 uppercase whitespace-nowrap"
|
class="py-3 px-4 text-xs font-semibold tracking-wider text-left text-gray-500 uppercase whitespace-nowrap"
|
||||||
>
|
>
|
||||||
Rodzaj urlopu
|
Rodzaj wniosku
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<InertiaHead title="Wnioski urlopowe" />
|
<InertiaHead title="Lista wniosków" />
|
||||||
<div class="bg-white shadow-md">
|
<div class="bg-white shadow-md">
|
||||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-lg font-medium leading-6 text-gray-900">
|
<h2 class="text-lg font-medium leading-6 text-gray-900">
|
||||||
Wnioski urlopowe
|
Lista wniosków
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@ -181,7 +181,7 @@
|
|||||||
scope="col"
|
scope="col"
|
||||||
class="py-3 px-4 text-xs font-semibold tracking-wider text-left text-gray-500 uppercase whitespace-nowrap"
|
class="py-3 px-4 text-xs font-semibold tracking-wider text-left text-gray-500 uppercase whitespace-nowrap"
|
||||||
>
|
>
|
||||||
Rodzaj urlopu
|
Rodzaj wniosku
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:px-6">
|
<div class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:py-5 sm:px-6">
|
||||||
<dt class="text-sm font-medium text-gray-500">
|
<dt class="text-sm font-medium text-gray-500">
|
||||||
Rodzaj urlopu
|
Rodzaj wniosku
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
|
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
|
||||||
<VacationType :type="request.type" />
|
<VacationType :type="request.type" />
|
||||||
|
@ -301,7 +301,7 @@ const navigation = computed(() =>
|
|||||||
can: true,
|
can: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Wnioski urlopowe',
|
name: 'Lista wniosków',
|
||||||
href: '/vacation/requests',
|
href: '/vacation/requests',
|
||||||
component: 'VacationRequest/IndexForApprovers',
|
component: 'VacationRequest/IndexForApprovers',
|
||||||
icon: CollectionIcon,
|
icon: CollectionIcon,
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"look_for_work_vacation": "Urlop na poszukiwanie pracy",
|
"look_for_work_vacation": "Urlop na poszukiwanie pracy",
|
||||||
"time_in_lieu": "Odbiór za święto",
|
"time_in_lieu": "Odbiór za święto",
|
||||||
"sick_vacation": "Zwolnienie lekarskie",
|
"sick_vacation": "Zwolnienie lekarskie",
|
||||||
|
"absence": "Nieobecność",
|
||||||
"employee": "Pracownik",
|
"employee": "Pracownik",
|
||||||
"administrator": "Administrator",
|
"administrator": "Administrator",
|
||||||
"technical_approver": "Techniczny akceptujący",
|
"technical_approver": "Techniczny akceptujący",
|
||||||
|
@ -6,9 +6,11 @@ use Illuminate\Support\Facades\Route;
|
|||||||
use Toby\Infrastructure\Http\Controllers\Api\CalculateUserUnavailableDaysController;
|
use Toby\Infrastructure\Http\Controllers\Api\CalculateUserUnavailableDaysController;
|
||||||
use Toby\Infrastructure\Http\Controllers\Api\CalculateUserVacationStatsController;
|
use Toby\Infrastructure\Http\Controllers\Api\CalculateUserVacationStatsController;
|
||||||
use Toby\Infrastructure\Http\Controllers\Api\CalculateVacationDaysController;
|
use Toby\Infrastructure\Http\Controllers\Api\CalculateVacationDaysController;
|
||||||
|
use Toby\Infrastructure\Http\Controllers\Api\GetAvailableVacationTypesController;
|
||||||
|
|
||||||
Route::middleware("auth:sanctum")->group(function (): void {
|
Route::middleware("auth:sanctum")->group(function (): void {
|
||||||
Route::post("vacation/calculate-days", CalculateVacationDaysController::class);
|
Route::post("vacation/calculate-days", CalculateVacationDaysController::class);
|
||||||
Route::post("vacation/calculate-stats", CalculateUserVacationStatsController::class);
|
Route::post("vacation/calculate-stats", CalculateUserVacationStatsController::class);
|
||||||
Route::post("vacation/calculate-unavailable-days", CalculateUserUnavailableDaysController::class);
|
Route::post("vacation/calculate-unavailable-days", CalculateUserUnavailableDaysController::class);
|
||||||
|
Route::post("vacation/get-available-vacation-types", GetAvailableVacationTypesController::class);
|
||||||
});
|
});
|
||||||
|
@ -6,6 +6,7 @@ namespace Tests\Feature;
|
|||||||
|
|
||||||
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
||||||
use Tests\FeatureTestCase;
|
use Tests\FeatureTestCase;
|
||||||
|
use Toby\Domain\Enums\EmploymentForm;
|
||||||
use Toby\Eloquent\Models\User;
|
use Toby\Eloquent\Models\User;
|
||||||
|
|
||||||
class VacationCalendarTest extends FeatureTestCase
|
class VacationCalendarTest extends FeatureTestCase
|
||||||
@ -16,6 +17,10 @@ class VacationCalendarTest extends FeatureTestCase
|
|||||||
{
|
{
|
||||||
$administrativeApprover = User::factory()->administrativeApprover()->create();
|
$administrativeApprover = User::factory()->administrativeApprover()->create();
|
||||||
|
|
||||||
|
User::factory(["employment_form" => EmploymentForm::EmploymentContract])
|
||||||
|
->count(10)
|
||||||
|
->create();
|
||||||
|
|
||||||
$this->actingAs($administrativeApprover)
|
$this->actingAs($administrativeApprover)
|
||||||
->get("/vacation/timesheet/january")
|
->get("/vacation/timesheet/january")
|
||||||
->assertOk();
|
->assertOk();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user