248 lines
11 KiB
PHP
248 lines
11 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->misDepartments->pluck('rf_mis_department_id')->toArray();
|
|
|
|
$validated = $request->validate([
|
|
'startAt' => 'required',
|
|
'endAt' => 'required',
|
|
]);
|
|
|
|
$dateRange = $this->dateRangeService->getNormalizedDateRange($user, $validated['startAt'], $validated['endAt']);
|
|
|
|
$deadPatients = ReportDutyPatient::query()
|
|
->whereHas('latestMigration', function ($q) use ($availableDepartments) {
|
|
$q->whereIn('department_id', $availableDepartments);
|
|
})
|
|
->with('latestMigration')
|
|
->where('death_date', '>', $dateRange->startSql())
|
|
->where('death_date', '<=', $dateRange->endSql())
|
|
->orderBy('death_date', 'desc')
|
|
->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);
|
|
}
|
|
|
|
public function getTransferredPatients(Request $request)
|
|
{
|
|
$user = Auth::user();
|
|
$departmentType = $request->query('departmentType');
|
|
$availableDepartments = $user->misDepartments->pluck('rf_mis_department_id')->toArray();
|
|
|
|
$validated = $request->validate([
|
|
'startAt' => 'required',
|
|
'endAt' => 'required',
|
|
]);
|
|
|
|
$dateRange = $this->dateRangeService->getNormalizedDateRange($user, $validated['startAt'], $validated['endAt']);
|
|
|
|
$deadPatients = ReportDutyPatient::query()
|
|
->whereHas('latestMigration', function ($q) use ($availableDepartments) {
|
|
$q->whereIn('department_id', $availableDepartments);
|
|
})
|
|
->with('latestMigration')
|
|
->where('death_date', '>', $dateRange->startSql())
|
|
->where('death_date', '<=', $dateRange->endSql())
|
|
->orderBy('death_date', 'desc')
|
|
->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);
|
|
}
|
|
|
|
public function getPatients(Request $request)
|
|
{
|
|
$user = Auth::user();
|
|
$departmentType = $request->query('departmentType');
|
|
$availableDepartments = $user->misDepartments->pluck('rf_mis_department_id')->toArray();
|
|
$validated = $request->validate([
|
|
'startAt' => 'required',
|
|
'endAt' => 'required',
|
|
'type' => 'required',
|
|
'departmentId' => 'nullable'
|
|
]);
|
|
$dateRange = $this->dateRangeService->getNormalizedDateRange($user, $validated['startAt'], $validated['endAt']);
|
|
|
|
$query = ReportDutyPatient::join('report_duties', 'report_duty_patients.report_duty_id', '=', 'report_duties.id')
|
|
->where('report_duties.period_start', '>=', $dateRange->startSql())
|
|
->where('report_duties.period_start', '<=', $dateRange->endSql())
|
|
->select('report_duty_patients.*')
|
|
->when(isset($validated['departmentId']), function ($query) use ($validated) {
|
|
return $query->where('rf_department_id', $validated['departmentId']);
|
|
})
|
|
->distinct(['original_id']);
|
|
|
|
$filterQuery = $this->getQueryByType($validated['type']);
|
|
if (isset($validated['type'])) {
|
|
$filterQuery($query, $dateRange->startDate, $dateRange->endDate);
|
|
}
|
|
|
|
$patients = $query->get();
|
|
|
|
return response()->json($patients);
|
|
}
|
|
|
|
private function getQueryByType($type) {
|
|
$types = [
|
|
'RECIPIENT_ALL' => function ($query, $start, $end) {
|
|
$query->where('report_duty_patients.recipient_date', '>=', $start)
|
|
->where('report_duty_patients.recipient_date', '<=', $end);
|
|
},
|
|
'RECIPIENT_PLAN' => function ($query, $start, $end) {
|
|
$query->where('report_duty_patients.urgency_id', 1);
|
|
},
|
|
'RECIPIENT_EMERGENCY' => function ($query, $start, $end) {
|
|
$query->where('report_duty_patients.recipient_date', '>', $start)
|
|
->where('report_duty_patients.recipient_date', '<', $end)
|
|
->where('report_duty_patients.urgency_id', 2);
|
|
},
|
|
'RECIPIENT_TRANSFERRED' => function ($query, $start, $end) {
|
|
$query->whereIn('report_duty_patients.visit_result_id', [4, 14]);
|
|
},
|
|
'OUTCOME' => function ($query, $start, $end) {
|
|
$query->whereBetween('report_duty_patients.extract_date', [$start, $end]);
|
|
},
|
|
'CONSIST' => function ($query, $start, $end) {
|
|
// Пациенты, которые числятся в отчётах за период и не выписаны/не умерли на конец периода
|
|
$query->where(function ($q) use ($end) {
|
|
$q->whereNull('report_duty_patients.extract_date')
|
|
->orWhere('report_duty_patients.extract_date', '>', $end);
|
|
})
|
|
->where(function ($q) use ($end) {
|
|
$q->whereNull('report_duty_patients.death_date')
|
|
->orWhere('report_duty_patients.death_date', '>', $end);
|
|
});
|
|
},
|
|
'DECEASED' => function ($query, $start, $end) {
|
|
$query->whereBetween('report_duty_patients.death_date', [$start, $end]);
|
|
},
|
|
'SURGICAL_PLAN' => function ($query, $start, $end) {
|
|
$query->whereHas('operations', function ($q) use ($start, $end) {
|
|
$q->whereBetween('surgical_operations.Date', [$start, $end])
|
|
->where('surgical_operations.type', 'plan');
|
|
});
|
|
},
|
|
'SURGICAL_EMERGENCY' => function ($query, $start, $end) {
|
|
$query->whereHas('operations', function ($q) use ($start, $end) {
|
|
$q->whereBetween('surgical_operations.Date', [$start, $end])
|
|
->where('surgical_operations.type', 'emergency');
|
|
});
|
|
},
|
|
// ... остальные
|
|
];
|
|
|
|
return $types[$type];
|
|
}
|
|
}
|