'datetime', 'sent_at' => 'datetime', 'period_start' => 'datetime', 'period_end' => 'datetime', ]; public function scopeWithinPeriod(Builder $query, string $startAt, string $endAt): Builder { return $query ->where('period_start', '>=', $startAt) ->where('period_start', '<=', $endAt); } public function scopeExactPeriod(Builder $query, string $startAt, string $endAt): Builder { return $query ->where('period_start', '>=', $startAt) ->where('period_end', '<=', $endAt); } public function scopeOnlySubmitted(Builder $query): Builder { return $query->where('status', 'submitted'); } public function metrikaResults(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(MetrikaResult::class, 'rf_report_id', 'report_id'); } public function observationPatients(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(ObservationPatient::class, 'rf_report_id', 'report_id'); } public function unwantedEvents() { return $this->hasMany(UnwantedEvent::class, 'rf_report_id', 'report_id'); } public function user() { return $this->belongsTo(User::class, 'rf_user_id'); } public function lpuDoctor() { return $this->belongsTo(MisLpuDoctor::class, 'rf_lpudoctor_id'); } /** * Связь со снапшотами */ public function snapshots() { return $this->hasMany(MedicalHistorySnapshot::class, 'rf_report_id', 'report_id'); } /** * Получить выписанных пациентов из снапшотов */ public function getDischargedPatientsOnSnapshots() { return $this->snapshots() ->where('patient_type', MedicalHistorySnapshot::PATIENT_TYPE_DISCHARGED) ->distinct() ->with('medicalHistory') ->get(); } /** * Получить текущих пациентов из снапшотов */ public function getCurrentPatientsOnSnapshots() { return $this->snapshots() ->where('patient_type', MedicalHistorySnapshot::PATIENT_TYPE_CURRENT) ->with('medicalHistory') ->get(); } /** * Рассчитать и сохранить средний койко-день на основе снапшотов */ public function calculateAndSaveAverageBedDays() { $dischargedPatients = $this->getDischargedPatientsOnSnapshots(); if ($dischargedPatients->isEmpty()) { $avgBedDays = 0; } else { $totalDays = 0; foreach ($dischargedPatients as $snapshot) { $history = $snapshot->medicalHistory; if ($history && $history->DateRecipient && $history->DateExtract) { $start = Carbon::parse($history->DateRecipient); $end = Carbon::parse($history->DateExtract); $days = $start->diffInDays($end); $totalDays += $days; } } $avgBedDays = round($totalDays / $dischargedPatients->count(), 1); } // Сохраняем результат как метрику MetrikaResult::updateOrCreate([ 'rf_report_id' => $this->report_id, 'rf_metrika_item_id' => self::METRIC_BED_DAYS_ID, ], [ 'value' => $avgBedDays, ]); return $avgBedDays; } }