fn($q) => $q->where(function ($q) use ($dateRange) { // Вариант А: Пациент уже лежит (текущий) $q->whereNull('out_date') ->whereNotNull('medical_history_id') ->where('ingoing_date', '<', $dateRange->startSql()); }) ->orWhere(function ($q) use ($dateRange) { $q->where('ingoing_date', '<=', $dateRange->endSql()) ->where('ingoing_date', '>', $dateRange->startSql()); }) ]) ->whereNull('extract_date') ->get() // Фильтр по отделению в памяти (быстро для <1000 записей) ->filter(fn($h) => $h->latestMigration?->department_id === $departmentId); // 2. Добавляем вычисляемые поля и превращаем в плоский массив $prepared = $all->map(function (UnifiedMedicalHistory $h) use ($dateRange) { return [ // Все исходные поля модели (автоматически через toArray) ...$h->toArray(), // + вычисляемые мета-поля для фронтенда 'patient_status' => PatientStatusClassifier::classify($h, $dateRange), 'patient_urgency' => PatientStatusClassifier::classifyUrgency($h->urgency_id), 'admitted_today' => PatientStatusClassifier::classifyAdmitted($h->latestMigration?->ingoing_date), ]; }); // 3. Сортировка $sortBy = 'recipient_date'; $sortOrder = 'desc'; $sorted = $prepared->sortBy($sortBy, SORT_REGULAR, $sortOrder === 'desc')->values(); // 4. Возвращаем плоский массив + метаданные для фронтенда return [ 'data' => $sorted->toArray(), 'meta' => [ 'total' => $sorted->count(), 'sortBy' => $sortBy, 'sortOrder' => $sortOrder, // Статистика для фильтров/бейджей (опционально) 'counts' => [ 'in_department' => $sorted->where('patient_status', 'in_department')->count(), 'discharged' => $sorted->where('patient_status', 'discharged')->count(), 'urgent' => $sorted->where('patient_urgency', 'urgent')->count(), 'planned' => $sorted->where('patient_urgency', 'planned')->count(), ] ] ]; } public function getHistories(DateRange $dateRange, int $departmentId) { $query = UnifiedMedicalHistory::query(); $query->where('recipient_date', '>=', $dateRange->startSql()) ->where('recipient_date', '<', $dateRange->endSql()) // 1. Оставляем только тех пациентов, у которых БЫЛО движение в этом отделении ->whereHas('latestMigration', fn($q) => $q->where('department_id', $departmentId)) // 2. Загружаем ТОЛЬКО последнее движение в этом отделении (не все миграции) ->with(['latestMigration' => fn($q) => $q->where('department_id', $departmentId)]); $result = $query->paginate(); return $result; } public function getUrgencyHistory(DateRange $dateRange, int $departmentId, int $urgencyId) { $query = UnifiedMedicalHistory::query(); $query->where('recipient_date', '>=', $dateRange->startSql()) ->where('recipient_date', '<', $dateRange->endSql()) ->urgency($urgencyId) ->whereHas('migrations', function ($m) use ($departmentId) { $m->where('department_id', $departmentId); }) ->with([ 'migrations' => fn ($m) => $m->where('department_id', $departmentId), 'migrations.operations' ]); $result = $query->paginate(); return $result; } public function getDepartmentHistories(DateRange $dateRange, int $departmentId) { return UnifiedMedicalHistory::query() ->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange) { $q->department($departmentId)->current($dateRange); }) ->with(['latestMigration']) ->get() // Сортировка по дате поступления в отделение (поле дочерней таблицы) ->sortByDesc(fn ($mh) => $mh->latestMigration->ingoing_date ?? $mh->recipient_date) ->values(); } /** * Получить карты поступившие сегодня * @param DateRange $dateRange * @param int $departmentId */ public function getRecipientHistories(DateRange $dateRange, int $departmentId) { $now = Carbon::now(); return UnifiedMedicalHistory::query() ->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange) { $q->department($departmentId)->admitted($dateRange->startSql(), $dateRange->endSql()); }) ->with(['latestMigration']) ->get(); } public function getDischargedHistories(DateRange $dateRange, int $departmentId) { return UnifiedMedicalHistory::query() ->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange) { $q->department($departmentId)->discharged($dateRange->startSql(), $dateRange->endSql()); }) ->with(['latestMigration']) ->get(); } public function getDeceasedHistories(DateRange $dateRange, int $departmentId) { return UnifiedMedicalHistory::query() ->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange) { $q->department($departmentId)->deceased($dateRange->startSql(), $dateRange->endSql()); }) ->with(['latestMigration']) ->get(); } public function getTransferredHistories(DateRange $dateRange, int $departmentId) { return UnifiedMedicalHistory::query() ->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange) { $q->department($departmentId)->transferred($dateRange->startSql(), $dateRange->endSql()); }) ->with(['latestMigration']) ->get(); } }