'date', 'admitted_at' => 'datetime', 'outcome_at' => 'datetime', 'is_manual' => 'boolean', ]; /** * Типы пациентов */ const PATIENT_TYPE_DISCHARGED = 'discharged'; // Выписанные const PATIENT_TYPE_CURRENT = 'current'; // Текущие public function report() { return $this->belongsTo(Report::class, 'rf_report_id'); } public function medicalHistory() { return $this->belongsTo(MedicalHistory::class, 'rf_medicalhistory_id', 'original_id'); } public function departmentPatient() { return $this->belongsTo(DepartmentPatient::class, 'rf_department_patient_id', 'department_patient_id'); } // Скоупы для фильтрации public function scopeForReport($query, $reportId) { return $query->where('rf_report_id', $reportId); } public function scopeByPatientType($query, $type) { return $query->where('patient_type', $type); } public function scopeByDepartment($query, $departmentId) { return $query->whereHas('medicalHistory.migrations', function ($q) use ($departmentId) { $q->department($departmentId); }); } /** * Исключить из снимка карты, по которым в МИС оформлен отказ от госпитализации. * Снимок остаётся неизменным (immutable) — отсекаем только при чтении. * Безопасно: пока таблицы отказов нет в реплике — no-op (см. MisDenial::tableAvailable()). */ public function scopeWithoutDenials($query) { if (! MisDenial::tableAvailable()) { return $query; } $denialTable = (new MisDenial)->getTable(); $snapshotTable = $this->getTable(); return $query->whereNotExists(function ($sub) use ($denialTable, $snapshotTable) { $sub->selectRaw('1') ->from($denialTable) ->whereColumn("{$denialTable}.rf_MedicalHistoryID", "{$snapshotTable}.rf_medicalhistory_id"); }); } }