Добавил базовые датасеты и агрегации для конструктора отчетов
This commit is contained in:
122
app/Services/Analytics/DataSets/ShiftsDataSet.php
Normal file
122
app/Services/Analytics/DataSets/ShiftsDataSet.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Analytics\DataSets;
|
||||
|
||||
use App\Domain\Reports\ValueObjects\MetrikaConfig;
|
||||
use App\Models\Department;
|
||||
use App\Models\MisLpuDoctor;
|
||||
use App\Services\Analytics\AbstractDataSet;
|
||||
use App\Services\Analytics\AnalyticsQuery;
|
||||
use App\Services\Analytics\Dimension;
|
||||
use App\Services\Analytics\FilterDef;
|
||||
use App\Services\Analytics\Measure;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ShiftsDataSet extends AbstractDataSet
|
||||
{
|
||||
private const STATUS_OPTIONS = [1 => 'Черновик', 2 => 'Сдан'];
|
||||
|
||||
public function key(): string
|
||||
{
|
||||
return 'shifts';
|
||||
}
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return 'Смены / дежурства';
|
||||
}
|
||||
|
||||
public function description(): string
|
||||
{
|
||||
return 'Показатели сданных дежурных смен отделения';
|
||||
}
|
||||
|
||||
public function category(): string
|
||||
{
|
||||
return 'Дежурства';
|
||||
}
|
||||
|
||||
protected function dateField(): string
|
||||
{
|
||||
return 'rd.period_start';
|
||||
}
|
||||
|
||||
protected function baseQuery(AnalyticsQuery $query): Builder
|
||||
{
|
||||
return DB::table('report_duties as rd')
|
||||
->leftJoin('duty_report_metric_results as m', 'm.rf_report_id', '=', 'rd.id')
|
||||
->where('rd.rf_department_id', $query->department->department_id)
|
||||
->where('rd.status_id', 2)
|
||||
->where('rd.period_start', '>=', $query->dateRange->startSql())
|
||||
->where('rd.period_end', '<=', $query->dateRange->endSql());
|
||||
}
|
||||
|
||||
public function dimensions(): array
|
||||
{
|
||||
return [
|
||||
new Dimension('shift_date', 'Дата смены', 'date', 'CAST(rd.period_start AS date)'),
|
||||
new Dimension(
|
||||
'doctor',
|
||||
'Врач',
|
||||
'string',
|
||||
'rd.rf_lpudoctor_id',
|
||||
labels: fn (array $ids) => MisLpuDoctor::whereIn('LPUDoctorID', $ids)->get()
|
||||
->mapWithKeys(fn ($d) => [$d->LPUDoctorID => trim("{$d->FAM_V} {$d->IM_V} {$d->OT_V}") ?: "Врач #{$d->LPUDoctorID}"])
|
||||
->all(),
|
||||
),
|
||||
new Dimension(
|
||||
'department',
|
||||
'Отделение',
|
||||
'string',
|
||||
'rd.rf_department_id',
|
||||
labels: fn (array $ids) => Department::whereIn('department_id', $ids)->get()
|
||||
->mapWithKeys(fn ($d) => [$d->department_id => $d->name_full ?? $d->name_short])
|
||||
->all(),
|
||||
),
|
||||
new Dimension(
|
||||
'status',
|
||||
'Статус',
|
||||
'string',
|
||||
'rd.status_id',
|
||||
labels: fn () => self::STATUS_OPTIONS,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
public function measures(): array
|
||||
{
|
||||
return [
|
||||
new Measure('shifts_count', 'Количество смен', 'count', 'COUNT(DISTINCT rd.id)'),
|
||||
new Measure('beds', 'Коек', 'count', $this->sum(MetrikaConfig::BEDS)),
|
||||
new Measure('recipient_plan', 'Поступило плановых', 'count', $this->sum(MetrikaConfig::PLAN)),
|
||||
new Measure('recipient_emergency', 'Поступило экстренных', 'count', $this->sum(MetrikaConfig::EMERGENCY)),
|
||||
new Measure('discharged', 'Выписано', 'count', $this->sum(MetrikaConfig::DISCHARGED)),
|
||||
new Measure('transferred', 'Переведено', 'count', $this->sum(MetrikaConfig::TRANSFERRED)),
|
||||
new Measure('deceased', 'Умерло', 'count', $this->sum(MetrikaConfig::DECEASED)),
|
||||
new Measure('surgery_plan', 'Операции плановые', 'count', $this->sum(MetrikaConfig::PLAN_SURGERY)),
|
||||
new Measure('surgery_emergency', 'Операции экстренные', 'count', $this->sum(MetrikaConfig::EMERGENCY_SURGERY)),
|
||||
new Measure('occupancy_percent', 'Занятость, %', 'percent', $this->avg(MetrikaConfig::DEPARTMENT_LOADED)),
|
||||
new Measure('avg_bed_days', 'Ср. койко-день', null, $this->avg(MetrikaConfig::AVERAGE_BED_DAYS)),
|
||||
new Measure('lethality_percent', 'Летальность, %', 'percent', $this->avg(MetrikaConfig::LETHALITY)),
|
||||
new Measure('staff_count', 'Мед. персонал', 'count', $this->avg(MetrikaConfig::STAFF_COUNT)),
|
||||
];
|
||||
}
|
||||
|
||||
public function filters(): array
|
||||
{
|
||||
return [
|
||||
new FilterDef('doctor', 'Врач', 'rd.rf_lpudoctor_id', 'select', null, 'doctors'),
|
||||
];
|
||||
}
|
||||
|
||||
private function sum(int $metricId): string
|
||||
{
|
||||
return "SUM(CASE WHEN m.rf_metrika_item_id = {$metricId} THEN NULLIF(m.value, '')::numeric ELSE 0 END)";
|
||||
}
|
||||
|
||||
private function avg(int $metricId): string
|
||||
{
|
||||
return "AVG(CASE WHEN m.rf_metrika_item_id = {$metricId} THEN NULLIF(m.value, '')::numeric END)";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user