* оптимизировал запросы выдачи пациентов, сохранения снапшотов
* доработал страницу отчета дежурного * переделал "действия" над пациентом * подключил виджеты на странице отчета дежурного
This commit is contained in:
@@ -52,52 +52,31 @@ class DutyReportController extends Controller
|
||||
|
||||
if ($hasReport) {
|
||||
$inDepartmentHistories = $this->dutyMedicalHistoryService->getDepartmentHistories($dateRange, $department->rf_mis_department_id);
|
||||
$plannedHistories = collect([ 'data' => [] ]);
|
||||
$emergencyHistories = collect([ 'data' => [] ]);
|
||||
$recipientHistories = $this->dutyMedicalHistoryService->getRecipientHistories($dateRange, $department->rf_mis_department_id);
|
||||
$dischargedHistories = $this->dutyMedicalHistoryService->getDischargedHistories($dateRange, $department->rf_mis_department_id);
|
||||
$deceasedHistories = $this->dutyMedicalHistoryService->getDeceasedHistories($dateRange, $department->rf_mis_department_id);
|
||||
$transferredHistories = $this->dutyMedicalHistoryService->getTransferredHistories($dateRange, $department->rf_mis_department_id);
|
||||
$reanimationHistories = collect([ 'data' => [] ]);
|
||||
} else if ($this->dateRangeService->isPastPeriod($dateRange)) {
|
||||
$inDepartmentHistories = collect([]);
|
||||
$recipientHistories = collect([]);
|
||||
$dischargedHistories = collect([]);
|
||||
$deceasedHistories = collect([]);
|
||||
$transferredHistories = collect([]);
|
||||
$inDepartmentHistories = collect([ 'data' => [] ]);
|
||||
$plannedHistories = collect([ 'data' => [] ]);
|
||||
$emergencyHistories = collect([ 'data' => [] ]);
|
||||
$recipientHistories = collect([ 'data' => [] ]);
|
||||
$dischargedHistories = collect([ 'data' => [] ]);
|
||||
$deceasedHistories = collect([ 'data' => [] ]);
|
||||
$transferredHistories = collect([ 'data' => [] ]);
|
||||
$reanimationHistories = collect([ 'data' => [] ]);
|
||||
} else {
|
||||
$inDepartmentHistories = MedicalHistoryResource::collection(
|
||||
$this->medicalHistoryService->getDepartmentHistories($dateRange, $department->rf_mis_department_id)
|
||||
);
|
||||
$plannedHistories = MedicalHistoryResource::collection(
|
||||
$this->medicalHistoryService->getPlannedHistories($dateRange, $department->rf_mis_department_id)
|
||||
);
|
||||
$emergencyHistories = MedicalHistoryResource::collection(
|
||||
$this->medicalHistoryService->getEmergencyHistories($dateRange, $department->rf_mis_department_id)
|
||||
);
|
||||
$recipientHistories = MedicalHistoryResource::collection(
|
||||
$this->medicalHistoryService->getRecipientHistories($dateRange, $department->rf_mis_department_id)
|
||||
);
|
||||
$dischargedHistories = MedicalHistoryResource::collection(
|
||||
$this->medicalHistoryService->getDischargedHistories($dateRange, $department->rf_mis_department_id)
|
||||
);
|
||||
$deceasedHistories = MedicalHistoryResource::collection(
|
||||
$this->medicalHistoryService->getDeceasedHistories($dateRange, $department->rf_mis_department_id)
|
||||
);
|
||||
$transferredHistories = MedicalHistoryResource::collection(
|
||||
$this->medicalHistoryService->getTransferredHistories($dateRange, $department->rf_mis_department_id)
|
||||
);
|
||||
$reanimationHistories = MedicalHistoryResource::collection(
|
||||
$this->medicalHistoryService->getReanimationHistories($dateRange, $department->rf_mis_department_id)
|
||||
);
|
||||
$patients = $this->medicalHistoryService->getGroupedHistories($dateRange, $department->rf_mis_department_id);
|
||||
}
|
||||
|
||||
return Inertia::render('Report/Index', [
|
||||
'inDepartmentHistories' => $inDepartmentHistories,
|
||||
'plannedHistories' => $plannedHistories,
|
||||
'emergencyHistories' => $emergencyHistories,
|
||||
'recipientHistories' => $recipientHistories,
|
||||
'dischargedHistories' => $dischargedHistories,
|
||||
'deceasedHistories' => $deceasedHistories,
|
||||
'transferredHistories' => $transferredHistories,
|
||||
'reanimationHistories' => $reanimationHistories,
|
||||
'patients' => $patients,
|
||||
'departmentInfo' => [
|
||||
// TODO: Добавить вывод информации из шапки
|
||||
],
|
||||
'dates' => [
|
||||
$dateRange->startDate->getTimestampMs(),
|
||||
$dateRange->endDate->getTimestampMs(),
|
||||
|
||||
@@ -44,32 +44,30 @@ class NurseReportController extends Controller
|
||||
|
||||
$hasReport = $existsReport && $isPastPeriod;
|
||||
|
||||
if ($hasReport) {
|
||||
$inDepartmentHistories = $this->nurseMedicalHistoryService->getDepartmentHistories($dateRange, $department->rf_mis_department_id);
|
||||
$recipientHistories = $this->nurseMedicalHistoryService->getRecipientHistories($dateRange, $department->rf_mis_department_id);
|
||||
$dischargedHistories = $this->nurseMedicalHistoryService->getDischargedHistories($dateRange, $department->rf_mis_department_id);
|
||||
$deceasedHistories = $this->nurseMedicalHistoryService->getDeceasedHistories($dateRange, $department->rf_mis_department_id);
|
||||
$transferredHistories = $this->nurseMedicalHistoryService->getTransferredHistories($dateRange, $department->rf_mis_department_id);
|
||||
} else if ($this->dateRangeService->isPastPeriod($dateRange)) {
|
||||
$inDepartmentHistories = collect([]);
|
||||
$recipientHistories = collect([]);
|
||||
$dischargedHistories = collect([]);
|
||||
$deceasedHistories = collect([]);
|
||||
$transferredHistories = collect([]);
|
||||
} else {
|
||||
$inDepartmentHistories = $this->unifiedMedicalHistoryService->getDepartmentHistories($dateRange, $department->rf_mis_department_id);
|
||||
$recipientHistories = $this->unifiedMedicalHistoryService->getRecipientHistories($dateRange, $department->rf_mis_department_id);
|
||||
$dischargedHistories = $this->unifiedMedicalHistoryService->getDischargedHistories($dateRange, $department->rf_mis_department_id);
|
||||
$deceasedHistories = $this->unifiedMedicalHistoryService->getDeceasedHistories($dateRange, $department->rf_mis_department_id);
|
||||
$transferredHistories = $this->unifiedMedicalHistoryService->getTransferredHistories($dateRange, $department->rf_mis_department_id);
|
||||
}
|
||||
// if ($hasReport) {
|
||||
// $inDepartmentHistories = $this->nurseMedicalHistoryService->getDepartmentHistories($dateRange, $department->rf_mis_department_id);
|
||||
// $recipientHistories = $this->nurseMedicalHistoryService->getRecipientHistories($dateRange, $department->rf_mis_department_id);
|
||||
// $dischargedHistories = $this->nurseMedicalHistoryService->getDischargedHistories($dateRange, $department->rf_mis_department_id);
|
||||
// $deceasedHistories = $this->nurseMedicalHistoryService->getDeceasedHistories($dateRange, $department->rf_mis_department_id);
|
||||
// $transferredHistories = $this->nurseMedicalHistoryService->getTransferredHistories($dateRange, $department->rf_mis_department_id);
|
||||
// } else if ($this->dateRangeService->isPastPeriod($dateRange)) {
|
||||
// $inDepartmentHistories = collect([]);
|
||||
// $recipientHistories = collect([]);
|
||||
// $dischargedHistories = collect([]);
|
||||
// $deceasedHistories = collect([]);
|
||||
// $transferredHistories = collect([]);
|
||||
// } else {
|
||||
// $inDepartmentHistories = $this->unifiedMedicalHistoryService->getDepartmentHistories($dateRange, $department->rf_mis_department_id);
|
||||
// $recipientHistories = $this->unifiedMedicalHistoryService->getRecipientHistories($dateRange, $department->rf_mis_department_id);
|
||||
// $dischargedHistories = $this->unifiedMedicalHistoryService->getDischargedHistories($dateRange, $department->rf_mis_department_id);
|
||||
// $deceasedHistories = $this->unifiedMedicalHistoryService->getDeceasedHistories($dateRange, $department->rf_mis_department_id);
|
||||
// $transferredHistories = $this->unifiedMedicalHistoryService->getTransferredHistories($dateRange, $department->rf_mis_department_id);
|
||||
// }
|
||||
|
||||
$data = $this->unifiedMedicalHistoryService->getGroupedHistories($dateRange, $department->rf_mis_department_id);
|
||||
|
||||
return Inertia::render('Nurse/Report/Index', [
|
||||
'inDepartmentHistories' => $inDepartmentHistories,
|
||||
'recipientHistories' => $recipientHistories,
|
||||
'dischargedHistories' => $dischargedHistories,
|
||||
'deceasedHistories' => $deceasedHistories,
|
||||
'transferredHistories' => $transferredHistories,
|
||||
'patients' => $data,
|
||||
'dates' => [
|
||||
$dateRange->startDate->getTimestampMs(),
|
||||
$dateRange->endDate->getTimestampMs(),
|
||||
|
||||
@@ -104,7 +104,7 @@ class MigrationPatient extends MaterializedViewModel
|
||||
->where('ingoing_date', '<', $dateRange->startSql())
|
||||
->wherehas('medicalHistory', function ($query) use ($dateRange) {
|
||||
$query->whereNull('extract_date');
|
||||
}); // опционально: поступил не раньше 2 лет назад
|
||||
});
|
||||
})
|
||||
->orWhere(function ($q) use ($dateRange) {
|
||||
$q->where('ingoing_date', '<=', $dateRange->endSql())
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Models;
|
||||
|
||||
use App\Services\DateRange;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class UnifiedMigrationPatient extends Model
|
||||
@@ -89,4 +90,23 @@ class UnifiedMigrationPatient extends Model
|
||||
->orderBy('ingoing_date', 'desc')
|
||||
->limit(1)->first();
|
||||
}
|
||||
|
||||
public function getAdmittedInCurrentAttribute(): bool
|
||||
{
|
||||
// Получаем дату поступления из последнего движения
|
||||
$ingoing = $this->ingoing_date;
|
||||
|
||||
if (!$ingoing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ingoingLocal = Carbon::parse($ingoing)->setTimezone(config('app.timezone', 'Europe/Moscow'));
|
||||
$now = Carbon::now(config('app.timezone', 'Europe/Moscow'));
|
||||
|
||||
// Окно смены: вчера 09:00 → сегодня 09:00
|
||||
$shiftStart = $now->copy()->subDay()->setTime(9, 0);
|
||||
$shiftEnd = $now->copy()->setTime(9, 0);
|
||||
|
||||
return $ingoingLocal->between($shiftStart, $shiftEnd);
|
||||
}
|
||||
}
|
||||
|
||||
84
app/Services/Classification/PatientStatusClassifier.php
Normal file
84
app/Services/Classification/PatientStatusClassifier.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
namespace App\Services\Classification;
|
||||
|
||||
use App\Models\MedicalHistory;
|
||||
use App\Models\UnifiedMedicalHistory;
|
||||
use App\Services\DateRange;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class PatientStatusClassifier
|
||||
{
|
||||
public const STATUS_IN_DEPARTMENT = 'in_department';
|
||||
public const STATUS_RECIPIENT = 'recipient';
|
||||
public const STATUS_DISCHARGED = 'discharged';
|
||||
public const STATUS_TRANSFERRED = 'transferred';
|
||||
public const STATUS_DECEASED = 'deceased';
|
||||
public const URGENCY_URGENT = 'urgent'; // urgency_id = 1
|
||||
public const URGENCY_PLANNED = 'planned'; // urgency_id = 2
|
||||
public const URGENCY_UNKNOWN = 'unknown';
|
||||
|
||||
/**
|
||||
* Определяет срочность пациента.
|
||||
*/
|
||||
public static function classifyUrgency(?int $urgencyId): string
|
||||
{
|
||||
return match ($urgencyId) {
|
||||
1 => self::URGENCY_URGENT,
|
||||
2 => self::URGENCY_PLANNED,
|
||||
default => self::URGENCY_UNKNOWN,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Определяет поступил ли пациент в диапазоне.
|
||||
*/
|
||||
public static function classifyAdmitted(Carbon|string|null $ingoingDate): bool
|
||||
{
|
||||
if (is_null($ingoingDate)) {return false;}
|
||||
|
||||
$ingoingLocal = Carbon::parse($ingoingDate);
|
||||
$now = Carbon::now();
|
||||
|
||||
// Окно смены: вчера 09:00 → сегодня 09:00
|
||||
$shiftStart = $now->copy()->subDay()->setTime(9, 0);
|
||||
$shiftEnd = $now->copy()->setTime(9, 0);
|
||||
|
||||
return $ingoingLocal->between($shiftStart, $shiftEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Определяет статус пациента на основе "сырых" полей из БД.
|
||||
* Логика изолирована и может быть легко протестирована.
|
||||
*/
|
||||
public static function classify(UnifiedMedicalHistory|MedicalHistory $history, DateRange $dateRange): string
|
||||
{
|
||||
// 1. Смерть — приоритет №1 (не зависит от дат)
|
||||
if (!empty($history->death_date)) {
|
||||
return self::STATUS_DECEASED;
|
||||
}
|
||||
|
||||
// 2. Если есть дата выбытия
|
||||
if (!empty($history->extract_date)) {
|
||||
// Переведён (коды 3, 4)
|
||||
if (in_array($history->visit_result_id, [3, 4], true)) {
|
||||
return self::STATUS_TRANSFERRED;
|
||||
}
|
||||
// Выписан домой/иное (исключаем коды 3-6)
|
||||
if (in_array($history->visit_result_id, [1], true)) {
|
||||
return self::STATUS_DISCHARGED;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Поступившие
|
||||
if ($history->latestMigration?->getAdmittedInCurrentAttribute()) {
|
||||
return self::STATUS_RECIPIENT;
|
||||
}
|
||||
|
||||
// 4. В отделении
|
||||
if (empty($history->latestMigration?->out_date) && $history->latestMigration?->ingoing_date < $dateRange->startDate) {
|
||||
return self::STATUS_IN_DEPARTMENT;
|
||||
}
|
||||
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
@@ -64,10 +64,10 @@ class DutyReportService
|
||||
/**
|
||||
* Сохранить снимок пациентов за период
|
||||
*/
|
||||
public function saveSnapshot(DateRange $dateRange, ReportNurse $reportNurse, ?int $departmentId = null, ?int $userId = null): array
|
||||
public function saveSnapshot(DateRange $dateRange, ReportDuty $reportDuty, ?int $departmentId = null, ?int $userId = null): array
|
||||
{
|
||||
$departmentId = $departmentId ?? $reportNurse->department->rf_mis_department_id;
|
||||
$userId = $userId ?? $reportNurse->rf_user_id;
|
||||
$departmentId = $departmentId ?? $reportDuty->department->rf_mis_department_id;
|
||||
$userId = $userId ?? $reportDuty->rf_user_id;
|
||||
$startYear = Carbon::now()->startOfYear()->format('Y-m-d');
|
||||
|
||||
$query = MedicalHistory::query()
|
||||
@@ -87,7 +87,7 @@ class DutyReportService
|
||||
// Получаем данные (chunk для памяти, если пациентов > 1000)
|
||||
$patients = $query->cursor();
|
||||
|
||||
$savedStats = $this->saveReportSnapshot($reportNurse->id, $patients, $userId);
|
||||
$savedStats = $this->saveReportSnapshot($reportDuty->id, $patients, $userId);
|
||||
|
||||
return [
|
||||
...$savedStats,
|
||||
@@ -109,9 +109,9 @@ class DutyReportService
|
||||
foreach ($patients as $patient) {
|
||||
// Подготовка данных пациента
|
||||
$patientBatch[] = [
|
||||
'report_nurse_id' => $reportDutyId,
|
||||
'source_type' => $patient->source_type,
|
||||
'original_id' => $patient->original_id,
|
||||
'report_duty_id' => $reportDutyId,
|
||||
'source_type' => 'mis',
|
||||
'original_id' => $patient->id,
|
||||
'medical_card_number' => $patient->medical_card_number,
|
||||
'full_name' => $patient->full_name,
|
||||
'birth_date' => $patient->birth_date,
|
||||
@@ -184,7 +184,7 @@ class DutyReportService
|
||||
$patientUniqueBy = ['report_duty_id', 'source_type', 'original_id'];
|
||||
$patientUpdateColumns = array_diff(array_keys($patientBatch[0]), $patientUniqueBy);
|
||||
|
||||
DB::table('report_nurse_patients')->upsert(
|
||||
DB::table('report_duty_patients')->upsert(
|
||||
$patientBatch,
|
||||
$patientUniqueBy,
|
||||
$patientUpdateColumns
|
||||
|
||||
@@ -4,10 +4,74 @@ namespace App\Services;
|
||||
|
||||
use App\Models\MedicalHistory;
|
||||
use App\Models\MigrationPatient;
|
||||
use App\Services\Classification\PatientStatusClassifier;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class MedicalHistoryService
|
||||
{
|
||||
public function getGroupedHistories(DateRange $dateRange, int $departmentId): array
|
||||
{
|
||||
$startYear = Carbon::now()->startOfYear()->format('Y-m-d');
|
||||
|
||||
// 1. Один запрос: получаем "сырые" данные (без вычисляемых статусов)
|
||||
$all = MedicalHistory::query()->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange, $startYear) {
|
||||
$q->where('department_id', $departmentId)
|
||||
// пребывание пересекается с отчётным периодом
|
||||
->where('ingoing_date', '<=', $dateRange->endSql())
|
||||
->where('ingoing_date', '>=', $startYear)
|
||||
->where(function ($sub) use ($dateRange) {
|
||||
$sub->whereNull('out_date')
|
||||
->orWhere('out_date', '>=', $dateRange->startSql())
|
||||
->where('out_date', '<=', $dateRange->endSql());
|
||||
});
|
||||
})->with(['latestMigration' => function ($q) use ($departmentId) {
|
||||
$q->where('department_id', $departmentId);
|
||||
}, 'latestMigration.operations', 'latestMigration.reanimations'])->get();
|
||||
|
||||
|
||||
// 2. Добавляем вычисляемые поля и превращаем в плоский массив
|
||||
$prepared = $all->map(function (MedicalHistory $h) use ($dateRange) {
|
||||
$patientStatus = PatientStatusClassifier::classify($h, $dateRange);
|
||||
$patientUrgency = null;
|
||||
if (!in_array($patientStatus, [
|
||||
PatientStatusClassifier::STATUS_DECEASED,
|
||||
PatientStatusClassifier::STATUS_DISCHARGED,
|
||||
PatientStatusClassifier::STATUS_TRANSFERRED
|
||||
])) $patientUrgency = PatientStatusClassifier::classifyUrgency($h->urgency_id);
|
||||
return [
|
||||
// Все исходные поля модели (автоматически через toArray)
|
||||
...$h->toArray(),
|
||||
|
||||
// + вычисляемые мета-поля для фронтенда
|
||||
'patient_status' => $patientStatus,
|
||||
'patient_urgency' => $patientUrgency,
|
||||
'admitted_today' => PatientStatusClassifier::classifyAdmitted($h->latestMigration?->ingoing_date),
|
||||
];
|
||||
});
|
||||
|
||||
// 3. Сортировка
|
||||
$sortBy = 'recipient_date';
|
||||
$sortOrder = 'desc';
|
||||
$sorted = $prepared->sortBy($sortBy, SORT_REGULAR, $sortOrder === 'desc')->values();
|
||||
|
||||
// 4. Возвращаем плоский массив + метаданные для фронтенда
|
||||
return [
|
||||
'data' => $sorted->toArray(),
|
||||
'meta' => [
|
||||
'total' => $sorted->count(),
|
||||
'sortBy' => $sortBy,
|
||||
'sortOrder' => $sortOrder,
|
||||
// Статистика для фильтров/бейджей (опционально)
|
||||
'counts' => [
|
||||
'in_department' => $sorted->where('patient_status', 'in_department')->count(),
|
||||
'discharged' => $sorted->where('patient_status', 'discharged')->count(),
|
||||
'urgent' => $sorted->where('patient_urgency', 'urgent')->count(),
|
||||
'planned' => $sorted->where('patient_urgency', 'planned')->count(),
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function getHistories(DateRange $dateRange, int $departmentId)
|
||||
{
|
||||
$query = MedicalHistory::query();
|
||||
|
||||
@@ -5,10 +5,67 @@ namespace App\Services;
|
||||
use App\Models\MedicalHistory;
|
||||
use App\Models\MigrationPatient;
|
||||
use App\Models\UnifiedMedicalHistory;
|
||||
use App\Services\Classification\PatientStatusClassifier;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class UnifiedMedicalHistoryService
|
||||
{
|
||||
public function getGroupedHistories(DateRange $dateRange, int $departmentId): array
|
||||
{
|
||||
// 1. Один запрос: получаем "сырые" данные (без вычисляемых статусов)
|
||||
$all = UnifiedMedicalHistory::with([
|
||||
'latestMigration' => fn($q) => $q->where(function ($q) use ($dateRange) {
|
||||
// Вариант А: Пациент уже лежит (текущий)
|
||||
$q->whereNull('out_date')
|
||||
->whereNotNull('medical_history_id')
|
||||
->where('ingoing_date', '<', $dateRange->startSql());
|
||||
})
|
||||
->orWhere(function ($q) use ($dateRange) {
|
||||
$q->where('ingoing_date', '<=', $dateRange->endSql())
|
||||
->where('ingoing_date', '>', $dateRange->startSql());
|
||||
})
|
||||
])
|
||||
->whereNull('extract_date')
|
||||
->get()
|
||||
// Фильтр по отделению в памяти (быстро для <1000 записей)
|
||||
->filter(fn($h) => $h->latestMigration?->department_id === $departmentId);
|
||||
|
||||
// 2. Добавляем вычисляемые поля и превращаем в плоский массив
|
||||
$prepared = $all->map(function (UnifiedMedicalHistory $h) use ($dateRange) {
|
||||
return [
|
||||
// Все исходные поля модели (автоматически через toArray)
|
||||
...$h->toArray(),
|
||||
|
||||
// + вычисляемые мета-поля для фронтенда
|
||||
'patient_status' => PatientStatusClassifier::classify($h, $dateRange),
|
||||
'patient_urgency' => PatientStatusClassifier::classifyUrgency($h->urgency_id),
|
||||
'admitted_today' => PatientStatusClassifier::classifyAdmitted($h->latestMigration?->ingoing_date),
|
||||
];
|
||||
});
|
||||
|
||||
// 3. Сортировка
|
||||
$sortBy = 'recipient_date';
|
||||
$sortOrder = 'desc';
|
||||
$sorted = $prepared->sortBy($sortBy, SORT_REGULAR, $sortOrder === 'desc')->values();
|
||||
|
||||
// 4. Возвращаем плоский массив + метаданные для фронтенда
|
||||
return [
|
||||
'data' => $sorted->toArray(),
|
||||
'meta' => [
|
||||
'total' => $sorted->count(),
|
||||
'sortBy' => $sortBy,
|
||||
'sortOrder' => $sortOrder,
|
||||
// Статистика для фильтров/бейджей (опционально)
|
||||
'counts' => [
|
||||
'in_department' => $sorted->where('patient_status', 'in_department')->count(),
|
||||
'discharged' => $sorted->where('patient_status', 'discharged')->count(),
|
||||
'urgent' => $sorted->where('patient_urgency', 'urgent')->count(),
|
||||
'planned' => $sorted->where('patient_urgency', 'planned')->count(),
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function getHistories(DateRange $dateRange, int $departmentId)
|
||||
{
|
||||
$query = UnifiedMedicalHistory::query();
|
||||
@@ -49,12 +106,10 @@ class UnifiedMedicalHistoryService
|
||||
public function getDepartmentHistories(DateRange $dateRange, int $departmentId)
|
||||
{
|
||||
return UnifiedMedicalHistory::query()
|
||||
->whereHas('migrations', function ($q) use ($departmentId, $dateRange) {
|
||||
->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange) {
|
||||
$q->department($departmentId)->current($dateRange);
|
||||
})
|
||||
->with(['latestMigration' => function ($q) use ($departmentId, $dateRange) {
|
||||
$q->department($departmentId)->current($dateRange); // подгружаем только отфильтрованные движения
|
||||
}])
|
||||
->with(['latestMigration'])
|
||||
->get()
|
||||
// Сортировка по дате поступления в отделение (поле дочерней таблицы)
|
||||
->sortByDesc(fn ($mh) => $mh->latestMigration->ingoing_date ?? $mh->recipient_date)
|
||||
@@ -71,48 +126,40 @@ class UnifiedMedicalHistoryService
|
||||
$now = Carbon::now();
|
||||
|
||||
return UnifiedMedicalHistory::query()
|
||||
->whereHas('migrations', function ($q) use ($departmentId, $dateRange) {
|
||||
->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange) {
|
||||
$q->department($departmentId)->admitted($dateRange->startSql(), $dateRange->endSql());
|
||||
})
|
||||
->with(['latestMigration' => function ($q) use ($departmentId) {
|
||||
$q->department($departmentId);
|
||||
}])
|
||||
->with(['latestMigration'])
|
||||
->get();
|
||||
}
|
||||
|
||||
public function getDischargedHistories(DateRange $dateRange, int $departmentId)
|
||||
{
|
||||
return UnifiedMedicalHistory::query()
|
||||
->whereHas('migrations', function ($q) use ($departmentId, $dateRange) {
|
||||
->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange) {
|
||||
$q->department($departmentId)->discharged($dateRange->startSql(), $dateRange->endSql());
|
||||
})
|
||||
->with(['latestMigration' => function ($q) use ($departmentId) {
|
||||
$q->department($departmentId);
|
||||
}])
|
||||
->with(['latestMigration'])
|
||||
->get();
|
||||
}
|
||||
|
||||
public function getDeceasedHistories(DateRange $dateRange, int $departmentId)
|
||||
{
|
||||
return UnifiedMedicalHistory::query()
|
||||
->whereHas('migrations', function ($q) use ($departmentId, $dateRange) {
|
||||
->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange) {
|
||||
$q->department($departmentId)->deceased($dateRange->startSql(), $dateRange->endSql());
|
||||
})
|
||||
->with(['latestMigration' => function ($q) use ($departmentId) {
|
||||
$q->department($departmentId);
|
||||
}])
|
||||
->with(['latestMigration'])
|
||||
->get();
|
||||
}
|
||||
|
||||
public function getTransferredHistories(DateRange $dateRange, int $departmentId)
|
||||
{
|
||||
return UnifiedMedicalHistory::query()
|
||||
->whereHas('migrations', function ($q) use ($departmentId, $dateRange) {
|
||||
->whereHas('latestMigration', function ($q) use ($departmentId, $dateRange) {
|
||||
$q->department($departmentId)->transferred($dateRange->startSql(), $dateRange->endSql());
|
||||
})
|
||||
->with(['latestMigration' => function ($q) use ($departmentId) {
|
||||
$q->department($departmentId);
|
||||
}])
|
||||
->with(['latestMigration'])
|
||||
->get();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user