Files
onboard/app/Exports/DutyReportExport.php
2026-07-06 07:37:53 +00:00

114 lines
4.0 KiB
PHP

<?php
namespace App\Exports;
use App\Models\Department;
use App\Models\User;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
class DutyReportExport
{
private const RU_MONTHS = [
1 => 'январь', 2 => 'февраль', 3 => 'март', 4 => 'апрель',
5 => 'май', 6 => 'июнь', 7 => 'июль', 8 => 'август',
9 => 'сентябрь', 10 => 'октябрь', 11 => 'ноябрь', 12 => 'декабрь',
];
public function __construct(
protected array $patients,
protected array $dateRange,
protected User $user,
protected Department $department,
protected string $reportName = 'Отчёт дежурного врача по приёмному покою и отделению',
) {}
/**
* Данные для Blade-шаблона PDF-отчёта.
*/
public function toViewData(): array
{
$patients = collect($this->patients);
$endDate = Carbon::parse($this->dateRange[1]);
return [
'title' => sprintf('%s «%s»', $this->reportName, $this->department->name_full ?? $this->department->name_short),
'day' => $endDate->format('d'),
'month' => self::RU_MONTHS[(int) $endDate->format('n')],
'year' => $endDate->format('Y'),
'planned' => $this->urgencyGroup($patients, 'planned'),
'urgent' => $this->urgencyGroup($patients, 'urgent'),
'inDepartment' => $patients->where('period_flags.current_at_end', true)->count(),
'plannedOperations' => $this->operationsGroup($patients, [6]),
'urgentOperations' => $this->operationsGroup($patients, [4, 5]),
'reanimation' => $this->flagGroup($patients, 'in_reanimation'),
'observableCount' => $patients->where('in_observable', true)->count(),
'deceased' => $this->flagGroup($patients, 'period_flags.deceased'),
];
}
private function urgencyGroup(Collection $patients, string $flag): array
{
$filtered = $patients
->where('period_flags.current_at_end', true)
->where("period_flags.{$flag}", true)
->values();
return [
'count' => $filtered->count(),
'patients' => $filtered->map(fn (array $p) => $this->presentPatient($p))->all(),
];
}
private function operationsGroup(Collection $patients, array $urgentStatuses): array
{
$filtered = $patients->filter(function (array $p) use ($urgentStatuses) {
return collect($p['operations'] ?? [])->whereIn('urgent_status', $urgentStatuses)->isNotEmpty();
})->values();
return [
'count' => $filtered->count(),
'patients' => $filtered->map(fn (array $p) => $this->presentPatient($p, withDiagnosis: false))->all(),
];
}
private function flagGroup(Collection $patients, string $flag): array
{
$filtered = $patients->where($flag, true)->values();
return [
'count' => $filtered->count(),
'patients' => $filtered->map(fn (array $p) => $this->presentPatient($p))->all(),
];
}
private function presentPatient(array $patient, bool $withDiagnosis = true): array
{
$age = ! empty($patient['birth_date'])
? Carbon::parse($patient['birth_date'])->diffInYears(Carbon::parse($this->dateRange[1]))
: null;
return [
'full_name' => $patient['full_name'],
'age' => $age !== null ? "{$age} ".$this->pluralizeAge($age) : '',
'diagnosis' => $withDiagnosis ? (data_get($patient, 'latest_migration.diagnosis_name') ?? '') : null,
];
}
private function pluralizeAge(int $age): string
{
$mod100 = $age % 100;
$mod10 = $age % 10;
if ($mod100 >= 11 && $mod100 <= 14) {
return 'лет';
}
return match ($mod10) {
1 => 'год',
2, 3, 4 => 'года',
default => 'лет',
};
}
}