* доработал страницу отчета дежурного * переделал "действия" над пациентом * подключил виджеты на странице отчета дежурного
85 lines
3.0 KiB
PHP
85 lines
3.0 KiB
PHP
<?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';
|
||
}
|
||
}
|