* #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:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
@@ -4,20 +4,21 @@ declare(strict_types=1);
|
||||
|
||||
namespace Toby\Domain;
|
||||
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
|
||||
use Toby\Eloquent\Models\User;
|
||||
|
||||
class TimesheetExport implements WithMultipleSheets
|
||||
{
|
||||
protected Collection $users;
|
||||
protected Collection $types;
|
||||
protected Carbon $month;
|
||||
|
||||
public function sheets(): array
|
||||
{
|
||||
return $this->users
|
||||
->map(fn(User $user) => new TimesheetPerUserSheet($user, $this->month))
|
||||
->map(fn(User $user) => new TimesheetPerUserSheet($user, $this->month, $this->types))
|
||||
->toArray();
|
||||
}
|
||||
|
||||
@@ -34,4 +35,11 @@ class TimesheetExport implements WithMultipleSheets
|
||||
|
||||
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\CarbonPeriod;
|
||||
use Generator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Maatwebsite\Excel\Concerns\FromGenerator;
|
||||
@@ -40,6 +41,7 @@ class TimesheetPerUserSheet implements WithTitle, WithHeadings, WithEvents, With
|
||||
public function __construct(
|
||||
protected User $user,
|
||||
protected Carbon $month,
|
||||
protected Collection $types,
|
||||
) {}
|
||||
|
||||
public function title(): string
|
||||
@@ -49,8 +51,6 @@ class TimesheetPerUserSheet implements WithTitle, WithHeadings, WithEvents, With
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
$types = VacationType::cases();
|
||||
|
||||
$headings = [
|
||||
__("Date"),
|
||||
__("Day of week"),
|
||||
@@ -59,7 +59,7 @@ class TimesheetPerUserSheet implements WithTitle, WithHeadings, WithEvents, With
|
||||
__("Worked hours"),
|
||||
];
|
||||
|
||||
foreach ($types as $type) {
|
||||
foreach ($this->types as $type) {
|
||||
$headings[] = $type->label();
|
||||
}
|
||||
|
||||
@@ -187,6 +187,7 @@ class TimesheetPerUserSheet implements WithTitle, WithHeadings, WithEvents, With
|
||||
{
|
||||
return $user->vacations()
|
||||
->with("vacationRequest")
|
||||
->whereRelation("vacationRequest", fn(Builder $query) => $query->whereIn("type", $this->types))
|
||||
->whereBetween("date", [$period->start, $period->end])
|
||||
->approved()
|
||||
->get()
|
||||
|
@@ -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));
|
||||
}
|
||||
|
@@ -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}");
|
||||
|
@@ -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));
|
||||
}
|
||||
|
@@ -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 Maatwebsite\Excel\Facades\Excel;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Toby\Domain\Enums\EmploymentForm;
|
||||
use Toby\Domain\Enums\Month;
|
||||
use Toby\Domain\Enums\VacationType;
|
||||
use Toby\Domain\TimesheetExport;
|
||||
use Toby\Domain\VacationTypeConfigRetriever;
|
||||
use Toby\Eloquent\Helpers\YearPeriodRetriever;
|
||||
use Toby\Eloquent\Models\User;
|
||||
|
||||
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");
|
||||
|
||||
$yearPeriod = $yearPeriodRetriever->selected();
|
||||
$carbonMonth = Carbon::create($yearPeriod->year, $month->toCarbonNumber());
|
||||
|
||||
$users = User::query()
|
||||
->where("employment_form", EmploymentForm::EmploymentContract)
|
||||
->orderBy("last_name")
|
||||
->orderBy("first_name")
|
||||
->get();
|
||||
|
||||
$types = VacationType::all()
|
||||
->filter(
|
||||
fn(VacationType $type) => $configRetriever->isAvailableFor($type, EmploymentForm::EmploymentContract),
|
||||
);
|
||||
|
||||
$filename = "{$carbonMonth->translatedFormat("F Y")}.xlsx";
|
||||
|
||||
$timesheet = (new TimesheetExport())
|
||||
->forMonth($carbonMonth)
|
||||
->forUsers($users);
|
||||
->forUsers($users)
|
||||
->forVacationTypes($types);
|
||||
|
||||
return Excel::download($timesheet, $filename);
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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"],
|
||||
];
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user