Files
hr/app/Services/Import/VacationImportTransformer.php
2026-07-30 17:24:40 +05:00

124 lines
3.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services\Import;
use App\DTOs\Import\VacationRowDto;
use App\Enums\ApprovalStatus;
use App\Enums\VacationType;
use App\Models\Employee;
use App\Models\Vacation;
use Carbon\Carbon;
use Illuminate\Support\Str;
class VacationImportTransformer
{
/**
* @return array<string, mixed>
*/
public function toAttributes(VacationRowDto $dto): array
{
$employeeId = $this->resolveEmployeeId($dto->employeeNumber);
return [
'employee_id' => $employeeId,
'type' => $this->resolveType($dto->type),
'start_date' => $this->parseDate($dto->startDate),
'end_date' => $this->parseDate($dto->endDate),
'return_date' => $this->parseDate($dto->returnDate),
'days' => $dto->days,
'status' => $this->resolveStatus($dto->status),
'reason' => $dto->reason,
];
}
/**
* @return array<int, string>
*/
public function validate(VacationRowDto $dto): array
{
$errors = [];
if ($dto->employeeNumber === '') {
$errors[] = 'Employee number is required.';
} elseif ($this->resolveEmployeeId($dto->employeeNumber) === null) {
$errors[] = "Employee \"{$dto->employeeNumber}\" was not found.";
}
if ($dto->startDate === null) {
$errors[] = 'Start date is required.';
}
if ($dto->endDate === null) {
$errors[] = 'End date is required.';
}
return $errors;
}
public function isDuplicate(VacationRowDto $dto): bool
{
$employeeId = $this->resolveEmployeeId($dto->employeeNumber);
if ($employeeId === null) {
return false;
}
$startDate = $this->parseDate($dto->startDate);
$endDate = $this->parseDate($dto->endDate);
if ($startDate === null || $endDate === null) {
return false;
}
return Vacation::query()
->where('employee_id', $employeeId)
->whereDate('start_date', $startDate)
->whereDate('end_date', $endDate)
->exists();
}
private function resolveEmployeeId(string $employeeNumber): ?int
{
return Employee::query()
->where('employee_number', $employeeNumber)
->value('id');
}
private function resolveType(?string $value): VacationType
{
if ($value === null || trim($value) === '') {
return VacationType::Annual;
}
$normalized = Str::lower(trim($value));
return VacationType::tryFrom($normalized) ?? VacationType::Annual;
}
private function resolveStatus(?string $value): ApprovalStatus
{
if ($value === null || trim($value) === '') {
return ApprovalStatus::Pending;
}
$normalized = Str::lower(trim($value));
return ApprovalStatus::tryFrom($normalized) ?? ApprovalStatus::Pending;
}
private function parseDate(?string $value): ?string
{
if ($value === null || trim($value) === '') {
return null;
}
try {
return Carbon::parse($value)->toDateString();
} catch (\Throwable) {
return null;
}
}
}