*/ public function toAttributes(ReportRowDto $dto, ?int $createdBy = null): array { return [ 'employee_id' => $this->resolveEmployeeId($dto->employeeNumber), 'report_date' => $this->parseDate($dto->reportDate), 'title' => $dto->title, 'description' => $dto->description, 'severity' => $this->resolveSeverity($dto->severity), 'created_by' => $createdBy, ]; } /** * @return array */ public function validate(ReportRowDto $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->reportDate === null) { $errors[] = 'Report date is required.'; } if ($dto->title === null || trim($dto->title) === '') { $errors[] = 'Title is required.'; } return $errors; } public function isDuplicate(ReportRowDto $dto): bool { $employeeId = $this->resolveEmployeeId($dto->employeeNumber); $reportDate = $this->parseDate($dto->reportDate); if ($employeeId === null || $reportDate === null || $dto->title === null) { return false; } return DisciplinaryReport::query() ->where('employee_id', $employeeId) ->whereDate('report_date', $reportDate) ->where('title', $dto->title) ->exists(); } private function resolveEmployeeId(string $employeeNumber): ?int { return Employee::query() ->where('employee_number', $employeeNumber) ->value('id'); } private function resolveSeverity(?string $value): DisciplinarySeverity { if ($value === null || trim($value) === '') { return DisciplinarySeverity::Low; } $normalized = Str::lower(trim($value)); return DisciplinarySeverity::tryFrom($normalized) ?? DisciplinarySeverity::Low; } private function parseDate(?string $value): ?string { if ($value === null || trim($value) === '') { return null; } try { return \Carbon\Carbon::parse($value)->toDateString(); } catch (\Throwable) { return null; } } }