* доработал страницу отчета дежурного * переделал "действия" над пациентом * подключил виджеты на странице отчета дежурного
113 lines
3.7 KiB
PHP
113 lines
3.7 KiB
PHP
<?php
|
||
|
||
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
|
||
{
|
||
protected $table = 'v_unified_migration_patient_nurse';
|
||
protected $primaryKey = 'id';
|
||
|
||
protected $casts = [
|
||
'ingoing_date' => 'datetime:Y-m-d H:i:s',
|
||
'out_date' => 'datetime:Y-m-d H:i:s',
|
||
];
|
||
|
||
public function medicalHistory()
|
||
{
|
||
return $this->belongsTo(UnifiedMedicalHistory::class, 'medical_history_id', 'id');
|
||
}
|
||
|
||
public function operations()
|
||
{
|
||
return $this->hasMany(SurgicalOperation::class, 'migration_patient_id', 'id');
|
||
}
|
||
|
||
// Пересечение с отчетным периодом
|
||
public function scopeDateRange($query, string $from, string $to)
|
||
{
|
||
return $query->where('ingoing_date', '<=', $to)
|
||
->where(function ($q) use ($from) {
|
||
$q->whereNull('out_date')->orWhere('out_date', '>=', $from);
|
||
});
|
||
}
|
||
|
||
// Фильтр по подразделению (получает ID отделений)
|
||
public function scopeDepartment($query, int $departmentId)
|
||
{
|
||
$branchIds = DB::table('stt_stationarbranch')
|
||
->where('rf_DepartmentID', $departmentId)
|
||
->pluck('StationarBranchID');
|
||
|
||
return $query->whereIn('stationar_branch_id', $branchIds);
|
||
}
|
||
|
||
// Быстрые фильтры по статусам (используют индексы MV, а не computed column)
|
||
public function scopeAdmitted($query, string $from, string $to)
|
||
{
|
||
return $query->where('ingoing_date', '>', $from)
|
||
->where('ingoing_date', '<=', $to);
|
||
}
|
||
|
||
public function scopeDischarged($query, string $from, string $to)
|
||
{
|
||
return $query->where('out_date', '>', $from)
|
||
->where('out_date', '<=', $to)
|
||
->whereNotIn('visit_result_id', [3, 4, 5, 6])
|
||
->whereNull('death_date'); // умершие не считаются "выбывшими домой"
|
||
}
|
||
|
||
public function scopeTransferred($query, string $from, string $to)
|
||
{
|
||
return $query->where('out_date', '>', $from)
|
||
->where('out_date', '<=', $to)
|
||
->whereIn('visit_result_id', [3, 4]);
|
||
}
|
||
|
||
public function scopeDeceased($query, string $from, string $to)
|
||
{
|
||
return $query->whereNotNull('death_date')
|
||
->where('death_date', '>', $from)
|
||
->where('death_date', '<=', $to);
|
||
}
|
||
|
||
public function scopeCurrent($query, DateRange $dateRange)
|
||
{
|
||
return $query->whereNull('out_date')
|
||
->whereNotNull('medical_history_id')
|
||
->where('ingoing_date', '<', $dateRange->startSql())
|
||
->whereNull('patient_extract_date');
|
||
}
|
||
|
||
public function scopeCurrentMigration($query, $historyId, $departmentId)
|
||
{
|
||
return $query->where('medical_history_id', $historyId)
|
||
->department($departmentId)
|
||
->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);
|
||
}
|
||
}
|