get('search'); $selectedUserId = $request->query('userId') ? (int) $request->query('userId') : null; $departmentId = $request->query('departmentId', $user->department->department_id); $department = Department::where('department_id', $departmentId)->firstOrFail(); $bedsInDepartment = DepartmentMetrikaDefault::where('rf_department_id', $departmentId) ->where('rf_metrika_item_id', 1)->first()->value ?? 0; $dateRange = $this->dateRangeService->getDateRangeFromRequest($request, $user); $isRangeOneDay = $this->dateRangeService->isRangeOneDay($dateRange->startDate, $dateRange->endDate); $isPastPeriod = $this->dateRangeService->isPastPeriod($dateRange); $isCurrentPeriod = !$isPastPeriod; // Всегда загружаем отчеты за период $reportsDuty = ReportDuty::where('rf_department_id', $departmentId) ->where('period_start', '>=', $dateRange->startSql()) ->where('period_end', '<=', $dateRange->endSql()) ->orderBy('period_end', 'desc') ->with(['unwantedEvents', 'doctor']) ->get(); $reportsNurse = ReportNurse::where('rf_department_id', $departmentId) ->where('period_start', '>=', $dateRange->startSql()) ->where('period_end', '<=', $dateRange->endSql()) ->orderBy('period_end', 'desc') ->get(); $hasDutyReport = $reportsDuty->count() > 0; $hasNurseReport = $reportsNurse->count() > 0; $reportDutyIds = $reportsDuty->pluck('id')->toArray(); $reportNurseIds = $reportsNurse->pluck('id')->toArray(); // dd($reportsDuty, $dateRange->endSql()); // Получаем пациентов (источник зависит от периода) if ($isCurrentPeriod) { // Для текущего периода - пациенты из МИС $patients = $this->medicalHistoryService->getGroupedHistories( $dateRange, $department->rf_mis_department_id, $search ); // Если есть отчет, загружаем из него дополнительные данные if ($hasDutyReport) { // Получаем нежелательные события и наблюдения из отчета $reportData = $this->getReportAdditionalData($reportsDuty); // Добавляем эти данные к пациентам $patients = $this->mergeReportData($patients, $reportData); } $nursePatients = $hasNurseReport ? $this->nurseMedicalHistoryService->getGroupedHistories( $dateRange, $department->rf_mis_department_id, $reportNurseIds ) : []; $currentPatients = $patients['meta']['counts']['in_department']; $loaded = $bedsInDepartment > 0 ? round(($currentPatients * 100) / $bedsInDepartment) : 0; $latestReport = $reportsDuty->first(); } else { // Для прошедшего периода - данные из отчета $patients = $hasDutyReport ? $this->dutyMedicalHistoryService->getGroupedHistories( $dateRange, $department->rf_mis_department_id, $reportDutyIds, $search ) : $this->getEmptyPatientsData(); $nursePatients = $hasNurseReport ? $this->nurseMedicalHistoryService->getGroupedHistories( $dateRange, $department->rf_mis_department_id, $reportNurseIds ) : []; $latestReport = $reportsDuty->first(); if ($latestReport && $hasDutyReport) { $currentPatients = $patients['meta']['counts']['in_department']; $loaded = $latestReport->getLoadedDepartmentAttribute($currentPatients); } else { $loaded = 0; } } return Inertia::render('Report/Index', [ 'department' => $department, 'patients' => $patients, 'nursePatients' => $nursePatients, 'latestReport' => $latestReport ?? null, 'canSaveReport' => $isRangeOneDay && $user->currentRoleCan('report.create'), 'canEditPastReport' => $user->currentRoleCan('report.edit.past'), 'canSaveNurseReport' => $isRangeOneDay && $user->currentRoleCan('nurse.report.create'), 'stats' => $this->prepareStats($patients, $nursePatients, $loaded, $bedsInDepartment), 'dates' => [ $dateRange->startDate->getTimestampMs(), $dateRange->endDate->getTimestampMs(), ], 'selectedUserId' => $selectedUserId, 'selectedDepartmentId' => (int) $departmentId, ]); } /** * Получает дополнительные данные из отчета (нежелательные события, наблюдения) */ private function getReportAdditionalData($reportsDuty): array { $unwantedEvents = []; $observations = []; foreach ($reportsDuty as $report) { // Нежелательные события foreach ($report->unwantedEvents as $event) { $unwantedEvents[] = [ ...$event->toArray(), ]; } // Наблюдения (если есть связь) if ($report->relationLoaded('observations') || $report->observations) { foreach ($report->observations as $observation) { $observations[] = [ ...$observation->toArray(), ]; } } } return [ 'unwanted_events' => $unwantedEvents, 'observations' => $observations ]; } /** * Объединяет данные пациентов из МИС с данными из отчета */ private function mergeReportData(array $patients, array $reportData): array { // Группируем нежелательные события по отчетам // $eventsByPatient = []; // foreach ($reportData['unwanted_events'] as $event) { // $reportId = $event['report_duty_id']; // if (!isset($eventsByPatient[$reportId])) { // $eventsByPatient[$reportId] = []; // } // $eventsByPatient[$reportId][] = $event; // } // Группируем наблюдения по пациентам $observationsByPatient = []; foreach ($reportData['observations'] as $observation) { $patientId = $observation['patient_id']; if (!isset($observationsByPatient[$patientId])) { $observationsByPatient[$patientId] = []; } $observationsByPatient[$patientId][] = $observation; } // Добавляем данные из отчета к каждому пациенту foreach ($patients['data'] as &$patient) { $patientId = $patient['original_id'] ?? $patient['id'] ?? null; // Может быть позже пригодится // if ($patientId && isset($eventsByPatient[$patientId])) { // $patient['unwanted_events'] = $eventsByPatient[$patientId]; // } else { // $patient['unwanted_events'] = []; // } if ($patientId && isset($observationsByPatient[$patientId])) { $patient['observations'] = $observationsByPatient[$patientId]; } else { $patient['observations'] = []; } } return $patients; } /** * Получает данные из сестринского отчета */ private function getNurseReportAdditionalData($reportsNurse): array { $nurseData = []; foreach ($reportsNurse as $report) { // Загружаем необходимые данные из сестринского отчета // Например, наблюдения медсестер, процедуры и т.д. if ($report->relationLoaded('nurseObservations')) { $nurseData = array_merge($nurseData, $report->nurseObservations->toArray()); } } return $nurseData; } /** * Возвращает пустую структуру данных для пациентов */ private function getEmptyPatientsData(): array { return [ 'data' => [], 'meta' => [ 'total' => 0, 'sortBy' => 'ingoing_date', 'sortOrder' => 'desc', 'counts' => [ 'in_department' => 0, 'recipient' => 0, 'discharged' => 0, 'deceased' => 0, 'urgent' => 0, 'planned' => 0, 'reanimations' => 0, 'surgical_planned' => 0, 'surgical_urgent' => 0, ] ] ]; } /** * Подготавливает статистику для отображения на фронтенде */ private function prepareStats(array $patients, array $nursePatients, int $loaded, ?int $bedsInDepartment): array { $deceased = $patients['meta']['counts']['deceased'] ?? 0; // Умершие $discharged = $patients['meta']['counts']['discharged'] ?? 0; // Выписанные $outcome = $deceased + $discharged; $lethality = !empty($discharged) ? round(($deceased / $discharged) * 100, 2) : 0; return [ 'nurse' => [ 'current' => !empty($nursePatients) ? ($nursePatients['meta']['counts']['in_department'] ?? 0) : 0, 'recipient' => !empty($nursePatients) ? ($nursePatients['meta']['counts']['recipient'] ?? 0) : 0, 'discharged' => empty($nursePatients) ? ($nursePatients['meta']['counts']['discharged'] ?? 0) : 0, ], 'duty' => [ 'beds' => $bedsInDepartment ?? 0, 'loaded' => $loaded, 'current' => $patients['meta']['counts']['in_department'] ?? 0, 'recipient' => $patients['meta']['counts']['recipient'] ?? 0, 'discharged' => ($patients['meta']['counts']['discharged'] ?? 0) + ($patients['meta']['counts']['deceased'] ?? 0), 'deceased' => $patients['meta']['counts']['deceased'] ?? 0, 'lethality' => $lethality, 'surgical_planned' => $patients['meta']['counts']['surgical_planned'] ?? 0, 'surgical_urgent' => $patients['meta']['counts']['surgical_urgent'] ?? 0, ] ]; } /** * Сохранение отчета * @return \Illuminate\Http\RedirectResponse */ public function store(Request $request) { abort_if(!auth()->user()->currentRoleCan('report.create'), 403); $user = auth()->user(); $observables = $request->get('observables', []); $unwantedEvents = $request->get('unwanted_events', []); $selectedUserId = $request->get('userId') ? (int) $request->get('userId') : null; $selectedDepartmentId = $request->get('departmentId') ? (int) $request->get('departmentId') : null; $staff = (int) $request->get('staff', 0); $dateRange = $this->dateRangeService->getDateRangeFromRequest($request, $user); $report = $this->dutyReportService->saveReport($dateRange, null, $selectedUserId, $selectedDepartmentId); $stats = $this->dutyReportService->saveSnapshot($dateRange, $report, null, auth()->id()); $this->dutyReportService->saveObservables($observables, $report); $this->dutyReportService->saveUnwantedEvents($unwantedEvents, $report); $this->dutyReportService->saveMetrics($stats, $report, $staff); return redirect()->back(); } public function closeObservation(Request $request) { $user = auth()->user(); $dateRange = $this->dateRangeService->getDateRangeFromRequest($request, $user); $observable = $request->get('observable'); $observableId = $observable['id'] ?? null; if ($observableId === null) return response()->json('Observable not found', 404); $observable = ObservableMedicalHistory::find($observableId); $observable->update([ 'observable_out' => $dateRange->endDate, 'out_reason' => 'Закрыто пользователем' ]); } }