modified: .gitignore

This commit is contained in:
brusnitsyn
2026-04-21 10:08:14 +09:00
parent 0e8b6f61b4
commit 2041ab54ea
74 changed files with 7533 additions and 1544 deletions

View File

@@ -2,12 +2,13 @@
namespace App\Services;
use App\Models\LifeMisMigrationPatient;
use App\Models\MisMedicalHistory;
use App\Models\MisMigrationPatient;
use App\Models\MisReanimation;
use App\Models\MisSurgicalOperation;
use App\Models\ObservationPatient;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
class PatientService
{
@@ -34,10 +35,7 @@ class PatientService
// Если нужно добавить уже находящихся в отделении
if ($includeCurrent) {
if ($fillableAuto) {
$currentIds = LifeMisMigrationPatient::currentlyInTreatment($branchId, $dateRange)
->distinct()
->pluck('rf_MedicalHistoryID')
->toArray();
$currentIds = $this->getHistoricalCurrentMedicalHistoryIds($branchId, $dateRange);
} else {
$currentIds = MisMigrationPatient::currentlyInTreatment($branchId)
->pluck('rf_MedicalHistoryID')
@@ -57,19 +55,75 @@ class PatientService
// Получаем истории
$query = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
->select([
'MedicalHistoryID',
'FAMILY',
'Name',
'OT',
'BD',
'DateRecipient',
'DateExtract',
'rf_EmerSignID',
'rf_kl_VisitResultID',
])
->with([
'surgicalOperations' => function ($q) use ($dateRange) {
// $q->whereBetween('Date', [$dateRange->startSql(), $dateRange->endSql()]);
$q->where('Date', '>=', $dateRange->startSql())
->where('Date', '<=', $dateRange->endSql());
'surgicalOperations' => function ($q) {
$q->select([
'SurgicalOperationID',
'rf_MedicalHistoryID',
'rf_kl_ServiceMedicalID',
'Date',
])->with(['serviceMedical' => function ($serviceQuery) {
$serviceQuery->select([
'ServiceMedicalID',
'ServiceMedicalCode',
'ServiceMedicalName',
]);
}]);
},
'outcomeMigration' => function ($q) {
$q->select([
'MigrationPatientID',
'rf_MedicalHistoryID',
'DateOut',
'rf_DiagnosID',
])->with(['mainDiagnosis' => function ($diagnosisQuery) {
$diagnosisQuery->select([
'DiagnosID',
'rf_MKBID',
])->with(['mkb' => function ($mkbQuery) {
$mkbQuery->select([
'MKBID',
'DS',
'NAME',
]);
}]);
}]);
},
'migrations' => function ($q) use ($branchId) {
$q->where('rf_StationarBranchID', $branchId)
->take(1) // берем только одну последнюю
->with(['mainDiagnosis' => function ($q) {
$q->with('mkb');
}]);
}
->select([
'MigrationPatientID',
'rf_MedicalHistoryID',
'rf_DiagnosID',
'DateIngoing',
'rf_StationarBranchID',
])
->orderByDesc('DateIngoing')
->with(['mainDiagnosis' => function ($diagnosisQuery) {
$diagnosisQuery->select([
'DiagnosID',
'rf_MKBID',
'rf_MigrationPatientID',
])->with(['mkb' => function ($mkbQuery) {
$mkbQuery->select([
'MKBID',
'DS',
'NAME',
]);
}]);
}]);
},
])
->orderBy('DateRecipient', 'DESC');
@@ -88,7 +142,7 @@ class PatientService
return $query->pluck('MedicalHistoryID');
}
return $query->get()->map(function ($patient) use ($recipientIds, $branchId) {
return $query->get()->map(function ($patient) use ($recipientIds) {
// Добавляем флаг "поступил сегодня"
$patient->is_recipient_today = in_array($patient->MedicalHistoryID, $recipientIds);
return $patient;
@@ -103,17 +157,22 @@ class PatientService
int $branchId,
DateRange $dateRange,
bool $countOnly = false,
bool $onlyIds = false
bool $onlyIds = false,
bool $fillableAuto = false
) {
// Поступившие сегодня
$recipientIds = $this->buildRecipientQuery(null, $isHeadOrAdmin, $branchId, $dateRange)
$recipientIds = $this->buildRecipientQuery(null, $isHeadOrAdmin, $branchId, $dateRange, $fillableAuto)
->pluck('rf_MedicalHistoryID')
->toArray();
// Уже находящиеся на лечении
$currentIds = MisMigrationPatient::currentlyInTreatment($branchId)
->pluck('rf_MedicalHistoryID')
->toArray();
if ($fillableAuto) {
$currentIds = $this->getHistoricalCurrentMedicalHistoryIds($branchId, $dateRange);
} else {
$currentIds = MisMigrationPatient::currentlyInTreatment($branchId)
->pluck('rf_MedicalHistoryID')
->toArray();
}
// Объединяем и убираем дубли
$allIds = array_unique(array_merge($recipientIds, $currentIds));
@@ -132,11 +191,76 @@ class PatientService
}
return MisMedicalHistory::whereIn('MedicalHistoryID', $allIds)
->with(['surgicalOperations' => function ($q) use ($dateRange) {
// $q->whereBetween('Date', [$dateRange->startSql(), $dateRange->endSql()]);
$q->where('Date', '>=', $dateRange->startSql())
->where('Date', '<=', $dateRange->endSql());
}])
->select([
'MedicalHistoryID',
'FAMILY',
'Name',
'OT',
'BD',
'DateRecipient',
'DateExtract',
'rf_EmerSignID',
'rf_kl_VisitResultID',
])
->with([
'surgicalOperations' => function ($q) {
$q->select([
'SurgicalOperationID',
'rf_MedicalHistoryID',
'rf_kl_ServiceMedicalID',
'Date',
])->with(['serviceMedical' => function ($serviceQuery) {
$serviceQuery->select([
'ServiceMedicalID',
'ServiceMedicalCode',
'ServiceMedicalName',
]);
}]);
},
'outcomeMigration' => function ($q) {
$q->select([
'MigrationPatientID',
'rf_MedicalHistoryID',
'DateOut',
'rf_DiagnosID',
])->with(['mainDiagnosis' => function ($diagnosisQuery) {
$diagnosisQuery->select([
'DiagnosID',
'rf_MKBID',
])->with(['mkb' => function ($mkbQuery) {
$mkbQuery->select([
'MKBID',
'DS',
'NAME',
]);
}]);
}]);
},
'migrations' => function ($q) use ($branchId) {
$q->where('rf_StationarBranchID', $branchId)
->select([
'MigrationPatientID',
'rf_MedicalHistoryID',
'rf_DiagnosID',
'DateIngoing',
'rf_StationarBranchID',
])
->orderByDesc('DateIngoing')
->with(['mainDiagnosis' => function ($diagnosisQuery) {
$diagnosisQuery->select([
'DiagnosID',
'rf_MKBID',
'rf_MigrationPatientID',
])->with(['mkb' => function ($mkbQuery) {
$mkbQuery->select([
'MKBID',
'DS',
'NAME',
]);
}]);
}]);
},
])
->orderBy('DateRecipient', 'DESC')
->get()
->map(function ($patient) use ($recipientIds) {
@@ -167,7 +291,6 @@ class PatientService
// Загрузка отношений, необходимых для FormattedPatientResource
$query->with([
'outcomeMigration.mainDiagnosis.mkb', // mkb через диагноз
'surgicalOperations.serviceMedical', // операции с услугами
]);
$patients = $query->get();
}
@@ -190,34 +313,156 @@ class PatientService
string $outcomeType = 'all',
bool $onlyIds = false
) {
$methodMap = [
'discharged' => 'outcomeDischarged',
'transferred' => 'outcomeTransferred',
'without-transferred' => 'outcomeWithoutTransferred',
'deceased' => 'deceasedOutcome',
'all' => 'outcomePatients',
];
$query = MisMedicalHistory::query()
->where('MedicalHistoryID', '<>', 0)
->whereHas('migrations', function ($migrationQuery) use ($branchId, $outcomeType) {
$migrationQuery->where('rf_StationarBranchID', $branchId);
$method = $methodMap[$outcomeType] ?? 'outcomePatients';
if ($outcomeType === 'deceased') {
$migrationQuery->whereIn('rf_kl_VisitResultID', [5, 6, 15, 16]);
} elseif ($outcomeType === 'transferred') {
$migrationQuery->whereIn('rf_kl_VisitResultID', [4, 14]);
} elseif ($outcomeType === 'discharged') {
$migrationQuery->whereIn('rf_kl_VisitResultID', [1, 11, 2, 12, 7, 18, 48]);
} elseif ($outcomeType === 'without-transferred') {
$migrationQuery->whereNotIn('rf_kl_VisitResultID', [4, 14])
->where('rf_kl_VisitResultID', '<>', 0);
}
});
$medicalHistoryIds = MisMigrationPatient::{$method}($branchId, $dateRange)
->pluck('rf_MedicalHistoryID')
->unique()
if ($dateRange->isOneDay) {
$query->where('DateExtract', '>', $dateRange->startSql())
->where('DateExtract', '<=', $dateRange->endSql());
} else {
$startAt = $dateRange->startSql();
$endDate = $dateRange->end()->toDateString();
$query->where('DateExtract', '>', $startAt)
->whereDate('DateExtract', '<=', $endDate);
}
if ($onlyIds) {
return $query->pluck('MedicalHistoryID');
}
return $query
->select([
'MedicalHistoryID',
'FAMILY',
'Name',
'OT',
'BD',
'DateRecipient',
'DateExtract',
'rf_EmerSignID',
'rf_kl_VisitResultID',
])
->with([
'outcomeMigration' => function ($q) {
$q->select([
'MigrationPatientID',
'rf_MedicalHistoryID',
'DateOut',
'rf_DiagnosID',
])->with(['mainDiagnosis' => function ($diagnosisQuery) {
$diagnosisQuery->select([
'DiagnosID',
'rf_MKBID',
])->with(['mkb' => function ($mkbQuery) {
$mkbQuery->select([
'MKBID',
'DS',
'NAME',
]);
}]);
}]);
},
])
->orderBy('DateRecipient', 'DESC')
->get()
->map(fn ($patient) => $this->addOutcomeInfo($patient));
}
/**
* Получить пациентов, находящихся в реанимации на конец периода
*/
public function getReanimationPatients(
int $branchId,
DateRange $dateRange,
bool $onlyIds = false
) {
$medicalHistoryIds = MisReanimation::query()
->join('stt_migrationpatient as mp', 'mp.MigrationPatientID', '=', 'stt_reanimation.rf_MigrationPatientID')
->where('stt_reanimation.rf_StationarBranchID', $branchId)
->where('mp.rf_StationarBranchID', $branchId)
->where('mp.rf_MedicalHistoryID', '<>', 0)
->where('stt_reanimation.DateIn', '<=', $dateRange->endSql())
->where(function ($query) use ($dateRange) {
$query->where('stt_reanimation.DateOut', '>=', $dateRange->endSql())
->orWhereNull('stt_reanimation.DateOut')
->orWhereDate('stt_reanimation.DateOut', '1900-01-01')
->orWhereDate('stt_reanimation.DateOut', '2222-01-01');
})
->distinct()
->pluck('mp.rf_MedicalHistoryID')
->toArray();
if (empty($medicalHistoryIds)) {
return collect();
}
if ($onlyIds) return collect($medicalHistoryIds);
if ($onlyIds) {
return collect($medicalHistoryIds);
}
return MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
->with(['surgicalOperations'])
->select([
'MedicalHistoryID',
'FAMILY',
'Name',
'OT',
'BD',
'DateRecipient',
'DateExtract',
'rf_EmerSignID',
'rf_kl_VisitResultID',
])
->with([
'surgicalOperations' => function ($q) {
$q->select([
'SurgicalOperationID',
'rf_MedicalHistoryID',
'rf_kl_ServiceMedicalID',
'Date',
])->with(['serviceMedical' => function ($serviceQuery) {
$serviceQuery->select([
'ServiceMedicalID',
'ServiceMedicalCode',
'ServiceMedicalName',
]);
}]);
},
'outcomeMigration' => function ($q) {
$q->select([
'MigrationPatientID',
'rf_MedicalHistoryID',
'DateOut',
'rf_DiagnosID',
])->with(['mainDiagnosis' => function ($diagnosisQuery) {
$diagnosisQuery->select([
'DiagnosID',
'rf_MKBID',
])->with(['mkb' => function ($mkbQuery) {
$mkbQuery->select([
'MKBID',
'DS',
'NAME',
]);
}]);
}]);
},
])
->orderBy('DateRecipient', 'DESC')
->get()
->map(function ($patient) {
return $this->addOutcomeInfo($patient);
});
->get();
}
/**
@@ -230,6 +475,7 @@ class PatientService
bool $countOnly = false
) {
$query = MisSurgicalOperation::where('rf_StationarBranchID', $branchId)
->completed()
->where('Date', '>=', $dateRange->startSql())
->where('Date', '<=', $dateRange->endSql());
// ->whereBetween('Date', [$dateRange->startSql(), $dateRange->endSql()]);
@@ -325,36 +571,64 @@ class PatientService
DateRange $dateRange,
bool $fillableAuto = false
) {
// Разная логика для заведующего и врача
if ($isHeadOrAdmin) {
// Заведующий: все поступившие за период
if ($fillableAuto) {
$query = LifeMisMigrationPatient::whereInDepartment($branchId)
->where('DateIngoing', '>=', $dateRange->startSql())
->where('DateIngoing', '<=', $dateRange->endSql());
// ->whereBetween('DateIngoing', [$dateRange->startSql(), $dateRange->endSql()]);
} else {
$query = MisMigrationPatient::whereInDepartment($branchId)
->where('DateIngoing', '>=', $dateRange->startSql())
->where('DateIngoing', '<=', $dateRange->endSql());
// ->whereBetween('DateIngoing', [$dateRange->startSql(), $dateRange->endSql()]);
}
} else {
// Врач: только поступившие за сутки
if ($fillableAuto) {
$query = LifeMisMigrationPatient::whereInDepartment($branchId)
->where('DateIngoing', '>=', $dateRange->startSql())
->where('DateIngoing', '<=', $dateRange->endSql());
// ->whereBetween('DateIngoing', [$dateRange->startSql(), $dateRange->endSql()]);
} else {
$query = MisMigrationPatient::whereInDepartment($branchId)
->where('DateIngoing', '>=', $dateRange->startSql())
->where('DateIngoing', '<=', $dateRange->endSql());
// ->whereBetween('DateIngoing', [$dateRange->startSql(), $dateRange->endSql()]);
};
$startAt = $dateRange->start()->copy()->subDay()->format('Y-m-d H:i:s');
$endAt = $dateRange->end()->copy()->addDay()->format('Y-m-d H:i:s');
if ($dateRange->isOneDay) {
$startAt = $dateRange->startSql();
$endAt = $dateRange->endSql();
}
return $query;
$query = DB::table('stt_medicalhistory as mh')
->selectRaw('mh."MedicalHistoryID" as "rf_MedicalHistoryID"')
->where('mh.MedicalHistoryID', '<>', 0);
$query->whereExists(function ($subQuery) use ($branchId, $startAt, $endAt) {
$subQuery->select(DB::raw(1))
->from('stt_migrationpatient as mp')
->whereColumn('mp.rf_MedicalHistoryID', 'mh.MedicalHistoryID')
->where('mp.rf_StationarBranchID', $branchId)
->where('mp.DateIngoing', '>', $startAt)
->where('mp.DateIngoing', '<=', $endAt);
});
if ($type === 'plan') {
$query->where('mh.rf_EmerSignID', 1);
} elseif ($type === 'emergency') {
$query->whereIn('mh.rf_EmerSignID', [2, 4]);
}
return $query->distinct();
}
private function getHistoricalCurrentMedicalHistoryIds(int $branchId, DateRange $dateRange): array
{
// Исторический срез по основной таблице миграций:
// для каждой истории болезни берём последнюю миграцию в отделении
// на момент конца периода и проверяем, что пациент числился в отделении.
$latestRows = DB::table('stt_migrationpatient')
->select('rf_MedicalHistoryID', DB::raw('MAX("MigrationPatientID") as max_migration_patient_id'))
->where('rf_StationarBranchID', $branchId)
->where('rf_MedicalHistoryID', '<>', 0)
->where('DateIngoing', '<=', $dateRange->endSql())
->groupBy('rf_MedicalHistoryID');
return DB::table('stt_migrationpatient as mp')
->joinSub($latestRows, 'latest', function ($join) {
$join->on('mp.rf_MedicalHistoryID', '=', 'latest.rf_MedicalHistoryID')
->on('mp.MigrationPatientID', '=', 'latest.max_migration_patient_id');
})
->join('stt_medicalhistory as mh', 'mh.MedicalHistoryID', '=', 'mp.rf_MedicalHistoryID')
->where('mp.rf_StationarBranchID', $branchId)
->where('mh.DateRecipient', '<=', $dateRange->endSql())
->where('mp.DateOut', '>=', $dateRange->endSql())
->where(function ($query) use ($dateRange) {
$query->where('mh.DateExtract', '>', $dateRange->endSql())
->orWhereDate('mh.DateExtract', '1900-01-01');
})
->distinct()
->pluck('mp.rf_MedicalHistoryID')
->toArray();
}
/**
@@ -386,26 +660,15 @@ class PatientService
int $branchId,
DateRange $dateRange
): int {
// Поступившие сегодня указанного типа
$recipientCount = $this->buildRecipientQuery($type, $isHeadOrAdmin, $branchId, $dateRange)
->count();
// Если нужны плановые/экстренные среди уже лечащихся
$currentCount = 0;
if ($type === 'plan' || $type === 'emergency') {
$currentIds = MisMigrationPatient::currentlyInTreatment($branchId)
->pluck('rf_MedicalHistoryID')
->toArray();
if (!empty($currentIds)) {
$currentCount = MisMedicalHistory::whereIn('MedicalHistoryID', $currentIds)
->when($type === 'plan', fn($q) => $q->plan())
->when($type === 'emergency', fn($q) => $q->emergency())
->count();
}
}
return $currentCount;
return $this->getPlanOrEmergencyPatients(
$type,
$isHeadOrAdmin,
$branchId,
$dateRange,
true,
false,
true
);
}
/**