*/ public function toAttributes(EmployeeRowDto $dto): array { return [ 'employee_number' => $dto->employeeNumber, 'full_name' => $dto->fullName, 'national_id' => $dto->nationalId, 'gender' => $this->resolveGender($dto->gender), 'birth_date' => $this->parseDate($dto->birthDate), 'phone' => $dto->phone ?? config('hr.default_phone'), 'address' => $dto->address, 'department_id' => $this->resolveDepartmentId($dto->department), 'position_id' => $this->resolvePositionId($dto->position), 'shift_id' => $this->resolveShiftId($dto->shift), 'employment_status' => $this->resolveEmploymentStatus($dto->employmentStatus), 'hire_date' => $this->parseDate($dto->hireDate), 'notes' => $dto->notes, ]; } /** * @return array */ public function validate(EmployeeRowDto $dto): array { $errors = []; if ($dto->employeeNumber === '') { $errors[] = 'Employee number is required.'; } if ($dto->fullName === '') { $errors[] = 'Full name is required.'; } if ($dto->department && $this->resolveDepartmentId($dto->department) === null) { $errors[] = "Department \"{$dto->department}\" was not found."; } if ($dto->position && $this->resolvePositionId($dto->position) === null) { $errors[] = "Position \"{$dto->position}\" was not found."; } if ($dto->shift && $this->resolveShiftId($dto->shift) === null) { $errors[] = "Shift \"{$dto->shift}\" was not found."; } return $errors; } public function isDuplicate(EmployeeRowDto $dto): bool { return Employee::query() ->where(function ($query) use ($dto): void { $query->where('employee_number', $dto->employeeNumber); if ($dto->nationalId) { $query->orWhere('national_id', $dto->nationalId); } }) ->exists(); } private function resolveGender(?string $value): ?Gender { if ($value === null) { return null; } $normalized = Str::lower(trim($value)); return Gender::tryFrom($normalized) ?? match ($normalized) { 'm', 'man' => Gender::Male, 'f', 'woman' => Gender::Female, default => null, }; } private function resolveEmploymentStatus(?string $value): EmploymentStatus { if ($value === null || trim($value) === '') { return EmploymentStatus::Active; } $normalized = Str::lower(str_replace(' ', '_', trim($value))); return EmploymentStatus::tryFrom($normalized) ?? EmploymentStatus::Active; } private function resolveDepartmentId(?string $value): ?int { if ($value === null || trim($value) === '') { return null; } return Department::query() ->where('name', $value) ->orWhere('code', $value) ->value('id'); } private function resolvePositionId(?string $value): ?int { if ($value === null || trim($value) === '') { return null; } return Position::query()->where('name', $value)->value('id'); } private function resolveShiftId(?string $value): ?int { if ($value === null || trim($value) === '') { return null; } return Shift::query() ->where('name', $value) ->orWhere('code', $value) ->value('id'); } private function parseDate(?string $value): ?string { if ($value === null || trim($value) === '') { return null; } try { return Carbon::parse($value)->toDateString(); } catch (\Throwable) { return null; } } }