* переписал функции прототипов в сервисы
* оптимизация доставки контента до клиента * переписал запросы выборок * убрал из подсчета переведенных * добавил сохранение метрикам для вывода в дашборд
This commit is contained in:
198
app/Services/SnapshotService.php
Normal file
198
app/Services/SnapshotService.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\MedicalHistorySnapshot;
|
||||
use App\Models\MisMedicalHistory;
|
||||
use App\Models\MisStationarBranch;
|
||||
use App\Models\Report;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class SnapshotService
|
||||
{
|
||||
public function __construct(
|
||||
protected PatientService $patientService
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Создать снапшоты пациентов для отчета
|
||||
*/
|
||||
public function createPatientSnapshots(Report $report, User $user, array $dates): void
|
||||
{
|
||||
$branchId = $this->getBranchId($user->department->rf_mis_department_id);
|
||||
[$startDate, $endDate] = $this->parseDates($dates);
|
||||
|
||||
// Плановые пациенты
|
||||
$this->createSnapshotsForType(
|
||||
$report,
|
||||
'plan',
|
||||
$this->patientService->getPlanOrEmergencyPatients(
|
||||
'plan',
|
||||
$user->isHeadOfDepartment() || $user->isAdmin(),
|
||||
$branchId,
|
||||
$startDate,
|
||||
$endDate,
|
||||
false,
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
// Экстренные пациенты
|
||||
$this->createSnapshotsForType(
|
||||
$report,
|
||||
'emergency',
|
||||
$this->patientService->getPlanOrEmergencyPatients(
|
||||
'emergency',
|
||||
$user->isHeadOfDepartment() || $user->isAdmin(),
|
||||
$branchId,
|
||||
$startDate,
|
||||
$endDate,
|
||||
false,
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
// Выписанные
|
||||
$this->createSnapshotsForType(
|
||||
$report,
|
||||
'discharged',
|
||||
$this->patientService->getOutcomePatients(
|
||||
$branchId,
|
||||
$startDate,
|
||||
$endDate,
|
||||
'discharged'
|
||||
)->pluck('MedicalHistoryID')->toArray()
|
||||
);
|
||||
|
||||
// Переведенные
|
||||
$this->createSnapshotsForType(
|
||||
$report,
|
||||
'transferred',
|
||||
$this->patientService->getOutcomePatients(
|
||||
$branchId,
|
||||
$startDate,
|
||||
$endDate,
|
||||
'transferred'
|
||||
)->pluck('MedicalHistoryID')->toArray()
|
||||
);
|
||||
|
||||
// Умершие
|
||||
$this->createSnapshotsForType(
|
||||
$report,
|
||||
'deceased',
|
||||
$this->patientService->getOutcomePatients(
|
||||
$branchId,
|
||||
$startDate,
|
||||
$endDate,
|
||||
'deceased'
|
||||
)->pluck('MedicalHistoryID')->toArray()
|
||||
);
|
||||
|
||||
// Поступившие
|
||||
$recipientIds = $this->patientService->getPlanOrEmergencyPatients(
|
||||
null,
|
||||
$user->isHeadOfDepartment() || $user->isAdmin(),
|
||||
$branchId,
|
||||
$startDate,
|
||||
$endDate,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
$this->createSnapshotsForType($report, 'recipient', $recipientIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить статистику из снапшотов
|
||||
*/
|
||||
public function getStatisticsFromSnapshots(array $reportIds): array
|
||||
{
|
||||
return [
|
||||
'plan' => $this->getCountFromSnapshots('plan', $reportIds),
|
||||
'emergency' => $this->getCountFromSnapshots('emergency', $reportIds),
|
||||
'outcome' => $this->getCountFromSnapshots('outcome', $reportIds),
|
||||
'deceased' => $this->getCountFromSnapshots('deceased', $reportIds),
|
||||
'discharged' => $this->getCountFromSnapshots('discharged', $reportIds),
|
||||
'transferred' => $this->getCountFromSnapshots('transferred', $reportIds),
|
||||
'recipient' => $this->getCountFromSnapshots('recipient', $reportIds),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить пациентов из снапшотов по типу
|
||||
*/
|
||||
public function getPatientsFromSnapshots(
|
||||
string $type,
|
||||
array $reportIds,
|
||||
?int $branchId = null
|
||||
): Collection {
|
||||
$medicalHistoryIds = MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds)
|
||||
->where('patient_type', $type)
|
||||
->pluck('rf_medicalhistory_id')
|
||||
->unique()
|
||||
->toArray();
|
||||
|
||||
if (empty($medicalHistoryIds)) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
return MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
|
||||
->when($type === 'plan', fn($q) => $q->plan())
|
||||
->when($type === 'emergency', fn($q) => $q->emergency())
|
||||
->orderBy('DateRecipient', 'DESC')
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить количество пациентов из снапшотов
|
||||
*/
|
||||
private function getCountFromSnapshots(string $type, array $reportIds): int
|
||||
{
|
||||
$query = MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds);
|
||||
|
||||
if ($type === 'outcome') {
|
||||
$query->whereIn('patient_type', ['discharged', 'deceased']);
|
||||
} else {
|
||||
$query->where('patient_type', $type);
|
||||
}
|
||||
|
||||
return $query->distinct('rf_medicalhistory_id')
|
||||
->count('rf_medicalhistory_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать снапшоты для определенного типа пациентов
|
||||
*/
|
||||
private function createSnapshotsForType(Report $report, string $type, array $medicalHistoryIds): void
|
||||
{
|
||||
foreach ($medicalHistoryIds as $id) {
|
||||
MedicalHistorySnapshot::create([
|
||||
'rf_report_id' => $report->report_id,
|
||||
'rf_medicalhistory_id' => $id,
|
||||
'patient_type' => $type,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить 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'),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user