snapshotPersistenceService = $snapshotPersistenceService ?? app(SnapshotPersistenceService::class); $this->snapshotPatientSource = $snapshotPatientSource ?? app(SnapshotPatientSource::class); } protected SnapshotPersistenceService $snapshotPersistenceService; protected SnapshotPatientSource $snapshotPatientSource; /** * Создать снапшоты пациентов для отчета */ public function createPatientSnapshots(Report $report, User $user, array $dates, $fillableAuto = false): void { $this->logSnapshotMemory('snapshots:start', [ 'report_id' => $report->report_id, 'department_id' => $report->rf_department_id, 'fillable_auto' => (bool) $fillableAuto, ]); $department = Department::query()->where('department_id', $report->rf_department_id)->first() ?? $user->department; $branchId = $department ? $this->getBranchId($department->rf_mis_department_id) : null; if (! $department || ! $branchId) { return; } $this->snapshotPersistenceService->clearReportSnapshots($report); $this->logSnapshotMemory('snapshots:after_delete_old', [ 'report_id' => $report->report_id, ]); [$startDate, $endDate] = $this->parseDates($dates); $dateRange = $this->dateRangeService->getNormalizedDateRange($user, $startDate, $endDate); $metrics = []; $this->logSnapshotMemory('snapshots:before_plan_load', ['report_id' => $report->report_id]); $planPatients = $this->unifiedPatientService->getLivePatientsByStatus( $department, $user, 'plan', $dateRange, $branchId, false, ! $fillableAuto, $fillableAuto, true ); $this->logSnapshotMemory('snapshots:after_plan_load', [ 'report_id' => $report->report_id, 'count' => $planPatients->count(), ]); $this->snapshotPersistenceService->createSnapshotsForType($report, 'plan', $planPatients); $this->logSnapshotMemory('snapshots:after_plan_save', ['report_id' => $report->report_id]); $metrics[MetrikaConfig::PLAN] = $planPatients->count(); $this->logSnapshotMemory('snapshots:before_emergency_load', ['report_id' => $report->report_id]); $emergencyPatients = $this->unifiedPatientService->getLivePatientsByStatus( $department, $user, 'emergency', $dateRange, $branchId, false, ! $fillableAuto, $fillableAuto, true ); $this->logSnapshotMemory('snapshots:after_emergency_load', [ 'report_id' => $report->report_id, 'count' => $emergencyPatients->count(), ]); $this->snapshotPersistenceService->createSnapshotsForType($report, 'emergency', $emergencyPatients); $this->logSnapshotMemory('snapshots:after_emergency_save', ['report_id' => $report->report_id]); $metrics[MetrikaConfig::EMERGENCY] = $emergencyPatients->count(); $this->logSnapshotMemory('snapshots:before_discharged_load', ['report_id' => $report->report_id]); $dischargedPatients = $this->unifiedPatientService->getLivePatientsByStatus( $department, $user, 'outcome-discharged', $dateRange, $branchId, false, null, $fillableAuto, true ); $this->logSnapshotMemory('snapshots:after_discharged_load', [ 'report_id' => $report->report_id, 'count' => $dischargedPatients->count(), ]); $this->snapshotPersistenceService->createSnapshotsForType($report, 'discharged', $dischargedPatients); $this->logSnapshotMemory('snapshots:after_discharged_save', ['report_id' => $report->report_id]); $metrics[MetrikaConfig::DISCHARGED] = $dischargedPatients->count(); $this->logSnapshotMemory('snapshots:before_transferred_load', ['report_id' => $report->report_id]); $transferredPatients = $this->unifiedPatientService->getLivePatientsByStatus( $department, $user, 'outcome-transferred', $dateRange, $branchId, false, null, $fillableAuto, true ); $this->logSnapshotMemory('snapshots:after_transferred_load', [ 'report_id' => $report->report_id, 'count' => $transferredPatients->count(), ]); $this->snapshotPersistenceService->createSnapshotsForType($report, 'transferred', $transferredPatients); $this->logSnapshotMemory('snapshots:after_transferred_save', ['report_id' => $report->report_id]); $metrics[MetrikaConfig::TRANSFERRED] = $transferredPatients->count(); $this->logSnapshotMemory('snapshots:before_deceased_load', ['report_id' => $report->report_id]); $deceasedPatients = $this->unifiedPatientService->getLivePatientsByStatus( $department, $user, 'outcome-deceased', $dateRange, $branchId, false, null, $fillableAuto, true ); $this->logSnapshotMemory('snapshots:after_deceased_load', [ 'report_id' => $report->report_id, 'count' => $deceasedPatients->count(), ]); $this->snapshotPersistenceService->createSnapshotsForType($report, 'deceased', $deceasedPatients); $this->logSnapshotMemory('snapshots:after_deceased_save', ['report_id' => $report->report_id]); $this->logSnapshotMemory('snapshots:before_recipient_load', ['report_id' => $report->report_id]); $recipientPatients = $this->unifiedPatientService->getLivePatientsByStatus( $department, $user, 'recipient', $dateRange, $branchId, false, null, $fillableAuto, true ); $this->logSnapshotMemory('snapshots:after_recipient_load', [ 'report_id' => $report->report_id, 'count' => $recipientPatients->count(), ]); $this->snapshotPersistenceService->createSnapshotsForType($report, 'recipient', $recipientPatients); $this->logSnapshotMemory('snapshots:after_recipient_save', ['report_id' => $report->report_id]); $this->logSnapshotMemory('snapshots:before_current_load', ['report_id' => $report->report_id]); $currentPatients = $this->unifiedPatientService->getLivePatientsByStatus( $department, $user, 'current', $dateRange, $branchId, false, null, $fillableAuto, true ); $this->logSnapshotMemory('snapshots:after_current_load', [ 'report_id' => $report->report_id, 'count' => $currentPatients->count(), ]); $this->snapshotPersistenceService->createSnapshotsForType($report, 'current', $currentPatients); $this->logSnapshotMemory('snapshots:after_current_save', ['report_id' => $report->report_id]); $planSurgeryCount = $this->patientService->getSurgicalPatients( 'plan', $branchId, $dateRange, true ); $emergencySurgeryCount = $this->patientService->getSurgicalPatients( 'emergency', $branchId, $dateRange, true ); $this->snapshotPersistenceService->saveMetrics($report, $metrics); $this->logSnapshotMemory('snapshots:after_save_metrics', ['report_id' => $report->report_id]); } private function logSnapshotMemory(string $stage, array $context = []): void { \Log::info('report.snapshot.memory', [ 'stage' => $stage, 'memory_mb' => round(memory_get_usage(true) / 1024 / 1024, 2), 'peak_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2), ...$context, ]); } /** * Получить статистику из снапшотов */ public function getStatisticsFromSnapshots(array $reportIds): array { return $this->snapshotPatientSource->getStatisticsFromSnapshots($reportIds); } /** * Получить пациентов из снапшотов по типу */ public function getPatientsFromSnapshots( string $type, array $reportIds, ?int $branchId = null, bool $onlyIds = false, bool $markRecipients = false, ?array $recipientReportIds = null ): Collection { return $this->snapshotPatientSource->getPatientsFromSnapshots( $type, $reportIds, $onlyIds, $markRecipients, $recipientReportIds ); } public function getPatientsFromOneDayCurrentSnapshots( string $type, array $reportIds, bool $onlyIds = false, ?array $recipientReportIds = null ): Collection { return $this->snapshotPatientSource->getPatientsFromOneDayCurrentSnapshots( $type, $reportIds, $onlyIds, $recipientReportIds ); } /** * Получить ID отделения */ private function getBranchId(int $misDepartmentId): ?int { return MisStationarBranch::where('rf_DepartmentID', $misDepartmentId) ->value('StationarBranchID'); } /** * Разобрать даты */ private function parseDates(array $dates): array { return [ Carbon::createFromTimestampMs($dates[0])->setTimezone('Asia/Yakutsk'), Carbon::createFromTimestampMs($dates[1])->setTimezone('Asia/Yakutsk'), ]; } }