* изменил таблицы в основном отчете

* изменил метод сохранения пациентов основного отчета
This commit is contained in:
brusnitsyn
2026-05-07 18:00:43 +09:00
parent 723ccee8d3
commit bb9e67ab3d
25 changed files with 1438 additions and 52 deletions

View File

@@ -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 MigrationPatient extends MaterializedViewModel
@@ -11,6 +12,14 @@ class MigrationPatient extends MaterializedViewModel
protected $table = 'mv_migrationpatient_details';
protected $primaryKey = 'id';
protected $casts = [
'birth_date' => 'date:Y-m-d',
'recipient_date' => 'datetime:Y-m-d H:i:s',
'extract_date' => 'datetime:Y-m-d H:i:s',
'death_date' => 'datetime:Y-m-d H:i:s',
'male' => 'boolean',
];
public function medicalHistory()
{
return $this->belongsTo(MedicalHistory::class, 'medical_history_id', 'id');
@@ -18,7 +27,8 @@ class MigrationPatient extends MaterializedViewModel
public function operations()
{
return $this->hasMany(SurgicalOperation::class, 'migration_patient_id', 'id');
return $this->hasMany(SurgicalOperation::class, 'migration_patient_id', 'id')
->orderBy('end_date', 'desc');
}
// Пересечение с отчетным периодом
@@ -40,24 +50,6 @@ class MigrationPatient extends MaterializedViewModel
return $query->whereIn('stationar_branch_id', $branchIds);
}
// Добавляет вычисляемый столбец `category` (только для отображения)
public function scopeWithCategory($query, string $from, string $to)
{
$sql = "CASE
WHEN ingoing_date BETWEEN ? AND ? THEN 'admitted'
WHEN out_date BETWEEN ? AND ? THEN
CASE
WHEN death_date IS NOT NULL AND death_date BETWEEN ? AND ? THEN 'deceased'
WHEN stat_cure_result_id IN (3,4,7) THEN 'transferred'
ELSE 'discharged'
END
WHEN ingoing_date < ? AND (out_date IS NULL OR out_date > ?) THEN 'current'
ELSE 'historical'
END as category";
return $query->selectRaw($sql, [$from, $to, $from, $to, $from, $to, $to, $to]);
}
// Быстрые фильтры по статусам (используют индексы MV, а не computed column)
public function scopeAdmitted($query, string $from, string $to)
{
@@ -89,7 +81,29 @@ class MigrationPatient extends MaterializedViewModel
public function scopeCurrent($query, DateRange $dateRange)
{
return $query->where('is_actually_current', true);
return $query->whereNull('out_date')
->whereNotNull('medical_history_id')
->where('ingoing_date', '<', $dateRange->startSql())
->wherehas('medicalHistory', function ($query) use ($dateRange) {
$query->whereNull('extract_date');
});
}
public function scopeCurrentOrAdmitted($query, DateRange $dateRange)
{
return $query->where(function ($q) use ($dateRange) {
// Вариант А: Пациент уже лежит (текущий)
$q->whereNull('out_date')
->whereNotNull('medical_history_id')
->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())
->where('ingoing_date', '>', $dateRange->startSql());
});
}
public function scopeCurrentMigration($query, $historyId, $departmentId)
@@ -99,4 +113,23 @@ class MigrationPatient extends MaterializedViewModel
->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);
}
}

42
app/Models/ReportDuty.php Normal file
View File

@@ -0,0 +1,42 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ReportDuty extends Model
{
protected $fillable = [
'report_date',
'sent_at',
'period_type',
'period_start',
'period_end',
'status_id',
'rf_lpudoctor_id',
'rf_department_id',
'rf_user_id',
];
protected $casts = [
'report_date' => 'date:Y-m-d',
'sent_at' => 'datetime:Y-m-d H:i:s',
'period_start' => 'datetime:Y-m-d H:i:s',
'period_end' => 'datetime:Y-m-d H:i:s',
];
public function department()
{
return $this->belongsTo(Department::class, 'rf_department_id', 'department_id');
}
public function patients()
{
return $this->hasMany(ReportNursePatient::class, 'report_nurse_id');
}
public function status()
{
return $this->belongsTo(ReportStatus::class);
}
}

View File

@@ -0,0 +1,108 @@
<?php
namespace App\Models;
use App\Services\DateRange;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class ReportDutyMigrationPatient extends Model
{
protected $fillable = [
'medical_history_id',
'ingoing_date',
'out_date',
'diagnosis_id',
'diagnosis_code',
'diagnosis_name',
'interrupted_event_id',
'stationar_branch_id',
'department_id',
'visit_result_id',
'stat_cure_result_id',
'user_id',
'mis_user_id',
'comment',
];
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(ReportNursePatient::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())
->whereHas('medicalHistory', function ($query) use ($dateRange) {
$query->whereNull('extract_date');
});
}
public function scopeCurrentMigration($query, $historyId, $departmentId)
{
return $query->where('medical_history_id', $historyId)
->department($departmentId)
->orderBy('ingoing_date', 'desc')
->limit(1)->first();
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ReportDutyPatient extends Model
{
protected $fillable = [
'report_duty_id',
'source_type',
'original_id',
'medical_card_number',
'full_name',
'birth_date',
'recipient_date',
'extract_date',
'death_date',
'male',
'urgency_id',
'hospital_result_id',
'visit_result_id',
'comment',
'user_id'
];
protected $casts = [
'birth_date' => 'date:Y-m-d',
'recipient_date' => 'datetime:Y-m-d H:i:s',
'extract_date' => 'datetime:Y-m-d H:i:s',
'death_date' => 'datetime:Y-m-d H:i:s',
'male' => 'boolean',
];
public function migrations(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(ReportDutyMigrationPatient::class, 'medical_history_id', 'id');
}
public function operations(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->hasMany(SurgicalOperation::class, 'medical_history_id', 'id');
}
public function latestMigration()
{
return $this->hasOne(ReportDutyMigrationPatient::class, 'medical_history_id', 'id')
->latest('ingoing_date');
}
public function operationsInDepartment($query, $departmentId)
{
return $this->operations()->where('department_id', $departmentId);
}
// Скоупы
public function scopeUrgency($query, $typeId) // 1 = Экстренно, 2 = Планово
{
return $query->where('urgency_id', $typeId);
}
}