contextResolver->resolveBranchId($department); if (! $branchId) { return $this->emptyStatistics(); } if ($this->contextResolver->shouldUseSnapshots($department, $dateRange)) { return $this->getStatisticsFromSnapshots($department, $dateRange); } return $this->getStatisticsFromReplica($department, $user, $dateRange, $branchId); } /** * Получить статистику из сохранённых снапшотов submitted-отчётов. */ private function getStatisticsFromSnapshots(Department $department, DateRange $dateRange): array { $reports = $this->contextResolver->getReportsForDateRange( $department->department_id, $dateRange ); $reportIds = $reports->pluck('report_id')->all(); $lastReportId = $reportIds[0] ?? null; $recipientReportIds = $this->contextResolver->getRecipientReportIds($reportIds); $snapshotStats = [ 'plan' => $this->getMetrikaResultCount(MetrikaConfig::PLAN, $reportIds), 'emergency' => $this->getMetrikaResultCount(MetrikaConfig::EMERGENCY, $reportIds), 'outcome' => $this->getMetrikaResultCount(MetrikaConfig::OUTCOME, $reportIds), 'deceased' => $this->getMetrikaResultCount(MetrikaConfig::DECEASED, $reportIds), 'current' => $this->getMetrikaResultCount(MetrikaConfig::CURRENT, $reportIds, false), 'transferred' => $this->getMetrikaResultCount(MetrikaConfig::TRANSFERRED, $reportIds), 'recipient' => $this->getMetrikaResultCount(MetrikaConfig::RECIPIENT, $reportIds), 'beds' => $this->getMetrikaResultCount(MetrikaConfig::BEDS, $reportIds, false), 'countStaff' => $lastReportId ? $this->getMetrikaResultCount(MetrikaConfig::STAFF_COUNT, [$lastReportId], false) : 0, ]; $recipientIds = $this->snapshotService ->getPatientsFromSnapshots('recipient', $recipientReportIds) ->pluck('id') ->all(); $surgicalCount = [ $this->getMetrikaResultCount(MetrikaConfig::EMERGENCY_SURGERY, $reportIds), $this->getMetrikaResultCount(MetrikaConfig::PLAN_SURGERY, $reportIds), ]; return [ 'recipientCount' => $snapshotStats['recipient'] ?? 0, 'extractCount' => $snapshotStats['outcome'] ?? 0, 'currentCount' => $snapshotStats['current'] ?? 0, 'deadCount' => $snapshotStats['deceased'] ?? 0, 'countStaff' => $snapshotStats['countStaff'] ?? 0, 'surgicalCount' => $surgicalCount, 'recipientIds' => $recipientIds, 'beds' => $snapshotStats['beds'] ?? 0, 'percentDead' => $this->calculatePercentDead($snapshotStats['deceased'], $snapshotStats['outcome']), ]; } /** * Получить статистику из live-реплики МИС и manual-источников. */ private function getStatisticsFromReplica( Department $department, User $user, DateRange $dateRange, int $branchId ): array { $planCount = $this->unifiedPatientService->getLivePatientCountByStatus($department, $user, 'plan', $dateRange, $branchId, true); $emergencyCount = $this->unifiedPatientService->getLivePatientCountByStatus($department, $user, 'emergency', $dateRange, $branchId, true); $currentCount = $this->unifiedPatientService->getLivePatientCountByStatus($department, $user, 'current', $dateRange, $branchId); $recipientCount = $this->unifiedPatientService->getLivePatientCountByStatus($department, $user, 'recipient', $dateRange, $branchId); $outcomeCount = $this->unifiedPatientService->getLivePatientCountByStatus($department, $user, 'outcome', $dateRange, $branchId); $deadCount = $this->unifiedPatientService->getLivePatientCountByStatus($department, $user, 'outcome-deceased', $dateRange, $branchId); $misSurgicalCount = [ $this->patientService->getSurgicalPatients('emergency', $branchId, $dateRange, true), $this->patientService->getSurgicalPatients('plan', $branchId, $dateRange, true), ]; $manualSurgicalCount = $this->calculatedMetricsSynchronizer->getManualSurgicalCounts($department, $dateRange); $surgicalCount = [ ($misSurgicalCount[0] ?? 0) + ($manualSurgicalCount[0] ?? 0), ($misSurgicalCount[1] ?? 0) + ($manualSurgicalCount[1] ?? 0), ]; $recipientIds = $this->unifiedPatientService ->getRecipientIdsForReport($department, $user, $dateRange, $branchId); return [ 'recipientCount' => $recipientCount, 'extractCount' => $outcomeCount, 'currentCount' => $currentCount, 'deadCount' => $deadCount, 'surgicalCount' => $surgicalCount, 'recipientIds' => $recipientIds, 'planCount' => $planCount, 'emergencyCount' => $emergencyCount, 'percentDead' => $this->calculatePercentDead($deadCount, $outcomeCount), 'beds' => (int) ($department->metrikaDefault ->where('rf_metrika_item_id', MetrikaConfig::BEDS) ->first() ?->value ?? 0), ]; } /** * Получить агрегированное значение метрики из набора отчётов. * * @param array $reportIds */ private function getMetrikaResultCount(int $metrikaItemId, array $reportIds, bool $sum = true): int { if (empty($reportIds)) { return 0; } $reports = Report::query() ->whereIn('report_id', $reportIds) ->with('metrikaResults') ->orderBy('created_at', 'DESC') ->get(); if (! $sum) { foreach ($reports as $report) { $metric = $report->metrikaResults ->firstWhere('rf_metrika_item_id', $metrikaItemId); if ($metric) { return (int) $metric->value; } } return 0; } $count = 0; foreach ($reports as $report) { foreach ($report->metrikaResults as $metrikaResult) { if ((int) $metrikaResult->rf_metrika_item_id === $metrikaItemId) { $count += (int) $metrikaResult->value; } } } return $count; } private function calculatePercentDead(int $deadCount, int $outcomeCount): float|int { if ($outcomeCount === 0) { return 0; } return round(($deadCount / $outcomeCount) * 100, 2); } private function emptyStatistics(): array { return [ 'recipientCount' => 0, 'extractCount' => 0, 'currentCount' => 0, 'deadCount' => 0, 'surgicalCount' => [0, 0], 'recipientIds' => [], 'planCount' => 0, 'emergencyCount' => 0, 'percentDead' => 0, 'beds' => 0, 'countStaff' => 0, ]; } }