Files
onboard/app/Http/Controllers/Api/StatisticController.php

173 lines
7.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Department;
use App\Models\DutyUnwantedEvent;
use App\Models\ReportDutyPatient;
use App\Services\DateRangeService;
use App\Services\ReportService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class StatisticController extends Controller
{
public function __construct(
protected DateRangeService $dateRangeService,
protected ReportService $reportService
) {}
public function getUnwantedEvents(Request $request)
{
$user = Auth::user();
$validated = $request->validate([
'startAt' => 'required',
'endAt' => 'required',
'departmentId' => 'required',
]);
$dateRange = $this->dateRangeService->getNormalizedDateRange($user, $validated['startAt'], $validated['endAt']);
$department = Department::findSole($request->departmentId, 'department_id');
$unwantedEvents = DutyUnwantedEvent::query()
->whereHas('reportDuty', function ($q) use ($department, $dateRange) {
$q->where('rf_department_id', $department->department_id)
->where('period_start', '>=', $dateRange->startSql())
->where('period_end', '<=', $dateRange->endSql());
})
->get()
->map(fn ($e) => [
...$e->toArray(),
'created_at' => Carbon::parse($e->created_at)->format('Создано d.m.Y в H:i'),
]);
return response()->json($unwantedEvents);
}
public function getObservablePatients(Request $request)
{
$user = Auth::user();
$validated = $request->validate([
'startAt' => 'required',
'endAt' => 'required',
'departmentId' => 'required',
]);
$dateRange = $this->dateRangeService->getNormalizedDateRange($user, $validated['startAt'], $validated['endAt']);
$department = Department::findSole($request->departmentId, 'department_id');
$observablePatients = DB::table('observable_medical_histories as omh')
->join('report_duty_patients as rdp', 'rdp.original_id', '=', 'omh.original_id')
->join('report_duties as rd', 'rd.id', '=', 'rdp.report_duty_id')
->leftJoin('report_duty_migration_patients as rdm', function ($join) {
$join->on('rdm.medical_history_id', '=', 'rdp.id')
->whereNull('rdm.out_date');
})
->where('rd.rf_department_id', $department->department_id)
->where('omh.observable_in', '>=', $dateRange->startSql())
->where('omh.observable_in', '<=', $dateRange->endSql())
->select('omh.*', 'rdm.diagnosis_code', 'rdm.diagnosis_name', 'rdm.ingoing_date as migration_ingoing_date')
->distinct()
->get()
->map(fn ($row) => [
'id' => $row->id,
'full_name' => $row->full_name,
'birth_date' => $row->birth_date,
'comment' => $row->comment,
'observable_reason'=> $row->observable_reason,
'observable_in' => $row->observable_in,
'observable_out' => $row->observable_out,
'migrations' => [[
'ingoing_date' => $row->migration_ingoing_date ?? $row->recipient_date,
'diagnosis_code' => $row->diagnosis_code,
'diagnosis_name' => $row->diagnosis_name,
]],
'operations' => [],
]);
return response()->json($observablePatients);
}
public function getDeadPatients(Request $request)
{
$user = Auth::user();
$departmentType = $request->query('departmentType');
$availableDepartments = $user->availableDepartments()->pluck('department_id')->all();
$validated = $request->validate([
'startAt' => 'required',
'endAt' => 'required',
]);
$dateRange = $this->dateRangeService->getNormalizedDateRange($user, $validated['startAt'], $validated['endAt']);
$lastMigrations = DB::table('report_duty_migration_patients')
->select('id', DB::raw('MAX(ingoing_date) as max_ingoing_date'))
->where('ingoing_date', '>=', $dateRange->startSql())
->where('ingoing_date', '<=', $dateRange->endSql())
->groupBy('id');
$deadPatients = DB::table('report_duty_migration_patients as rdm')
->joinSub($lastMigrations, 'last_rdm', function ($join) {
$join->on('rdm.id', '=', 'last_rdm.id')
->on('rdm.ingoing_date', '=', 'last_rdm.max_ingoing_date');
})
->leftJoin('report_duty_patients as rdp', 'rdm.id', '=', 'rdp.id')
->join('report_duties as rd', 'rd.id', '=', 'rdp.report_duty_id')
->join('departments as dep', 'dep.department_id', '=', 'rd.rf_department_id')
->whereIn('rd.rf_department_id', $availableDepartments)
->whereNotNull('rdp.death_date')
->select(
'rdp.id', 'rdp.full_name', 'rdp.birth_date', 'rdp.recipient_date', 'rdm.ingoing_date',
'rdm.diagnosis_code', 'rdm.diagnosis_name', 'dep.name_full'
)
->orderBy('rdm.ingoing_date', 'desc')
->orderBy('rdm.id', 'desc')
->get()
->groupBy('medical_history_id') // Группируем по id пациента
->map(fn ($rows) => $rows->first()) // Берем первую (самую последнюю) запись
->values()
->map(fn ($row) => [
'id' => $row->id,
'full_name' => $row->full_name,
'birth_date' => $row->birth_date,
'ingoing_date' => $row->ingoing_date ?? $row->recipient_date,
'diagnosis_code' => $row->diagnosis_code,
'diagnosis_name' => $row->diagnosis_name,
'department_name' => $row->name_full,
]);
$deadPatients = ReportDutyPatient::query()
->whereHas('latestMigration', function ($query) use ($dateRange) {
$query->where('ingoing_date', '<=', $dateRange->endSql())
->where(function ($sub) use ($dateRange) {
// Миграции без out_date (еще лежат)
$sub->whereNull('out_date');
// Миграции с out_date (закрытые)
$sub->orWhere(function ($sub2) use ($dateRange) {
$sub2->whereNotNull('out_date')
->where('out_date', '>', $dateRange->startSql());
});
});
})
->with('latestMigration')
->whereNotNull('death_date')
->get()->unique('original_id')->values()
->map(fn ($row) => [
'id' => $row->id,
'full_name' => $row->full_name,
'birth_date' => $row->birth_date,
'ingoing_date' => $row->latestMigration->ingoing_date ?? $row->recipient_date,
'diagnosis_code' => $row->latestMigration->diagnosis_code,
'diagnosis_name' => $row->latestMigration->diagnosis_name,
'department_name' => $row->latestMigration->department->name_full,
]);
return response()->json($deadPatients);
}
}