* работа над функционалом автоматического заполнения

* исправил фантомный сдвиг даты
* переделал получение ФИО врачей из отделений
* добавил возможность поиска врача
* переписал сохранение отчета
This commit is contained in:
brusnitsyn
2026-02-05 17:11:43 +09:00
parent eab78a0291
commit 10fb138c30
22 changed files with 1192 additions and 654 deletions

View File

@@ -3,8 +3,10 @@
namespace App\Services;
use App\Models\MedicalHistorySnapshot;
use App\Models\MetrikaResult;
use App\Models\MisMedicalHistory;
use App\Models\MisStationarBranch;
use App\Models\ObservationPatient;
use App\Models\Report;
use App\Models\User;
use Carbon\Carbon;
@@ -13,95 +15,146 @@ use Illuminate\Support\Collection;
class SnapshotService
{
public function __construct(
protected PatientService $patientService
protected PatientService $patientService,
protected DateRangeService $dateRangeService,
) {}
/**
* Создать снапшоты пациентов для отчета
*/
public function createPatientSnapshots(Report $report, User $user, array $dates): void
public function createPatientSnapshots(Report $report, User $user, array $dates, $fillableAuto = false): void
{
$branchId = $this->getBranchId($user->department->rf_mis_department_id);
[$startDate, $endDate] = $this->parseDates($dates);
$dateRange = $this->dateRangeService->getNormalizedDateRange($user, $startDate, $endDate);
$isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin();
// Плановые пациенты
$this->createSnapshotsForType(
$report,
// Массив для хранения подсчитанных метрик
$metrics = [];
// 1. Плановые пациенты
$planIds = $this->patientService->getPlanOrEmergencyPatients(
'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(),
$isHeadOrAdmin,
$branchId,
$startDate,
$endDate,
$dateRange,
false,
true,
true,
$fillableAuto
);
$this->createSnapshotsForType($report, 'plan', $planIds);
$metrics[4] = $this->patientService->getPlanOrEmergencyPatients(
'plan',
$isHeadOrAdmin,
$branchId,
$dateRange,
true,
$fillableAuto
); // metrika_item_3 - плановые
// 2. Экстренные пациенты
$emergencyIds = $this->patientService->getPlanOrEmergencyPatients(
'emergency',
$isHeadOrAdmin,
$branchId,
$dateRange,
false,
true,
true,
$fillableAuto
);
$this->createSnapshotsForType($report, 'emergency', $emergencyIds);
$metrics[12] = $this->patientService->getPlanOrEmergencyPatients(
'emergency',
$isHeadOrAdmin,
$branchId,
$dateRange,
true,
$fillableAuto
);; // metrika_item_12 - экстренные
// 3. Выписанные
$dischargedIds = $this->patientService->getOutcomePatients(
$branchId,
$dateRange,
'discharged',
true
);
$this->createSnapshotsForType($report, 'discharged', $dischargedIds);
$metrics[15] = count($dischargedIds); // metrika_item_15 - выписанные
// 4. Переведенные
$transferredIds = $this->patientService->getOutcomePatients(
$branchId,
$dateRange,
'transferred',
true
);
$this->createSnapshotsForType($report, 'transferred', $transferredIds);
$metrics[13] = count($transferredIds); // metrika_item_13 - переведенные
// 5. Умершие
$deceasedIds = $this->patientService->getOutcomePatients(
$branchId,
$dateRange,
'deceased',
true
);
$this->createSnapshotsForType($report, 'deceased', $deceasedIds);
// $metrics[9] = count($deceasedIds); // metrika_item_9 - умершие
// 6. Поступившие (все новые поступления - плановые + экстренные)
$recipientIds = $this->patientService->getPlanOrEmergencyPatients(
null,
$isHeadOrAdmin,
$branchId,
$dateRange,
false,
true,
false // только поступившие сегодня
);
$this->createSnapshotsForType($report, 'recipient', $recipientIds);
// $metrics[3] = count($recipientIds); // metrika_item_3 - поступившие
// 8. Плановые операции
$planSurgeryCount = $this->patientService->getSurgicalPatients(
'plan',
$branchId,
$dateRange,
true
);
// $metrics[11] = $planSurgeryCount; // metrika_item_11 - плановые операции
// 9. Экстренные операции
$emergencySurgeryCount = $this->patientService->getSurgicalPatients(
'emergency',
$branchId,
$dateRange,
true
);
// $metrics[10] = $emergencySurgeryCount; // metrika_item_10 - экстренные операции
// Сохраняем все метрики
$this->saveMetrics($report, $metrics);
}
/**
* Сохранить метрики в базу
*/
private function saveMetrics(Report $report, array $metrics): void
{
foreach ($metrics as $metrikaItemId => $value) {
MetrikaResult::updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => $metrikaItemId,
],
[
'value' => $value,
]
);
}
}
/**
@@ -126,8 +179,12 @@ class SnapshotService
public function getPatientsFromSnapshots(
string $type,
array $reportIds,
?int $branchId = null
?int $branchId = null,
bool $onlyIds = false
): Collection {
// Для плановых и экстренных включаем уже лечащихся
// $includeCurrent = in_array($type, ['plan', 'emergency']);
$medicalHistoryIds = MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds)
->where('patient_type', $type)
->pluck('rf_medicalhistory_id')
@@ -138,6 +195,10 @@ class SnapshotService
return collect();
}
if ($onlyIds) {
return collect($medicalHistoryIds);
}
return MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
->when($type === 'plan', fn($q) => $q->plan())
->when($type === 'emergency', fn($q) => $q->emergency())
@@ -165,14 +226,21 @@ class SnapshotService
/**
* Создать снапшоты для определенного типа пациентов
*/
private function createSnapshotsForType(Report $report, string $type, array $medicalHistoryIds): void
private function createSnapshotsForType(Report $report, string $type, Collection $medicalHistoryIds): void
{
foreach ($medicalHistoryIds as $id) {
MedicalHistorySnapshot::create([
'rf_report_id' => $report->report_id,
'rf_medicalhistory_id' => $id,
'patient_type' => $type,
]);
MedicalHistorySnapshot::updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_medicalhistory_id' => $id,
'patient_type' => $type
],
[
'rf_report_id' => $report->report_id,
'rf_medicalhistory_id' => $id,
'patient_type' => $type,
]
);
}
}