173 lines
7.6 KiB
PHP
173 lines
7.6 KiB
PHP
<?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);
|
||
}
|
||
}
|