Перевод на доменную архитектуру
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace App\Infrastructure\Reports\Services;
|
||||
|
||||
use App\Domain\Reports\ValueObjects\MetrikaConfig;
|
||||
use App\Models\Department;
|
||||
use App\Models\DepartmentPatientOperation;
|
||||
use App\Models\MedicalHistorySnapshot;
|
||||
use App\Models\MisStationarBranch;
|
||||
use App\Models\ObservationPatient;
|
||||
use App\Models\Report;
|
||||
use App\Models\UnwantedEvent;
|
||||
use App\Models\User;
|
||||
use App\Services\DateRange;
|
||||
use App\Services\DateRangeService;
|
||||
use App\Services\PatientService;
|
||||
|
||||
class CalculatedMetricsSynchronizer
|
||||
{
|
||||
public function __construct(
|
||||
private readonly DateRangeService $dateRangeService,
|
||||
private readonly PatientService $patientService,
|
||||
private readonly ReportStorageService $reportStorageService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public function sync(Report $report, User $user, array $data): void
|
||||
{
|
||||
if (! isset($data['dates'][0], $data['dates'][1])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$department = Department::query()->where('department_id', $report->rf_department_id)->first();
|
||||
if (! $department) {
|
||||
return;
|
||||
}
|
||||
|
||||
$dateRange = $this->dateRangeService->getNormalizedDateRange(
|
||||
$user,
|
||||
(string) $data['dates'][0],
|
||||
(string) $data['dates'][1]
|
||||
);
|
||||
|
||||
$branchId = $this->getBranchId($department->rf_mis_department_id);
|
||||
|
||||
$planCount = $this->countUniqueSnapshotsForTypes($report->report_id, ['plan']);
|
||||
$emergencyCount = $this->countUniqueSnapshotsForTypes($report->report_id, ['emergency']);
|
||||
$recipientCount = $this->countUniqueSnapshotsForTypes($report->report_id, ['recipient']);
|
||||
$dischargedCount = $this->countUniqueSnapshotsForTypes($report->report_id, ['discharged']);
|
||||
$transferredCount = $this->countUniqueSnapshotsForTypes($report->report_id, ['transferred']);
|
||||
$deceasedCount = $this->countUniqueSnapshotsForTypes($report->report_id, ['deceased']);
|
||||
$currentCount = $this->countUniqueSnapshotsForTypes($report->report_id, ['current']);
|
||||
$outcomeCount = $dischargedCount + $deceasedCount;
|
||||
|
||||
$manualSurgicalCount = $this->getManualSurgicalCounts($department, $dateRange);
|
||||
$misEmergencySurgery = $branchId
|
||||
? $this->patientService->getSurgicalPatients('emergency', $branchId, $dateRange, true)
|
||||
: 0;
|
||||
$misPlanSurgery = $branchId
|
||||
? $this->patientService->getSurgicalPatients('plan', $branchId, $dateRange, true)
|
||||
: 0;
|
||||
|
||||
$observationCount = ObservationPatient::query()
|
||||
->where('rf_department_id', $department->department_id)
|
||||
->where('rf_report_id', $report->report_id)
|
||||
->count();
|
||||
|
||||
$unwantedEventsCount = UnwantedEvent::query()
|
||||
->where('rf_report_id', $report->report_id)
|
||||
->count();
|
||||
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::RECIPIENT, $recipientCount);
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::PLAN, $planCount);
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::OUTCOME, $outcomeCount);
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::CURRENT, $currentCount);
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::DECEASED, $deceasedCount);
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::EMERGENCY_SURGERY, $misEmergencySurgery + ($manualSurgicalCount[0] ?? 0));
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::PLAN_SURGERY, $misPlanSurgery + ($manualSurgicalCount[1] ?? 0));
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::EMERGENCY, $emergencyCount);
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::TRANSFERRED, $transferredCount);
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::OBSERVATION, $observationCount);
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::DISCHARGED, $dischargedCount);
|
||||
$this->reportStorageService->saveMetric($report, MetrikaConfig::UNWANTED_EVENTS, $unwantedEventsCount);
|
||||
}
|
||||
|
||||
private function getBranchId(int $misDepartmentId): ?int
|
||||
{
|
||||
return MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)
|
||||
->value('StationarBranchID');
|
||||
}
|
||||
|
||||
private function countUniqueSnapshotsForTypes(int $reportId, array $patientTypes): int
|
||||
{
|
||||
return MedicalHistorySnapshot::query()
|
||||
->where('rf_report_id', $reportId)
|
||||
->whereIn('patient_type', $patientTypes)
|
||||
->get(['medical_history_snapshot_id', 'patient_uid', 'rf_medicalhistory_id'])
|
||||
->map(function (MedicalHistorySnapshot $snapshot) {
|
||||
return $snapshot->patient_uid
|
||||
?: ($snapshot->rf_medicalhistory_id
|
||||
? "mis:{$snapshot->rf_medicalhistory_id}"
|
||||
: "snapshot:{$snapshot->medical_history_snapshot_id}");
|
||||
})
|
||||
->unique()
|
||||
->count();
|
||||
}
|
||||
|
||||
public function getManualSurgicalCounts(Department $department, DateRange $dateRange): array
|
||||
{
|
||||
$baseQuery = DepartmentPatientOperation::query()
|
||||
->whereBetween('started_at', [$dateRange->startSql(), $dateRange->endSql()])
|
||||
->whereHas('patient', function ($query) use ($department) {
|
||||
$query->where('rf_department_id', $department->department_id)
|
||||
->whereIn('source_type', ['manual', 'special']);
|
||||
});
|
||||
|
||||
$emergencyCount = (clone $baseQuery)
|
||||
->where(function ($query) {
|
||||
$query->where('urgency', 'emergency')
|
||||
->orWhere(function ($fallback) {
|
||||
$fallback->whereNull('urgency')
|
||||
->whereHas('patient', fn ($patientQuery) => $patientQuery->where('patient_kind', 'emergency'));
|
||||
});
|
||||
})
|
||||
->count();
|
||||
|
||||
$planCount = (clone $baseQuery)
|
||||
->where(function ($query) {
|
||||
$query->where('urgency', 'plan')
|
||||
->orWhere(function ($fallback) {
|
||||
$fallback->whereNull('urgency')
|
||||
->whereHas('patient', fn ($patientQuery) => $patientQuery->where('patient_kind', 'plan'));
|
||||
});
|
||||
})
|
||||
->count();
|
||||
|
||||
return [$emergencyCount, $planCount];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user