219 lines
8.6 KiB
PHP
219 lines
8.6 KiB
PHP
<?php
|
|
|
|
namespace App\Infrastructure\Reports\Sources;
|
|
|
|
use App\Data\UnifiedPatientData;
|
|
use App\Models\DepartmentPatientOperation;
|
|
use App\Models\MedicalHistory;
|
|
use App\Models\MedicalHistorySnapshot;
|
|
use Illuminate\Support\Collection;
|
|
|
|
class SnapshotPatientSource
|
|
{
|
|
public function getStatisticsFromSnapshots(array $reportIds): array
|
|
{
|
|
return [
|
|
'plan' => $this->getCountFromSnapshots('plan', $reportIds),
|
|
'emergency' => $this->getCountFromSnapshots('emergency', $reportIds),
|
|
'outcome' => $this->getCountFromSnapshots('outcome', $reportIds),
|
|
'deceased' => $this->getCountFromSnapshots('deceased', $reportIds),
|
|
'discharged' => $this->getCountFromSnapshots('discharged', $reportIds),
|
|
'transferred' => $this->getCountFromSnapshots('transferred', $reportIds),
|
|
'recipient' => $this->getCountFromSnapshots('recipient', $reportIds),
|
|
];
|
|
}
|
|
|
|
public function getPatientsFromSnapshots(
|
|
string $type,
|
|
array $reportIds,
|
|
bool $onlyIds = false,
|
|
bool $markRecipients = false,
|
|
?array $recipientReportIds = null
|
|
): Collection {
|
|
$snapshots = MedicalHistorySnapshot::query()
|
|
->whereIn('rf_report_id', $reportIds)
|
|
->where('patient_type', $type)
|
|
->get()
|
|
->unique(fn (MedicalHistorySnapshot $snapshot) => $this->snapshotIdentity($snapshot))
|
|
->values();
|
|
|
|
if ($snapshots->isEmpty()) {
|
|
return collect();
|
|
}
|
|
|
|
$recipientIds = [];
|
|
if ($markRecipients) {
|
|
$recipientReportIds ??= $reportIds;
|
|
$recipientIds = MedicalHistorySnapshot::query()
|
|
->whereIn('rf_report_id', $recipientReportIds)
|
|
->where('patient_type', 'recipient')
|
|
->get()
|
|
->map(fn (MedicalHistorySnapshot $snapshot) => UnifiedPatientData::fromSnapshot($snapshot)->id)
|
|
->unique()
|
|
->values()
|
|
->all();
|
|
}
|
|
|
|
$operationsByHistoryId = $this->getOperationsByMedicalHistoryId($snapshots);
|
|
$operationsByDepartmentPatientId = $this->getOperationsByDepartmentPatientId($snapshots);
|
|
|
|
$patients = $snapshots->map(function (MedicalHistorySnapshot $snapshot) use ($recipientIds, $operationsByHistoryId, $operationsByDepartmentPatientId) {
|
|
$patientId = $snapshot->rf_department_patient_id
|
|
? "manual:{$snapshot->rf_department_patient_id}"
|
|
: ($snapshot->patient_uid ?: "mis:{$snapshot->rf_medicalhistory_id}");
|
|
|
|
$misOperations = $snapshot->rf_medicalhistory_id
|
|
? ($operationsByHistoryId[$snapshot->rf_medicalhistory_id] ?? [])
|
|
: [];
|
|
$manualOperations = $snapshot->rf_department_patient_id
|
|
? ($operationsByDepartmentPatientId[$snapshot->rf_department_patient_id] ?? [])
|
|
: [];
|
|
$operations = collect($misOperations)
|
|
->merge($manualOperations)
|
|
->unique(fn (array $operation) => ($operation['code'] ?? '').'|'.($operation['name'] ?? ''))
|
|
->values()
|
|
->all();
|
|
|
|
return UnifiedPatientData::fromSnapshot(
|
|
$snapshot,
|
|
in_array($patientId, $recipientIds, true),
|
|
$operations
|
|
);
|
|
})->sortByDesc(fn (UnifiedPatientData $patient) => $patient->admittedAt ?? '')->values();
|
|
|
|
return $onlyIds ? $patients->pluck('id') : $patients;
|
|
}
|
|
|
|
public function getPatientsFromOneDayCurrentSnapshots(
|
|
string $type,
|
|
array $reportIds,
|
|
bool $onlyIds = false,
|
|
?array $recipientReportIds = null
|
|
): Collection {
|
|
$snapshots = MedicalHistorySnapshot::query()
|
|
->whereIn('rf_report_id', $reportIds)
|
|
->where('patient_type', 'current')
|
|
->get();
|
|
|
|
if ($snapshots->isEmpty()) {
|
|
return $this->getPatientsFromSnapshots(
|
|
$type,
|
|
$reportIds,
|
|
$onlyIds,
|
|
true,
|
|
$recipientReportIds
|
|
);
|
|
}
|
|
|
|
$recipientReportIds ??= $reportIds;
|
|
$recipientIds = MedicalHistorySnapshot::query()
|
|
->whereIn('rf_report_id', $recipientReportIds)
|
|
->where('patient_type', 'recipient')
|
|
->get()
|
|
->map(fn (MedicalHistorySnapshot $snapshot) => UnifiedPatientData::fromSnapshot($snapshot)->id)
|
|
->unique()
|
|
->values()
|
|
->all();
|
|
|
|
$operationsByHistoryId = $this->getOperationsByMedicalHistoryId($snapshots);
|
|
$operationsByDepartmentPatientId = $this->getOperationsByDepartmentPatientId($snapshots);
|
|
|
|
$patients = $snapshots
|
|
->filter(fn (MedicalHistorySnapshot $snapshot) => $snapshot->patient_kind === $type)
|
|
->unique(fn (MedicalHistorySnapshot $snapshot) => $this->snapshotIdentity($snapshot))
|
|
->map(function (MedicalHistorySnapshot $snapshot) use ($recipientIds, $operationsByHistoryId, $operationsByDepartmentPatientId) {
|
|
$misOperations = $snapshot->rf_medicalhistory_id
|
|
? ($operationsByHistoryId[$snapshot->rf_medicalhistory_id] ?? [])
|
|
: [];
|
|
$manualOperations = $snapshot->rf_department_patient_id
|
|
? ($operationsByDepartmentPatientId[$snapshot->rf_department_patient_id] ?? [])
|
|
: [];
|
|
$operations = collect($misOperations)
|
|
->merge($manualOperations)
|
|
->unique(fn (array $operation) => ($operation['code'] ?? '').'|'.($operation['name'] ?? ''))
|
|
->values()
|
|
->all();
|
|
|
|
$patient = UnifiedPatientData::fromSnapshot(
|
|
$snapshot,
|
|
false,
|
|
$operations
|
|
);
|
|
$patient->isRecipientToday = in_array($patient->id, $recipientIds, true);
|
|
|
|
return $patient;
|
|
})
|
|
->sortByDesc(fn (UnifiedPatientData $patient) => $patient->admittedAt ?? '')
|
|
->values();
|
|
|
|
return $onlyIds ? $patients->pluck('id') : $patients;
|
|
}
|
|
|
|
private function getCountFromSnapshots(string $type, array $reportIds): int
|
|
{
|
|
$query = MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds);
|
|
|
|
if ($type === 'outcome') {
|
|
$query->whereIn('patient_type', ['discharged', 'deceased']);
|
|
} else {
|
|
$query->where('patient_type', $type);
|
|
}
|
|
|
|
return $query->get()
|
|
->map(fn (MedicalHistorySnapshot $snapshot) => $this->snapshotIdentity($snapshot))
|
|
->unique()
|
|
->count();
|
|
}
|
|
|
|
private function snapshotIdentity(MedicalHistorySnapshot $snapshot): string
|
|
{
|
|
return $snapshot->patient_uid
|
|
?: ($snapshot->rf_medicalhistory_id
|
|
? "mis:{$snapshot->rf_medicalhistory_id}"
|
|
: "snapshot:{$snapshot->medical_history_snapshot_id}");
|
|
}
|
|
|
|
private function getOperationsByMedicalHistoryId(Collection $snapshots): array
|
|
{
|
|
$historyIds = $snapshots->pluck('rf_medicalhistory_id')->filter()->unique()->values();
|
|
|
|
if ($historyIds->isEmpty()) {
|
|
return [];
|
|
}
|
|
|
|
return MedicalHistory::query()
|
|
->whereIn('id', $historyIds)
|
|
->with(['operations'])
|
|
->get()
|
|
->mapWithKeys(function (MedicalHistory $history) {
|
|
return [
|
|
$history->original_id => $history->operations->map(fn ($operation) => [
|
|
'code' => $operation->service_medical_code ?? null,
|
|
'name' => $operation->service_medical_name ?? null,
|
|
])->values()->all(),
|
|
];
|
|
})
|
|
->all();
|
|
}
|
|
|
|
private function getOperationsByDepartmentPatientId(Collection $snapshots): array
|
|
{
|
|
$departmentPatientIds = $snapshots->pluck('rf_department_patient_id')->filter()->unique()->values();
|
|
|
|
if ($departmentPatientIds->isEmpty()) {
|
|
return [];
|
|
}
|
|
|
|
return DepartmentPatientOperation::query()
|
|
->whereIn('rf_department_patient_id', $departmentPatientIds)
|
|
->with('serviceMedical')
|
|
->get()
|
|
->groupBy('rf_department_patient_id')
|
|
->map(fn (Collection $operations) => $operations->map(fn (DepartmentPatientOperation $operation) => [
|
|
'code' => $operation->serviceMedical?->ServiceMedicalCode ?? $operation->service_code,
|
|
'name' => $operation->serviceMedical?->ServiceMedicalName ?? $operation->service_name,
|
|
])->values()->all())
|
|
->all();
|
|
}
|
|
}
|