Профиль хирургии
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
// app/Services/MetricCalculators/PreoperativeDaysCalculator.php
|
||||
|
||||
namespace App\Services\MetricCalculators;
|
||||
|
||||
use App\Services\Base\BaseMetricService;
|
||||
use App\Contracts\MetricCalculatorInterface;
|
||||
use App\Models\MedicalHistorySnapshot;
|
||||
use App\Models\Report;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class PreoperativeDaysCalculator extends BaseMetricService implements MetricCalculatorInterface
|
||||
{
|
||||
public function getMetricId(): int
|
||||
{
|
||||
return 21;
|
||||
}
|
||||
|
||||
public function calculate(array $departmentIds, string $startDate, string $endDate): array
|
||||
{
|
||||
if (empty($departmentIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Получаем отчеты за период
|
||||
$reports = Report::whereIn('rf_department_id', $departmentIds)
|
||||
->where('sent_at', '>', $startDate)
|
||||
->where('sent_at', '<=', $endDate)
|
||||
// ->whereBetween('created_at', [$startDate, $endDate])
|
||||
->get(['report_id', 'rf_department_id'])
|
||||
->keyBy('report_id');
|
||||
|
||||
if ($reports->isEmpty()) {
|
||||
return array_fill_keys($departmentIds, 0);
|
||||
}
|
||||
|
||||
$reportIds = $reports->keys()->toArray();
|
||||
|
||||
// Получаем пациентов из снапшотов
|
||||
$snapshots = MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds)
|
||||
->whereIn('patient_type', ['discharged', 'deceased'])
|
||||
->get(['rf_report_id', 'rf_medicalhistory_id']);
|
||||
|
||||
if ($snapshots->isEmpty()) {
|
||||
return array_fill_keys($departmentIds, 0);
|
||||
}
|
||||
|
||||
$historyIds = $snapshots->pluck('rf_medicalhistory_id')->unique()->toArray();
|
||||
|
||||
// Получаем первые операции и первые поступления одним запросом
|
||||
$operations = DB::table('stt_surgicaloperation as so')
|
||||
->join('stt_migrationpatient as mp', 'so.rf_MedicalHistoryID', '=', 'mp.rf_MedicalHistoryID')
|
||||
->whereIn('so.rf_MedicalHistoryID', $historyIds)
|
||||
->whereNotNull('so.Date')
|
||||
->whereNotNull('mp.DateIngoing')
|
||||
->select(
|
||||
'so.rf_MedicalHistoryID',
|
||||
DB::raw('MIN(so."Date") as first_operation'),
|
||||
DB::raw('MIN(mp."DateIngoing") as first_admission')
|
||||
)
|
||||
->groupBy('so.rf_MedicalHistoryID')
|
||||
->get()
|
||||
->keyBy('rf_MedicalHistoryID');
|
||||
|
||||
// Группируем по отделениям
|
||||
$results = [];
|
||||
foreach ($snapshots as $snapshot) {
|
||||
$deptId = $reports[$snapshot->rf_report_id]->rf_department_id;
|
||||
$historyId = $snapshot->rf_medicalhistory_id;
|
||||
|
||||
if (!isset($operations[$historyId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$op = $operations[$historyId];
|
||||
$days = Carbon::parse($op->first_admission)
|
||||
->diffInDays(Carbon::parse($op->first_operation));
|
||||
|
||||
if ($days >= 0) {
|
||||
if (!isset($results[$deptId])) {
|
||||
$results[$deptId] = ['total' => 0, 'count' => 0];
|
||||
}
|
||||
$results[$deptId]['total'] += $days;
|
||||
$results[$deptId]['count']++;
|
||||
}
|
||||
}
|
||||
|
||||
// Усредняем по отделениям
|
||||
$preoperative = [];
|
||||
foreach ($departmentIds as $deptId) {
|
||||
$preoperative[$deptId] = isset($results[$deptId]) && $results[$deptId]['count'] > 0
|
||||
? round($results[$deptId]['total'] / $results[$deptId]['count'], 1)
|
||||
: 0;
|
||||
}
|
||||
|
||||
return $preoperative;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user