Добавил возможность выбора отчетов мед. сестры за период

This commit is contained in:
brusnitsyn
2026-06-02 16:24:06 +09:00
parent 6ae5703d29
commit f55dfdc084

View File

@@ -10,29 +10,49 @@ use Illuminate\Support\Carbon;
class UnifiedMedicalHistoryService class UnifiedMedicalHistoryService
{ {
public function getGroupedHistories(DateRange $dateRange, int $departmentId): array public function getGroupedHistories(DateRange $dateRange, int $departmentId, ?string $search = null): array
{ {
$startYear = $dateRange->startDate->copy()->startOfYear()->format('Y-m-d'); $startYear = $dateRange->startDate->copy()->startOfYear()->format('Y-m-d');
$periodMigrationFilter = function ($q) use ($departmentId, $dateRange, $startYear) {
$q->where('department_id', $departmentId)
->where('ingoing_date', '<=', $dateRange->endSql())
->where(function ($sub) use ($dateRange, $startYear) {
// Миграции без out_date (еще лежат)
$sub->whereNull('out_date')
->where('ingoing_date', '>', $startYear);
// Миграции с out_date (закрытые)
$sub->orWhere(function ($sub2) use ($dateRange, $startYear) {
$sub2->whereNotNull('out_date')
->where('out_date', '>', $dateRange->startSql())
->where('out_date', '>', $startYear);
});
});
};
$departmentMigrationFilter = function ($q) use ($departmentId) {
$q->where('department_id', $departmentId)
->orderByDesc('ingoing_date');
};
// 1. Один запрос: получаем "сырые" данные (без вычисляемых статусов) // 1. Один запрос: получаем "сырые" данные (без вычисляемых статусов)
$all = UnifiedMedicalHistory::query()->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange, $startYear) { $all = UnifiedMedicalHistory::query()
$q->where('department_id', $departmentId) ->whereHas('migrations', $periodMigrationFilter)
// пребывание пересекается с отчётным периодом: ingoing <= end AND (out IS NULL OR out >= start) ->when($search, function ($query, $search) {
->where('ingoing_date', '<=', $dateRange->endSql()) // Поиск по ФИО (точное совпадение или LIKE)
->where('ingoing_date', '>=', $startYear) return $query->where(function ($q) use ($search) {
->where(function ($sub) use ($dateRange) { $q->where('full_name', 'ilike', "%{$search}%"); // PostgreSQL
$sub->whereNull('out_date')
->orWhere('out_date', '>=', $dateRange->startSql());
}); });
})->with(['latestMigration' => function ($q) use ($departmentId) { })
$q->where('department_id', $departmentId); ->with([
}, 'latestMigration.operations'])->get(); 'latestMigration' => $periodMigrationFilter,
'migrations' => $departmentMigrationFilter,
])->get();
// 2. Добавляем вычисляемые поля и превращаем в плоский массив // 2. Добавляем вычисляемые поля и превращаем в плоский массив
$prepared = $all->map(function (UnifiedMedicalHistory $h) use ($dateRange) { $prepared = $all->map(function (UnifiedMedicalHistory $h) use ($dateRange) {
$patientStatus = PatientStatusClassifier::classify($h, $dateRange); $patientStatus = PatientStatusClassifier::classify($h, $dateRange);
$patientUrgency = null; $patientUrgency = null;
$patientReanimation = null;
if (!in_array($patientStatus, [ if (!in_array($patientStatus, [
PatientStatusClassifier::STATUS_DECEASED, PatientStatusClassifier::STATUS_DECEASED,
PatientStatusClassifier::STATUS_DISCHARGED, PatientStatusClassifier::STATUS_DISCHARGED,
@@ -47,7 +67,6 @@ class UnifiedMedicalHistoryService
// + вычисляемые мета-поля для фронтенда // + вычисляемые мета-поля для фронтенда
'patient_status' => $patientStatus, 'patient_status' => $patientStatus,
'patient_urgency' => $patientUrgency, 'patient_urgency' => $patientUrgency,
'in_reanimation' => $patientReanimation,
'admitted_today' => PatientStatusClassifier::classifyAdmitted($h->latestMigration?->ingoing_date, $dateRange), 'admitted_today' => PatientStatusClassifier::classifyAdmitted($h->latestMigration?->ingoing_date, $dateRange),
]; ];
}); });
@@ -57,13 +76,12 @@ class UnifiedMedicalHistoryService
$sortOrder = 'desc'; $sortOrder = 'desc';
$sorted = $prepared->sortBy($sortBy, SORT_REGULAR, $sortOrder === 'desc')->values(); $sorted = $prepared->sortBy($sortBy, SORT_REGULAR, $sortOrder === 'desc')->values();
// 4. Возвращаем плоский массив + метаданные для фронтенда
$countInDepartment = $sorted->where('patient_status', 'in_department')->count(); $countInDepartment = $sorted->where('patient_status', 'in_department')->count();
$countRecipient = $sorted->where('patient_status', 'recipient')->count(); $countRecipient = $sorted->where('patient_status', 'recipient')->count();
$countDischarged = $sorted->where('patient_status', 'discharged')->count(); $countDischarged = $sorted->where('patient_status', 'discharged')->count();
$countDeceased = $sorted->where('patient_status', 'deceased')->count();
$countUrgent = $sorted->where('patient_urgency', 'urgent')->count(); $countUrgent = $sorted->where('patient_urgency', 'urgent')->count();
$countPlanned = $sorted->where('patient_urgency', 'planned')->count(); $countPlanned = $sorted->where('patient_urgency', 'planned')->count();
$countReanimations = $sorted->where('in_reanimation', true)->count();
// 4. Возвращаем плоский массив + метаданные для фронтенда // 4. Возвращаем плоский массив + метаданные для фронтенда
return [ return [
@@ -78,7 +96,7 @@ class UnifiedMedicalHistoryService
'discharged' => $countDischarged, 'discharged' => $countDischarged,
'urgent' => $countUrgent, 'urgent' => $countUrgent,
'planned' => $countPlanned, 'planned' => $countPlanned,
'reanimations' => $countReanimations, 'deceased' => $countDeceased,
] ]
] ]
]; ];