Files
onboard/app/Infrastructure/Services/MisPatientSnapshotProvider.php
2026-07-31 17:19:03 +09:00

113 lines
5.3 KiB
PHP

<?php
namespace App\Infrastructure\Services;
use App\Domain\ReportDuty\Contracts\PatientSnapshotProviderInterface;
use App\Models\MedicalHistory;
use App\Services\Classification\PatientStatusClassifier;
use App\Services\DateRange;
use Illuminate\Support\Carbon;
use Illuminate\Support\LazyCollection;
/**
* Извлекает пациентов из МИС (Material View)
*/
class MisPatientSnapshotProvider implements PatientSnapshotProviderInterface
{
public function __construct(
protected PatientStatusClassifier $classifier
) {
}
public function getPatients(DateRange $dateRange, int $departmentId): LazyCollection
{
$startYear = Carbon::now()->startOfYear()->format('Y-m-d');
return MedicalHistory::query()
->whereHas('migrations', function ($q) use ($departmentId, $dateRange, $startYear) {
$q->where('department_id', $departmentId)
->where('ingoing_date', '<=', $dateRange->endSql())
->where(function ($sub) use ($dateRange, $startYear) {
$sub->whereNull('out_date')
->where('ingoing_date', '>', $startYear);
$sub->orWhere(function ($sub2) use ($dateRange, $startYear) {
$sub2->whereNotNull('out_date')
->where('out_date', '>', $dateRange->startSql())
->where('out_date', '>', $startYear);
});
});
})
->with([
'latestMigration' => function ($q) use ($departmentId) {
$q->where('department_id', $departmentId);
},
'latestMigration.operations',
'latestMigration.reanimations',
'migrations' => function ($q) use ($departmentId, $dateRange, $startYear) {
$q->where('department_id', $departmentId)
->where('ingoing_date', '<=', $dateRange->endSql())
->where(function ($sub) use ($dateRange, $startYear) {
$sub->whereNull('out_date')
->where('ingoing_date', '>', $startYear);
$sub->orWhere(function ($sub2) use ($dateRange, $startYear) {
$sub2->whereNotNull('out_date')
->where('out_date', '>', $dateRange->startSql())
->where('out_date', '>', $startYear);
});
});
},
'migrations.reanimations' => function ($q) use ($dateRange) {
$q->where(function ($sub) use ($dateRange) {
$sub->whereNull('out_date')
->orWhere('out_date', '>=', $dateRange->startSql());
});
},
'operations' => function ($q) use ($departmentId, $dateRange) {
$q->where('department_id', $departmentId)
->where('start_date', '>=', $dateRange->startSql())
->where('start_date', '<', $dateRange->endSql());
}
])
->lazy()
->map(function (MedicalHistory $h) use ($dateRange) {
$patientStatus = $this->classifier::classify($h, $dateRange);
$periodFlags = $this->classifier::classifyPeriodFlags($h, $dateRange);
$patientUrgency = null;
$patientReanimation = null;
if (!in_array($patientStatus, [
PatientStatusClassifier::STATUS_DECEASED,
PatientStatusClassifier::STATUS_DISCHARGED,
PatientStatusClassifier::STATUS_TRANSFERRED
])) {
$patientUrgency = $this->classifier::classifyUrgency($h->urgency_id);
$patientReanimation = $this->classifier::classifyReanimation($h->latestMigration?->reanimations, $dateRange);
}
return new PatientSnapshotData(
id: $h->id,
sourceType: 'mis',
medicalCardNumber: $h->medical_card_number,
fullName: $h->full_name,
birthDate: $h->birth_date,
recipientDate: $h->recipient_date,
extractDate: $h->extract_date,
deathDate: $h->death_date,
male: $h->male,
urgencyId: $h->urgency_id,
visitResultId: $h->visit_result_id,
hospitalResultId: $h->hospital_result_id,
comment: $h->comment,
profitTypeId: $h->profit_type_id,
migrations: $h->migrations->map(fn($m) => $m->toArray())->toArray(),
operations: $h->operations->toArray(),
patientStatus: $patientStatus,
patientUrgency: $patientUrgency,
periodFlags: $periodFlags,
inReanimation: $patientReanimation,
admittedToday: $this->classifier::classifyAdmitted($h->latestMigration?->ingoing_date, $dateRange),
inObservable: $this->classifier::classifyObservable($h->observable, $dateRange),
);
});
}
}