nothing
This commit is contained in:
@@ -30,17 +30,16 @@ class ReportService
|
||||
/**
|
||||
* Получить статистику для отчета
|
||||
*/
|
||||
public function getReportStatistics(User $user, DateRange $dateRange): array
|
||||
public function getReportStatistics(Department $department, User $user, DateRange $dateRange): array
|
||||
{
|
||||
$department = $user->department;
|
||||
$misDepartmentId = $department->rf_mis_department_id;
|
||||
$branchId = $this->getBranchId($misDepartmentId);
|
||||
|
||||
// Определяем, используем ли мы снапшоты
|
||||
$useSnapshots = $this->shouldUseSnapshots($user, $dateRange);
|
||||
$useSnapshots = $this->shouldUseSnapshots($department, $user, $dateRange);
|
||||
|
||||
if ($useSnapshots) {
|
||||
return $this->getStatisticsFromSnapshots($user, $dateRange, $branchId);
|
||||
return $this->getStatisticsFromSnapshots($department, $dateRange, $branchId);
|
||||
}
|
||||
|
||||
return $this->getStatisticsFromReplica($user, $dateRange, $branchId);
|
||||
@@ -63,6 +62,9 @@ class ReportService
|
||||
// Сохраняем снапшоты пациентов
|
||||
$this->snapshotService->createPatientSnapshots($report, $user, $data['dates'], $fillableAuto);
|
||||
|
||||
// Сохраняем метрику среднего койко-дня из снапшотов
|
||||
$this->saveAverageBedDaysMetricFromSnapshots($report);
|
||||
|
||||
DB::commit();
|
||||
|
||||
// ОЧИСТКА КЭША ПОСЛЕ УСПЕШНОГО СОЗДАНИЯ ОТЧЕТА
|
||||
@@ -75,6 +77,76 @@ class ReportService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Сохранить метрику среднего койко-дня из снапшотов отчета
|
||||
*/
|
||||
protected function saveAverageBedDaysMetricFromSnapshots(Report $report): void
|
||||
{
|
||||
try {
|
||||
// Получаем все снапшоты выписанных пациентов из этого отчета
|
||||
$snapshots = MedicalHistorySnapshot::where('rf_report_id', $report->report_id)
|
||||
->whereIn('patient_type', ['discharged', 'deceased']) // выписанные и умершие
|
||||
->with('medicalHistory')
|
||||
->get();
|
||||
|
||||
if ($snapshots->isEmpty()) {
|
||||
// Если нет выписанных, сохраняем 0
|
||||
MetrikaResult::updateOrCreate(
|
||||
[
|
||||
'rf_report_id' => $report->report_id,
|
||||
'rf_metrika_item_id' => 18,
|
||||
],
|
||||
['value' => 0]
|
||||
);
|
||||
|
||||
\Log::info("No discharged patients in report {$report->report_id}, saved 0");
|
||||
return;
|
||||
}
|
||||
|
||||
// Рассчитываем средний койко-день по снапшотам
|
||||
$totalDays = 0;
|
||||
$validCount = 0;
|
||||
|
||||
foreach ($snapshots as $snapshot) {
|
||||
$history = $snapshot->medicalHistory;
|
||||
|
||||
if ($history && $history->DateRecipient && $history->DateExtract) {
|
||||
// Проверяем что дата выписки не специальная
|
||||
if ($history->DateExtract->format('Y-m-d') === '2222-01-01') {
|
||||
continue; // пропускаем текущих пациентов
|
||||
}
|
||||
|
||||
$start = Carbon::parse($history->DateRecipient);
|
||||
$end = Carbon::parse($history->DateExtract);
|
||||
|
||||
// Проверяем что дата выписки позже даты поступления
|
||||
if ($end->gt($start)) {
|
||||
$days = $start->diffInDays($end);
|
||||
$totalDays += $days;
|
||||
$validCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$avgBedDays = $validCount > 0 ? round($totalDays / $validCount, 1) : 0;
|
||||
|
||||
// Сохраняем метрику
|
||||
MetrikaResult::updateOrCreate(
|
||||
[
|
||||
'rf_report_id' => $report->report_id,
|
||||
'rf_metrika_item_id' => 18,
|
||||
],
|
||||
['value' => $avgBedDays]
|
||||
);
|
||||
|
||||
\Log::info("Saved average bed days metric for report {$report->report_id}: {$avgBedDays} (from {$validCount} patients)");
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::error("Failed to save average bed days metric: " . $e->getMessage());
|
||||
// Не прерываем выполнение, если метрика не сохранилась
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Очистить кэш после создания отчета
|
||||
*/
|
||||
@@ -115,6 +187,7 @@ class ReportService
|
||||
* Получить пациентов по статусу
|
||||
*/
|
||||
public function getPatientsByStatus(
|
||||
Department $department,
|
||||
User $user,
|
||||
string $status,
|
||||
DateRange $dateRange,
|
||||
@@ -122,34 +195,35 @@ class ReportService
|
||||
bool $beforeCreate = false,
|
||||
?bool $includeCurrentPatients = null
|
||||
) {
|
||||
$branchId = $this->getBranchId($user->department->rf_mis_department_id);
|
||||
$branchId = $this->getBranchId($department->rf_mis_department_id);
|
||||
|
||||
$useSnapshots = $this->shouldUseSnapshots($user, $dateRange, $beforeCreate);
|
||||
$useSnapshots = $this->shouldUseSnapshots($department, $user, $dateRange, $beforeCreate);
|
||||
|
||||
if ($useSnapshots) {
|
||||
return $this->getPatientsFromSnapshots($user, $status, $dateRange, $branchId);
|
||||
return $this->getPatientsFromSnapshots($department, $status, $dateRange, $branchId);
|
||||
}
|
||||
|
||||
return $this->getPatientsFromReplica($user, $status, $dateRange, $branchId, $onlyIds, $includeCurrentPatients);
|
||||
return $this->getPatientsFromReplica($department, $user, $status, $dateRange, $branchId, $onlyIds, $includeCurrentPatients);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить количество пациентов по статусу
|
||||
*/
|
||||
public function getPatientsCountByStatus(
|
||||
Department $department,
|
||||
User $user,
|
||||
string $status,
|
||||
DateRange $dateRange
|
||||
): int {
|
||||
$branchId = $this->getBranchId($user->department->rf_mis_department_id);
|
||||
$branchId = $this->getBranchId($department->rf_mis_department_id);
|
||||
|
||||
$useSnapshots = $this->shouldUseSnapshots($user, $dateRange);
|
||||
$useSnapshots = $this->shouldUseSnapshots($department, $user, $dateRange);
|
||||
|
||||
if ($useSnapshots) {
|
||||
return $this->getPatientsCountFromSnapshots($user, $status, $dateRange);
|
||||
return $this->getPatientsCountFromSnapshots($department, $status, $dateRange);
|
||||
}
|
||||
|
||||
return $this->getPatientsCountFromReplica($user, $status, $dateRange, $branchId);
|
||||
return $this->getPatientsCountFromReplica($department, $user, $status, $dateRange, $branchId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,7 +238,7 @@ class ReportService
|
||||
/**
|
||||
* Определить, нужно ли использовать снапшоты
|
||||
*/
|
||||
private function shouldUseSnapshots(User $user, DateRange $dateRange, bool $beforeCreate = false): bool
|
||||
private function shouldUseSnapshots(Department $department, User $user, DateRange $dateRange, bool $beforeCreate = false): bool
|
||||
{
|
||||
if (($user->isAdmin() || $user->isHeadOfDepartment()) && !$beforeCreate) {
|
||||
return true;
|
||||
@@ -173,6 +247,7 @@ class ReportService
|
||||
// Проверяем, есть ли отчет на сегодня
|
||||
$reportToday = Report::whereDate('sent_at', $dateRange->end())
|
||||
->whereDate('created_at', $dateRange->end())
|
||||
->where('rf_department_id', $department->department_id)
|
||||
->first();
|
||||
|
||||
return !$dateRange->isEndDateToday() || $reportToday;
|
||||
@@ -237,6 +312,7 @@ class ReportService
|
||||
{
|
||||
if (empty($unwantedEvents)) {
|
||||
$report->unwantedEvents()->delete();
|
||||
$this->saveMetrics($report, [16 => 0]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -260,6 +336,9 @@ class ReportService
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Обновить метрику
|
||||
$this->saveMetrics($report, [16 => count($unwantedEvents)]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,6 +353,8 @@ class ReportService
|
||||
ObservationPatient::where('rf_department_id', $departmentId)
|
||||
->where('rf_report_id', $report->report_id)
|
||||
->delete();
|
||||
// Обновить метрику
|
||||
$this->saveMetrics($report, [14 => 0]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -290,16 +371,19 @@ class ReportService
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Обновить метрику
|
||||
$this->saveMetrics($report, [14 => count($observationPatients)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить информацию о текущем отчете
|
||||
*/
|
||||
public function getCurrentReportInfo(User $user, DateRange $dateRange): array
|
||||
public function getCurrentReportInfo(Department $department, User $user, DateRange $dateRange): array
|
||||
{
|
||||
$department = $user->department;
|
||||
$reportToday = Report::whereDate('sent_at', $dateRange->endSql())
|
||||
->whereDate('created_at', $dateRange->endSql())
|
||||
->where('rf_department_id', $department->department_id)
|
||||
->first();
|
||||
|
||||
$isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin();
|
||||
@@ -313,7 +397,7 @@ class ReportService
|
||||
}
|
||||
|
||||
// Получаем нежелательные события
|
||||
$unwantedEvents = $this->getUnwantedEvents($user, $dateRange);
|
||||
$unwantedEvents = $this->getUnwantedEvents($department, $dateRange);
|
||||
|
||||
// Определяем активность кнопки отправки
|
||||
$isActiveSendButton = $this->isSendButtonActive($user, $dateRange, $reportToday, $fillableUserId);
|
||||
@@ -367,11 +451,11 @@ class ReportService
|
||||
/**
|
||||
* Получить статистику из снапшотов
|
||||
*/
|
||||
private function getStatisticsFromSnapshots(User $user, DateRange $dateRange, int $branchId): array
|
||||
private function getStatisticsFromSnapshots(Department $department, DateRange $dateRange, int $branchId): array
|
||||
{
|
||||
// Получаем отчеты за период
|
||||
$reports = $this->getReportsForDateRange(
|
||||
$user->rf_department_id,
|
||||
$department->department_id,
|
||||
$dateRange
|
||||
);
|
||||
|
||||
@@ -403,6 +487,13 @@ class ReportService
|
||||
$this->getMetrikaResultCount(11, $reportIds) // плановые операции
|
||||
];
|
||||
|
||||
if ($snapshotStats['outcome'] == 0) {
|
||||
$percentDead = 0;
|
||||
} else {
|
||||
$percentDead = ($snapshotStats['deceased'] / $snapshotStats['outcome']) * 100;
|
||||
$percentDead = round($percentDead, 2);
|
||||
}
|
||||
|
||||
return [
|
||||
'recipientCount' => $snapshotStats['recipient'] ?? 0,
|
||||
'extractCount' => $snapshotStats['outcome'] ?? 0,
|
||||
@@ -410,7 +501,8 @@ class ReportService
|
||||
'deadCount' => $snapshotStats['deceased'] ?? 0,
|
||||
'surgicalCount' => $surgicalCount,
|
||||
'recipientIds' => $recipientIds,
|
||||
'beds' => $snapshotStats['beds'] ?? 0
|
||||
'beds' => $snapshotStats['beds'] ?? 0,
|
||||
'percentDead' => $percentDead,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -501,6 +593,13 @@ class ReportService
|
||||
$beds = Department::where('rf_mis_department_id', $misBranch->rf_DepartmentID)
|
||||
->first()->metrikaDefault->where('rf_metrika_item_id', 1)->first();
|
||||
|
||||
if ($outcomeCount == 0) {
|
||||
$percentDead = 0;
|
||||
} else {
|
||||
$percentDead = ($deadCount / $outcomeCount) * 100;
|
||||
$percentDead = round($percentDead, 2);
|
||||
}
|
||||
|
||||
return [
|
||||
'recipientCount' => $recipientCount, // только поступившие сегодня
|
||||
'extractCount' => $outcomeCount,
|
||||
@@ -510,6 +609,7 @@ class ReportService
|
||||
'recipientIds' => $recipientIds, // ID поступивших сегодня
|
||||
'planCount' => $planCount, // плановые (поступившие + уже лечащиеся)
|
||||
'emergencyCount' => $emergencyCount, // экстренные (поступившие + уже лечащиеся)
|
||||
'percentDead' => $percentDead,
|
||||
'beds' => $beds->value
|
||||
];
|
||||
}
|
||||
@@ -517,15 +617,15 @@ class ReportService
|
||||
/**
|
||||
* Получить пациентов из снапшотов
|
||||
*/
|
||||
private function getPatientsFromSnapshots(
|
||||
User $user,
|
||||
public function getPatientsFromSnapshots(
|
||||
Department $department,
|
||||
string $status,
|
||||
DateRange $dateRange,
|
||||
int $branchId,
|
||||
bool $onlyIds = false
|
||||
) {
|
||||
$reports = $this->getReportsForDateRange(
|
||||
$user->rf_department_id,
|
||||
$department->department_id,
|
||||
$dateRange
|
||||
);
|
||||
|
||||
@@ -543,7 +643,7 @@ class ReportService
|
||||
$patientType = $patientTypeMap[$status] ?? null;
|
||||
|
||||
if ($patientType === 'observation') {
|
||||
return $this->patientQueryService->getObservationPatients($user->rf_department_id, $onlyIds); //$this->getObservationPatientsFromSnapshots($user->rf_department_id, $reportIds, $onlyIds);
|
||||
return $this->patientQueryService->getObservationPatients($department->department_id, $onlyIds); //$this->getObservationPatientsFromSnapshots($user->rf_department_id, $reportIds, $onlyIds);
|
||||
}
|
||||
|
||||
return $this->snapshotService->getPatientsFromSnapshots($patientType, $reportIds, $branchId, $onlyIds);
|
||||
@@ -553,6 +653,7 @@ class ReportService
|
||||
* Получить пациентов из реплики БД
|
||||
*/
|
||||
private function getPatientsFromReplica(
|
||||
Department $department,
|
||||
User $user,
|
||||
string $status,
|
||||
DateRange $dateRange,
|
||||
@@ -575,7 +676,7 @@ class ReportService
|
||||
$onlyIds,
|
||||
$includeCurrent
|
||||
),
|
||||
'observation' => $this->patientQueryService->getObservationPatients($user->rf_department_id, $onlyIds),
|
||||
'observation' => $this->patientQueryService->getObservationPatients($department->department_id, $onlyIds),
|
||||
'outcome' => $this->patientQueryService->getOutcomePatients(
|
||||
$branchId,
|
||||
$dateRange,
|
||||
@@ -623,10 +724,10 @@ class ReportService
|
||||
/**
|
||||
* Получить количество пациентов из снапшотов
|
||||
*/
|
||||
private function getPatientsCountFromSnapshots(User $user, string $status, DateRange $dateRange): int
|
||||
private function getPatientsCountFromSnapshots(Department $department, string $status, DateRange $dateRange): int
|
||||
{
|
||||
$reports = $this->getReportsForDateRange(
|
||||
$user->rf_department_id,
|
||||
$department->department_id,
|
||||
$dateRange
|
||||
);
|
||||
|
||||
@@ -669,7 +770,13 @@ class ReportService
|
||||
/**
|
||||
* Получить количество пациентов из реплики БД
|
||||
*/
|
||||
private function getPatientsCountFromReplica(User $user, string $status, DateRange $dateRange, int $branchId): int
|
||||
private function getPatientsCountFromReplica(
|
||||
Department $department,
|
||||
User $user,
|
||||
string $status,
|
||||
DateRange $dateRange,
|
||||
int $branchId
|
||||
): int
|
||||
{
|
||||
$isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin();
|
||||
|
||||
@@ -680,7 +787,7 @@ class ReportService
|
||||
$branchId,
|
||||
$dateRange,
|
||||
),
|
||||
'observation' => ObservationPatient::where('rf_department_id', $user->rf_department_id)->count(),
|
||||
'observation' => ObservationPatient::where('rf_department_id', $department->department_id)->count(),
|
||||
'outcome' => $this->patientQueryService->getOutcomePatients(
|
||||
$branchId,
|
||||
$dateRange,
|
||||
@@ -708,11 +815,11 @@ class ReportService
|
||||
/**
|
||||
* Получить нежелательные события за дату
|
||||
*/
|
||||
private function getUnwantedEvents(User $user, DateRange $dateRange)
|
||||
public function getUnwantedEvents(Department $department, DateRange $dateRange)
|
||||
{
|
||||
return UnwantedEvent::whereHas('report', function ($query) use ($user, $dateRange) {
|
||||
$query->where('rf_department_id', $user->rf_department_id)
|
||||
->whereDate('created_at', $dateRange->endSql());
|
||||
return UnwantedEvent::whereHas('report', function ($query) use ($department, $dateRange) {
|
||||
$query->where('rf_department_id', $department->department_id)
|
||||
->whereBetween('sent_at', [$dateRange->startSql(), $dateRange->endSql()]);
|
||||
})
|
||||
->get()
|
||||
->map(function ($item) {
|
||||
@@ -733,8 +840,12 @@ class ReportService
|
||||
return $dateRange->isEndDateToday() && !$reportToday;
|
||||
}
|
||||
|
||||
// Для заведующего/админа: если есть отчет и он заполнен текущим пользователем
|
||||
if ($reportToday && $reportToday->rf_lpudoctor_id === intval($fillableUserId)) {
|
||||
// Для заведующего/админа: если есть отчет & он заполнен текущим пользователем & диапазон дат = 1 дню
|
||||
if (
|
||||
$reportToday &&
|
||||
$reportToday->rf_lpudoctor_id === intval($fillableUserId) &&
|
||||
$dateRange->isOneDay
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -761,7 +872,7 @@ class ReportService
|
||||
/**
|
||||
* Получить отчеты за диапазон дат
|
||||
*/
|
||||
private function getReportsForDateRange(int $departmentId, DateRange $dateRange)
|
||||
public function getReportsForDateRange(int $departmentId, DateRange $dateRange)
|
||||
{
|
||||
if ($dateRange->isOneDay) {
|
||||
return Report::where('rf_department_id', $departmentId)
|
||||
|
||||
Reference in New Issue
Block a user