Добавил базовые датасеты и агрегации для конструктора отчетов

This commit is contained in:
brusnitsyn
2026-06-22 17:00:58 +09:00
parent 71bd4b9d1a
commit 5bad7599cf
16 changed files with 1453 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
<?php
namespace App\Services\Analytics\DataSets\Concerns;
use App\Services\Analytics\Dimension;
use App\Services\Analytics\Measure;
/**
* Общие измерения и показатели для пациентских источников (дежурный врач / медсестра).
* Псевдоним пациентской таблицы передаётся параметром ($p), исходы считаются по той же
* логике, что и ReportSourceRegistry::outcomeLabel (death_date / visit_result_id∈{4,14} / extract_date).
*/
trait PatientAggregates
{
private const URGENCY_OPTIONS = [1 => 'Планово', 2 => 'Экстренно'];
private function urgencyDimension(string $p): Dimension
{
return new Dimension(
'urgency',
'Срочность',
'string',
"{$p}.urgency_id",
labels: fn () => self::URGENCY_OPTIONS,
);
}
private function outcomeDimension(string $p): Dimension
{
$expr = "CASE
WHEN {$p}.death_date IS NOT NULL THEN 'Умер'
WHEN COALESCE({$p}.visit_result_id, 0) IN (4, 14) THEN 'Переведён'
WHEN {$p}.extract_date IS NOT NULL THEN 'Выписан'
ELSE 'В отделении' END";
return new Dimension('outcome', 'Исход', 'string', $expr);
}
/**
* @param string $p алиас таблицы пациентов
* @param string|null $report алиас отчёта (report_duties/report_nurses) если задан,
* добавляется показатель «Поступило» (по дате поступления в период смены)
* @return Measure[]
*/
private function patientMeasures(string $p, ?string $report = null): array
{
return [
new Measure('patients_count', 'Количество пациентов', 'count', 'COUNT(*)'),
...($report !== null ? [$this->admittedMeasure($p, $report)] : []),
...$this->outcomeMeasures($p),
];
}
/**
* «Поступило» пациенты, чья дата поступления попала в период смены отчёта.
* Требует алиас отчёта ($report), т.к. границы периода лежат в report_duties/report_nurses.
*/
private function admittedMeasure(string $p, string $report): Measure
{
return new Measure('admitted', 'Поступило', 'count',
"SUM(CASE WHEN {$p}.recipient_date >= {$report}.period_start AND {$p}.recipient_date <= {$report}.period_end THEN 1 ELSE 0 END)");
}
/** @return Measure[] */
private function outcomeMeasures(string $p): array
{
return [
new Measure('discharged', 'Выписано', 'count',
"SUM(CASE WHEN {$p}.death_date IS NULL AND COALESCE({$p}.visit_result_id, 0) NOT IN (4, 14) AND {$p}.extract_date IS NOT NULL THEN 1 ELSE 0 END)"),
new Measure('transferred', 'Переведено', 'count',
"SUM(CASE WHEN {$p}.death_date IS NULL AND COALESCE({$p}.visit_result_id, 0) IN (4, 14) THEN 1 ELSE 0 END)"),
new Measure('deceased', 'Умерло', 'count',
"SUM(CASE WHEN {$p}.death_date IS NOT NULL THEN 1 ELSE 0 END)"),
new Measure('in_department', 'В отделении', 'count',
"SUM(CASE WHEN {$p}.death_date IS NULL AND COALESCE({$p}.visit_result_id, 0) NOT IN (4, 14) AND {$p}.extract_date IS NULL THEN 1 ELSE 0 END)"),
];
}
}