* оптимизация обновления при редактировании спец контингента * добавил поддержку заключительных диагнозов * изменил определение законченной операции * добавил поддержку исхода операции * добавил определение отмены для операции через назначение * работа над диапазонами календарей, подсчет статистики * добавил статусы отчетов и подкорректировал привязку спец контингента к отчету * добавил новые сервисы для будущего кеширования * частичное разделение логики подсчета пациентов
443 lines
16 KiB
PHP
443 lines
16 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
|
||
use App\Models\MisMedicalHistory;
|
||
use App\Models\MisMigrationPatient;
|
||
use App\Models\MisReanimation;
|
||
use App\Models\MisSurgicalOperation;
|
||
use App\Models\ObservationPatient;
|
||
|
||
class PatientService
|
||
{
|
||
public function __construct(
|
||
protected OutcomePatientService $outcomePatientService,
|
||
protected RecipientPatientService $recipientPatientService,
|
||
protected CurrentPatientService $currentPatientService
|
||
)
|
||
{ }
|
||
|
||
/**
|
||
* Получить плановых или экстренных пациентов
|
||
*/
|
||
public function getPlanOrEmergencyPatients(
|
||
?string $type,
|
||
bool $isHeadOrAdmin,
|
||
int $branchId,
|
||
DateRange $dateRange,
|
||
bool $countOnly = false,
|
||
bool $onlyIds = false,
|
||
bool $includeCurrent = false,
|
||
bool $fillableAuto = false
|
||
) {
|
||
$medicalHistoryIds = $this->recipientPatientService->resolvePlanOrEmergencyMedicalHistoryIds(
|
||
$type,
|
||
$isHeadOrAdmin,
|
||
$branchId,
|
||
$dateRange,
|
||
$includeCurrent,
|
||
$fillableAuto
|
||
);
|
||
|
||
if (empty($medicalHistoryIds)) {
|
||
return $countOnly ? 0 : collect();
|
||
}
|
||
|
||
if ($countOnly) {
|
||
return count($medicalHistoryIds);
|
||
}
|
||
|
||
if ($onlyIds) {
|
||
return collect($medicalHistoryIds);
|
||
}
|
||
|
||
$recipientIds = $this->recipientPatientService->getRecipientMedicalHistoryIds(
|
||
$type,
|
||
$isHeadOrAdmin,
|
||
$branchId,
|
||
$dateRange
|
||
);
|
||
|
||
$res = $this->buildPatientCardsQuery($medicalHistoryIds, $branchId);
|
||
|
||
return $res->get()
|
||
->map(function ($patient) use ($recipientIds) {
|
||
$patient->is_recipient_today = in_array($patient->MedicalHistoryID, $recipientIds, true);
|
||
return $patient;
|
||
});
|
||
|
||
}
|
||
|
||
/**
|
||
* Получить всех пациентов в отделении (поступившие сегодня + уже лечащиеся)
|
||
*/
|
||
public function getAllPatientsInDepartment(
|
||
bool $isHeadOrAdmin,
|
||
int $branchId,
|
||
DateRange $dateRange,
|
||
bool $countOnly = false,
|
||
bool $onlyIds = false,
|
||
bool $fillableAuto = false
|
||
) {
|
||
$recipientIds = $this->recipientPatientService->buildRecipientQuery(null, $isHeadOrAdmin, $branchId, $dateRange, $fillableAuto)
|
||
->pluck('rf_MedicalHistoryID')
|
||
->toArray();
|
||
|
||
if ($fillableAuto) {
|
||
$currentIds = $this->currentPatientService->getHistoricalCurrentMedicalHistoryIds(null, $branchId, $dateRange);
|
||
} else {
|
||
$currentIds = MisMigrationPatient::currentlyInTreatment($branchId)
|
||
->pluck('rf_MedicalHistoryID')
|
||
->toArray();
|
||
}
|
||
|
||
$allIds = array_unique(array_merge($recipientIds, $currentIds));
|
||
|
||
if (empty($allIds)) {
|
||
if ($countOnly) return 0;
|
||
return collect();
|
||
}
|
||
|
||
if ($countOnly) {
|
||
return count($allIds);
|
||
}
|
||
|
||
if ($onlyIds) {
|
||
return collect($allIds);
|
||
}
|
||
|
||
$res = MisMedicalHistory::whereIn('MedicalHistoryID', $allIds)
|
||
->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([
|
||
'stt_migrationpatient.MigrationPatientID',
|
||
'stt_migrationpatient.rf_MedicalHistoryID',
|
||
'stt_migrationpatient.DateOut',
|
||
'stt_migrationpatient.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');
|
||
|
||
return $res->get()
|
||
->map(function ($patient) use ($recipientIds) {
|
||
$patient->is_recipient_today = in_array($patient->MedicalHistoryID, $recipientIds);
|
||
return $patient;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Получить пациентов под наблюдением
|
||
*/
|
||
public function getObservationPatients(int $departmentId, bool $onlyIds = false)
|
||
{
|
||
$query = MisMedicalHistory::whereHas('observationPatient', function ($q) use ($departmentId) {
|
||
$q->where('rf_department_id', $departmentId);
|
||
});
|
||
|
||
if (!$onlyIds) {
|
||
$query->with(['observationPatient' => function ($query) use ($departmentId) {
|
||
$query->where('rf_department_id', $departmentId)
|
||
->select(['rf_medicalhistory_id', 'observation_patient_id', 'comment']);
|
||
}])
|
||
->orderBy('DateRecipient', 'DESC');
|
||
}
|
||
|
||
if ($onlyIds) $patients = $query->pluck('MedicalHistoryID');
|
||
else {
|
||
$query->with([
|
||
'outcomeMigration.mainDiagnosis.mkb',
|
||
]);
|
||
$patients = $query->get();
|
||
}
|
||
|
||
return $patients->map(function ($patient) {
|
||
$patient->comment = $patient->observationPatient
|
||
->pluck('comment')
|
||
->filter()
|
||
->implode('; ');
|
||
return $patient;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Получить выбывших пациентов
|
||
*/
|
||
public function getOutcomePatients(
|
||
int $branchId,
|
||
DateRange $dateRange,
|
||
string $outcomeType = 'all',
|
||
bool $onlyIds = false
|
||
) {
|
||
return $this->outcomePatientService->getOutcomePatients($branchId, $dateRange, $outcomeType, $onlyIds);
|
||
}
|
||
|
||
/**
|
||
* Получить пациентов, находящихся в реанимации на конец периода
|
||
*/
|
||
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);
|
||
}
|
||
|
||
return MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
|
||
->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([
|
||
'stt_migrationpatient.MigrationPatientID',
|
||
'stt_migrationpatient.rf_MedicalHistoryID',
|
||
'stt_migrationpatient.DateOut',
|
||
'stt_migrationpatient.rf_DiagnosID',
|
||
])->with(['mainDiagnosis' => function ($diagnosisQuery) {
|
||
$diagnosisQuery->select([
|
||
'DiagnosID',
|
||
'rf_MKBID',
|
||
])->with(['mkb' => function ($mkbQuery) {
|
||
$mkbQuery->select([
|
||
'MKBID',
|
||
'DS',
|
||
'NAME',
|
||
]);
|
||
}]);
|
||
}]);
|
||
},
|
||
])
|
||
->orderBy('DateRecipient', 'DESC')
|
||
->get();
|
||
}
|
||
|
||
/**
|
||
* Получить пациентов с операциями
|
||
*/
|
||
public function getSurgicalPatients(
|
||
string $type,
|
||
int $branchId,
|
||
DateRange $dateRange,
|
||
bool $countOnly = false
|
||
) {
|
||
$query = MisSurgicalOperation::where('rf_StationarBranchID', $branchId)
|
||
->completed()
|
||
->where('Date', '>=', $dateRange->startSql())
|
||
->where('Date', '<=', $dateRange->endSql());
|
||
|
||
if ($type === 'plan') {
|
||
$query->where('rf_TypeSurgOperationInTimeID', 6);
|
||
} else {
|
||
$query->whereIn('rf_TypeSurgOperationInTimeID', [4, 5]);
|
||
}
|
||
|
||
if ($countOnly) {
|
||
return $query->count();
|
||
}
|
||
|
||
return $query->get();
|
||
}
|
||
|
||
/**
|
||
* Получить количество пациентов по типу с учетом уже находящихся в отделении
|
||
*/
|
||
public function getPatientsCountWithCurrent(
|
||
?string $type,
|
||
bool $isHeadOrAdmin,
|
||
int $branchId,
|
||
DateRange $dateRange
|
||
): int {
|
||
return $this->getPlanOrEmergencyPatients(
|
||
$type,
|
||
$isHeadOrAdmin,
|
||
$branchId,
|
||
$dateRange,
|
||
true,
|
||
false,
|
||
true
|
||
);
|
||
}
|
||
|
||
private function buildPatientCardsQuery(array $medicalHistoryIds, int $branchId)
|
||
{
|
||
return MisMedicalHistory::query()
|
||
->whereIn('MedicalHistoryID', $medicalHistoryIds)
|
||
->select([
|
||
'MedicalHistoryID',
|
||
'FAMILY',
|
||
'Name',
|
||
'OT',
|
||
'BD',
|
||
'DateRecipient',
|
||
'DateExtract',
|
||
'DateDeath',
|
||
'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([
|
||
'stt_migrationpatient.MigrationPatientID',
|
||
'stt_migrationpatient.rf_MedicalHistoryID',
|
||
'stt_migrationpatient.DateOut',
|
||
'stt_migrationpatient.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');
|
||
}
|
||
}
|