finalize export function

This commit is contained in:
2026-04-29 08:58:06 +07:00
parent d801964f59
commit cdd8251b17
7 changed files with 748 additions and 563 deletions

View File

@@ -64,82 +64,13 @@ class DashboardService
return $results;
}
/*
|--------------------------------------------------------------------------
| Fast SARI Summary (single query)
|--------------------------------------------------------------------------
*/
public function programSummaryFast($surveillanceId, $year, $week)
{
$row = SurveillanceCase::leftJoin(
'case_lab_results',
'surveillance_cases.lab_code',
'=',
'case_lab_results.lab_code'
)
->where('surveillance_cases.surveillance_id', $surveillanceId)
->where('surveillance_cases.year_data', $year)
->where('surveillance_cases.week_data', $week)
->selectRaw("
COUNT(DISTINCT surveillance_cases.lab_code) as total_cases,
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
THEN surveillance_cases.lab_code
END) as overall_positive,
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
AND (
LOWER(case_lab_results.pathogen_name) LIKE '%influenza%'
OR LOWER(case_lab_results.pathogen_name) LIKE '%influzena%'
)
THEN surveillance_cases.lab_code
END) as influenza_positive,
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
AND (
LOWER(case_lab_results.pathogen_name) LIKE '%covid%'
OR LOWER(case_lab_results.pathogen_name) LIKE '%sars%'
)
THEN surveillance_cases.lab_code
END) as covid_positive
")
->first();
if (!$row || $row->total_cases == 0) {
return [
'cases' => 0,
'overall_rate' => 0,
'influenza_rate' => 0,
'covid_rate' => 0
];
}
return [
'cases' => $row->total_cases,
'overall_rate' => round(($row->overall_positive / $row->total_cases) * 100, 1),
'influenza_rate' => round(($row->influenza_positive / $row->total_cases) * 100, 1),
'covid_rate' => round(($row->covid_positive / $row->total_cases) * 100, 1),
];
}
/*
|--------------------------------------------------------------------------
| Program Summary
|--------------------------------------------------------------------------
*/
public function afiTrend($surveillanceId, $startYear, $startWeek, $endYear, $endWeek)
{
return CaseLabResult::join(
@@ -152,107 +83,177 @@ class DashboardService
->where('surveillance_cases.surveillance_id', $surveillanceId)
->where(function ($q) use ($startYear, $startWeek, $endYear, $endWeek) {
$q->whereRaw("(year_data > ? OR (year_data = ? AND week_data >= ?))", [$startYear, $startYear, $startWeek])
->whereRaw("(year_data < ? OR (year_data = ? AND week_data <= ?))", [$endYear, $endYear, $endWeek]);
$q->whereRaw(
"(year_data > ? OR (year_data = ? AND week_data >= ?))",
[$startYear, $startYear, $startWeek]
)
->whereRaw(
"(year_data < ? OR (year_data = ? AND week_data <= ?))",
[$endYear, $endYear, $endWeek]
);
})
->where('case_lab_results.is_positive', 1)
->whereNotNull('case_lab_results.pathogen_name')
->where('case_lab_results.pathogen_name', '!=', '')
->where('case_lab_results.pathogen_name', '!=', 'Positive')
->where(function ($q) {
$q->whereNotNull('case_lab_results.pathogen_name')
->orWhereRaw("LOWER(case_lab_results.indicator) LIKE '%serum%'");
})
->selectRaw("
surveillance_cases.year_data as year,
surveillance_cases.week_data as period,
surveillance_cases.year_data as year,
surveillance_cases.week_data as period,
CASE
WHEN LOWER(case_lab_results.pathogen_name) LIKE '%influenza%' THEN 'Influenza'
ELSE case_lab_results.pathogen_name
END as pathogen,
CASE
WHEN LOWER(case_lab_results.pathogen_name) LIKE '%influenza%'
OR LOWER(case_lab_results.pathogen_name) LIKE '%influzena%'
THEN 'Influenza'
ELSE case_lab_results.pathogen_name
END as pathogen,
COUNT(DISTINCT surveillance_cases.lab_code) as total
")
CASE
WHEN LOWER(case_lab_results.indicator) LIKE '%serum%' THEN 'Serum'
ELSE 'PCR'
END as test_type,
COUNT(case_lab_results.id) as total_tests,
COUNT(DISTINCT surveillance_cases.lab_code) as total_tested,
COUNT(CASE
WHEN case_lab_results.is_positive = 1
THEN surveillance_cases.lab_code
END) as total_positive
")
->groupBy(
'surveillance_cases.year_data',
'surveillance_cases.week_data',
'pathogen'
'pathogen',
'test_type'
)
//->havingRaw("pathogen IS NOT NULL AND pathogen != ''")
->orderBy('surveillance_cases.year_data')
->orderBy('surveillance_cases.week_data')
->get();
->get()
->map(function ($r) {
$r->positivity_rate = $r->total_tested > 0
? round(($r->total_positive / $r->total_tested) * 100, 1)
: 0;
return $r;
});
}
public function programSummaryFast($surveillanceId, $year = null, $week = null, $dateFrom = null, $dateTo = null)
{
$query = SurveillanceCase::leftJoin(
'case_lab_results',
'surveillance_cases.lab_code',
'=',
'case_lab_results.lab_code'
)
->where('surveillance_cases.surveillance_id', $surveillanceId);
if ($dateFrom && $dateTo) {
$query->whereBetween('surveillance_cases.case_date', [$dateFrom, $dateTo]);
} else {
$query->where('surveillance_cases.year_data', $year)
->where('surveillance_cases.week_data', $week);
}
$row = $query->selectRaw("
COUNT(DISTINCT surveillance_cases.lab_code) as total_cases,
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
THEN surveillance_cases.lab_code
END) as overall_positive,
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
AND (
LOWER(case_lab_results.pathogen_name) LIKE '%influenza%'
OR LOWER(case_lab_results.pathogen_name) LIKE '%influzena%'
)
THEN surveillance_cases.lab_code
END) as influenza_positive,
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
AND (
LOWER(case_lab_results.pathogen_name) LIKE '%covid%'
OR LOWER(case_lab_results.pathogen_name) LIKE '%sars%'
)
THEN surveillance_cases.lab_code
END) as covid_positive
")->first();
if (!$row || $row->total_cases == 0) {
return [
'cases' => 0,
'overall_rate' => 0,
'influenza_rate' => 0,
'covid_rate' => 0
];
}
return [
'cases' => $row->total_cases,
'overall_rate' => round(($row->overall_positive / $row->total_cases) * 100, 1),
'influenza_rate' => round(($row->influenza_positive / $row->total_cases) * 100, 1),
'covid_rate' => round(($row->covid_positive / $row->total_cases) * 100, 1),
];
}
public function programSummary($surveillanceId, $startYear, $startWeek, $endYear, $endWeek)
{
$dateTo = now()->toDateString();
$dateFrom = now()->subDays(7)->toDateString();
$prevWeek = $endWeek - 1;
$prevYear = $endYear;
$current = $this->programSummaryFast(
$surveillanceId,
null,
null,
$dateFrom,
$dateTo
);
if ($prevWeek <= 0) {
$prevWeek = 52;
$prevYear--;
}
$prevFrom = date('Y-m-d', strtotime($dateFrom . ' -7 days'));
$prevTo = date('Y-m-d', strtotime($dateFrom . ' -1 day'));
$latest = SurveillanceCase::where('surveillance_id', $surveillanceId)
->selectRaw("year_data, week_data")
->orderByDesc('year_data')
->orderByDesc('week_data')
->first();
$year = $latest->year_data;
$week = $latest->week_data;
$current = $this->programSummaryFast($surveillanceId, $year, $week);
$previous = $this->programSummaryFast($surveillanceId, $prevYear, $prevWeek);
$prevWeek = $week - 1;
$prevYear = $year;
if ($prevWeek <= 0) {
$prevWeek = 52;
$prevYear--;
}
$previous = $this->programSummaryFast($surveillanceId, $prevYear, $prevWeek);
$previous = $this->programSummaryFast(
$surveillanceId,
null,
null,
$prevFrom,
$prevTo
);
return [
'cases' => [
'current' => $current['cases'],
'previous' => $previous['cases']
],
'hospital_rate' => [
'current' => 0,
'previous' => 0
],
'icu_rate' => [
'current' => 0,
'previous' => 0
],
'positivity_rate' => [
'current' => $current['overall_rate'],
'previous' => $previous['overall_rate']
],
'influenza_rate' => [
'current' => $current['influenza_rate'],
'previous' => $previous['influenza_rate']
],
'covid_rate' => [
'current' => $current['covid_rate'],
'previous' => $previous['covid_rate']
],
];
}
/*
|--------------------------------------------------------------------------
| Overview Trend
@@ -437,7 +438,7 @@ class DashboardService
COUNT(DISTINCT surveillance_cases.lab_code) as total_samples,
-- Overall positivity rate
-- Overall positivity
ROUND(
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
@@ -446,33 +447,52 @@ class DashboardService
/ NULLIF(COUNT(DISTINCT surveillance_cases.lab_code), 0) * 100
,1) as positivity_rate,
-- Influenza positivity rate
-- Influenza %
ROUND(
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
AND (
LOWER(case_lab_results.pathogen_name) LIKE '%influenza%'
OR LOWER(case_lab_results.pathogen_name) LIKE '%influzena%'
)
THEN surveillance_cases.lab_code
END)
/ NULLIF(COUNT(DISTINCT surveillance_cases.lab_code), 0) * 100
,1) as influenza_rate,
-- COVID positivity rate
-- COVID %
ROUND(
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
AND (
case_lab_results.pathogen_name = 'Positive'
case_lab_results.pathogen_name = 'COVID-19'
OR case_lab_results.pathogen_name = 'SARS-CoV-2'
)
AND case_lab_results.indicator LIKE '%Covid%'
AND case_lab_results.indicator LIKE '%COVID%'
THEN surveillance_cases.lab_code
END)
/ NULLIF(COUNT(DISTINCT surveillance_cases.lab_code), 0) * 100
,1) as covid_rate
")
,1) as covid_rate,
-- EV %
ROUND(
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
AND LOWER(case_lab_results.pathogen_name) LIKE '%enterovirus%'
THEN surveillance_cases.lab_code
END)
/ NULLIF(COUNT(DISTINCT surveillance_cases.lab_code), 0) * 100
,1) as ev_rate,
-- MPOX %
ROUND(
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
AND LOWER(case_lab_results.pathogen_name) LIKE '%mpox%'
THEN surveillance_cases.lab_code
END)
/ NULLIF(COUNT(DISTINCT surveillance_cases.lab_code), 0) * 100
,1) as mpox_rate
")
->groupBy(
'surveillance_cases.year_data',
@@ -546,7 +566,6 @@ class DashboardService
WHEN case_lab_results.is_positive = 1
AND (
LOWER(case_lab_results.pathogen_name) LIKE '%influenza%'
OR LOWER(case_lab_results.pathogen_name) LIKE '%influzena%'
)
THEN surveillance_cases.lab_code
END) as influenza,
@@ -559,7 +578,19 @@ class DashboardService
)
AND case_lab_results.indicator LIKE '%Covid%'
THEN surveillance_cases.lab_code
END) as covid
END) as covid,
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
AND LOWER(case_lab_results.pathogen_name) LIKE '%enterovirus%'
THEN surveillance_cases.lab_code
END) as ev,
COUNT(DISTINCT CASE
WHEN case_lab_results.is_positive = 1
AND LOWER(case_lab_results.pathogen_name) LIKE '%mpox%'
THEN surveillance_cases.lab_code
END) as mpox
")
->groupBy('surveillance_cases.week_data')
@@ -643,7 +674,7 @@ class DashboardService
return SurveillanceCase::join('case_lab_results', function ($join) {
$join->on('surveillance_cases.lab_code', '=', 'case_lab_results.lab_code')
->on('surveillance_cases.surveillance_id', '=', 'case_lab_results.surveillance_id');
})
})
->where(function ($q) use ($startYear, $startWeek, $endYear, $endWeek) {
$q->whereRaw(
"(surveillance_cases.year_data * 100 + surveillance_cases.week_data) BETWEEN ? AND ?",
@@ -670,17 +701,17 @@ class DashboardService
$join->on('surveillance_cases.lab_code', '=', 'case_lab_results.lab_code')
->on('surveillance_cases.surveillance_id', '=', 'case_lab_results.surveillance_id');
})
->where(function ($q) use ($startYear, $startWeek, $endYear, $endWeek) {
$q->whereRaw(
"(surveillance_cases.year_data * 100 + surveillance_cases.week_data) BETWEEN ? AND ?",
[
$startYear * 100 + $startWeek,
$endYear * 100 + $endWeek
]
);
})
->whereRaw('case_lab_results.is_positive = 1 and surveillance_cases.surveillance_id not in(6) and case_lab_results.indicator="Covid-19"')
->selectRaw("
->where(function ($q) use ($startYear, $startWeek, $endYear, $endWeek) {
$q->whereRaw(
"(surveillance_cases.year_data * 100 + surveillance_cases.week_data) BETWEEN ? AND ?",
[
$startYear * 100 + $startWeek,
$endYear * 100 + $endWeek
]
);
})
->whereRaw('case_lab_results.is_positive = 1 and surveillance_cases.surveillance_id not in(6) and case_lab_results.indicator="Covid-19"')
->selectRaw("
CASE
WHEN patient_age_inday <= 28 THEN '028 days'
WHEN patient_age_inday <= 364 THEN '29 days11 months'
@@ -703,9 +734,9 @@ class DashboardService
END as age_order,
COUNT(*) as total
")
->groupBy('age_group', 'age_order')
->orderBy('age_order')
->get();
->groupBy('age_group', 'age_order')
->orderBy('age_order')
->get();
}