createReportForDate($user, $date, $departmentId, $force); if ($reportCreated) { $createdCount++; } } catch (\Exception $e) { Log::error("Ошибка создания отчета для {$user->id} на {$date->format('Y-m-d')}: {$e->getMessage()}"); throw $e; // или continue в зависимости от требований } } return $createdCount; } /** * Создать отчет для конкретной даты */ public function createReportForDate(User $user, Carbon $date, $departmentId, bool $force = false): bool { $user->rf_department_id = $departmentId; // Проверяем, существует ли уже отчет на эту дату $existingReport = Report::where('rf_department_id', $departmentId) ->whereDate('created_at', $date) ->whereDate('sent_at', $date) ->first(); if ($existingReport && !$force) { return false; // Отчет уже существует } // Если есть существующий отчет и force=true - удаляем его if ($existingReport && $force) { MetrikaResult::where('rf_report_id', $existingReport->report_id)->delete(); MedicalHistorySnapshot::where('rf_report_id', $existingReport->report_id)->delete(); $existingReport->delete(); } // Создаем DateRange для этой даты // Приводим к Illuminate\Carbon если нужно if (!$date instanceof \Illuminate\Support\Carbon) { $date = \Illuminate\Support\Carbon::instance($date); } $dateRange = $this->dateRangeService->createDateRangeForDate($date, $user); // Получаем данные для отчета $reportData = $this->prepareReportData($user, $dateRange, $date, $departmentId); // Создаем отчет DB::transaction(function () use ($user, $reportData, $date) { $this->reportService->storeReport($reportData, $user); }); return true; } /** * Подготовить данные для отчета */ private function prepareReportData(User $user, DateRange $dateRange, Carbon $date, $departmentId): array { $department = Department::where('department_id', $departmentId)->first(); $branchId = $this->getBranchId($department->rf_mis_department_id); $isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin(); // Получаем метрики $metrics = $this->calculateMetrics( $user, $isHeadOrAdmin, $branchId, $dateRange ); // Получаем количество коек $beds = $this->getBedCount($department); // Формируем данные отчета return [ 'departmentId' => $department->department_id, 'userId' => $user->rf_lpudoctor_id ?? $user->id, 'dates' => [ $dateRange->startTimestamp(), $dateRange->endTimestamp() ], 'sent_at' => $this->dateRangeService->toSqlFormat($date), 'created_at' => $this->dateRangeService->toSqlFormat($date), 'metrics' => $this->formatMetrics($metrics), 'observationPatients' => $this->getObservationPatients($departmentId, $date), 'unwantedEvents' => [], ]; } /** * Рассчитать метрики для отчета */ private function calculateMetrics( User $user, bool $isHeadOrAdmin, int $branchId, DateRange $dateRange ): array { $metrics = []; // 1. Плановые пациенты $metrics['plan'] = $this->patientQueryService->getPlanOrEmergencyPatients( 'plan', $isHeadOrAdmin, $branchId, $dateRange, true, false, true, true ); // 2. Экстренные пациенты $metrics['emergency'] = $this->patientQueryService->getPlanOrEmergencyPatients( 'emergency', $isHeadOrAdmin, $branchId, $dateRange, true, false, true, true ); // 3. Поступившие сегодня $metrics['recipient'] = $this->patientQueryService->getPlanOrEmergencyPatients( null, $isHeadOrAdmin, $branchId, $dateRange, true, false, false, true ); // 4. Выписанные $metrics['discharged'] = $this->patientQueryService->getOutcomePatients( $branchId, $dateRange, 'discharged' )->count(); // 5. Переведенные $metrics['transferred'] = $this->patientQueryService->getOutcomePatients( $branchId, $dateRange, 'transferred' )->count(); // 6. Умершие $metrics['deceased'] = $this->patientQueryService->getOutcomePatients( $branchId, $dateRange, 'deceased' )->count(); // 7. Текущие пациенты $metrics['current'] = $this->patientQueryService->getAllPatientsInDepartment( $isHeadOrAdmin, $branchId, $dateRange, true ); // 8. Плановые операции $metrics['plan_surgery'] = $this->patientQueryService->getSurgicalPatients( 'plan', $branchId, $dateRange, true ); // 9. Экстренные операции $metrics['emergency_surgery'] = $this->patientQueryService->getSurgicalPatients( 'emergency', $branchId, $dateRange, true ); return $metrics; } /** * Форматировать метрики для сохранения */ private function formatMetrics(array $metrics): array { return [ 'metrika_item_4' => $metrics['plan'] ?? 0, // плановые 'metrika_item_12' => $metrics['emergency'] ?? 0, // экстренные 'metrika_item_3' => $metrics['recipient'] ?? 0, // поступившие // 'metrika_item_6' => ($metrics['plan_surgery'] ?? 0) + ($metrics['emergency_surgery'] ?? 0), // всего операций 'metrika_item_7' => $metrics['discharged'] ?? 0, // выписанные 'metrika_item_8' => $metrics['current'] ?? 0, // текущие 'metrika_item_9' => $metrics['deceased'] ?? 0, // умершие 'metrika_item_11' => $metrics['plan_surgery'] ?? 0, // плановые операции 'metrika_item_10' => $metrics['emergency_surgery'] ?? 0, // экстренные операции 'metrika_item_13' => $metrics['transferred'] ?? 0, // переведенные 'metrika_item_14' => 0, // под наблюдением (будет заполнено отдельно) ]; } /** * Получить пациентов под наблюдением на дату */ private function getObservationPatients(int $departmentId, Carbon $date): array { // Здесь нужно реализовать логику получения пациентов под наблюдением // на конкретную дату. Возможно, из снапшотов или истории. return []; // временно возвращаем пустой массив } /** * Получить ID отделения */ private function getBranchId(int $misDepartmentId): ?int { return MisStationarBranch::where('rf_DepartmentID', $misDepartmentId) ->value('StationarBranchID'); } /** * Получить количество коек */ private function getBedCount(Department $department): int { $default = $department->metrikaDefault()->where('rf_metrika_item_id', 1)->first(); return (int)($default->value ?? 0); } }