* добавил получение выбывших * фильтрация выбывших по результатам лечения * добавил подсказку при наведении на операции * добавил вывод причины наблюдения * добавил вкладки для выбывших * изменил связь и сохранение пациентов на контроле * добавил возможность редактирования причины контроля * полное изменение окна с нежелательными событиями * исправил просмотр причины контроля * работа над окном редактирования причины контроля в таблице * визуальное выделение умерших и проведенных операций * добавил выбор даты для роли врач * центрирование блоков статистики * разделение выполненных операций на срочность * поправил метод определения текущего дня для роли врач * функция блокировки при выборе другой даты для роли врач
808 lines
31 KiB
PHP
808 lines
31 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Api;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use App\Http\Resources\Mis\FormattedPatientResource;
|
||
use App\Models\MedicalHistorySnapshot;
|
||
use App\Models\MetrikaGroup;
|
||
use App\Models\MetrikaResult;
|
||
use App\Models\MisMedicalHistory;
|
||
use App\Models\MisMigrationPatient;
|
||
use App\Models\MisStationarBranch;
|
||
use App\Models\MisSurgicalOperation;
|
||
use App\Models\ObservationPatient;
|
||
use App\Models\Report;
|
||
use App\Models\UnwantedEvent;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Support\Carbon;
|
||
use Illuminate\Support\Facades\Auth;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Illuminate\Support\Facades\Session;
|
||
use Illuminate\Support\Str;
|
||
use Inertia\Inertia;
|
||
|
||
class ReportController extends Controller
|
||
{
|
||
public function index(Request $request)
|
||
{
|
||
$user = Auth::user();
|
||
$department = $user->department;
|
||
|
||
$startDateCarbon = Carbon::now()->firstOfMonth();
|
||
$endDateCarbon = Carbon::now();
|
||
|
||
// Определяем даты в зависимости от роли
|
||
[$startDate, $endDate] = $this->getDateRangeForRole($user, $request->query('startAt'), $request->query('endAt'));
|
||
if (Carbon::parse($startDate)->isValid()) {
|
||
$startDateCarbon = Carbon::parse($startDate)->setTimeZone('Asia/Yakutsk');
|
||
}
|
||
if (Carbon::parse($endDate)->isValid()) {
|
||
$endDateCarbon = Carbon::parse($endDate)->setTimeZone('Asia/Yakutsk');
|
||
}
|
||
|
||
$beds = (int)$department->metrikaDefault()->where('rf_metrika_item_id', 1)->first()->value;
|
||
$occupiedBeds = optional(Report::where('rf_department_id', $user->rf_department_id)
|
||
->join('metrika_results', 'reports.report_id', '=', 'metrika_results.rf_report_id')
|
||
->where('metrika_results.rf_metrika_item_id', 8)
|
||
->orderBy('sent_at', 'desc')->first())->value ?? 0;
|
||
|
||
$percentLoadedBeds = round(intval($occupiedBeds) * 100 / $beds); //intval($occupiedBeds) * 100 / $beds;
|
||
|
||
$metrikaGroup = MetrikaGroup::whereMetrikaGroupId(2)->first();
|
||
$metrikaItems = $metrikaGroup->metrikaItems;
|
||
|
||
$misDepartmentId = $request->user()->department->rf_mis_department_id;
|
||
|
||
$branchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)
|
||
->value('StationarBranchID');
|
||
|
||
$unwantedEvents = UnwantedEvent::whereHas('report', function ($query) use ($user, $startDate, $endDate) {
|
||
$query->where('rf_department_id', $user->rf_department_id)
|
||
->whereBetween('created_at', [$startDate, $endDate]);
|
||
})
|
||
->get()->map(function ($item) {
|
||
return [
|
||
...$item->toArray(),
|
||
'created_at' => Carbon::parse($item->created_at)->format('Создано d.m.Y в H:i'),
|
||
];
|
||
});
|
||
|
||
// Определяем, является ли пользователь заведующим/администратором
|
||
$isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin();
|
||
|
||
$plan = $this->getPlanOrEmergencyPatients(
|
||
'plan',
|
||
$isHeadOrAdmin,
|
||
$branchId,
|
||
$startDate,
|
||
$endDate,
|
||
true,
|
||
today: true
|
||
);
|
||
$emergency = $this->getPlanOrEmergencyPatients(
|
||
'emergency',
|
||
$isHeadOrAdmin,
|
||
$branchId,
|
||
$startDate,
|
||
$endDate,
|
||
true,
|
||
today: true
|
||
);
|
||
$outcomeCount = $this->getAllOutcomePatients(
|
||
$branchId,
|
||
$startDate,
|
||
$endDate,
|
||
true
|
||
);
|
||
$currentCount = $this->getCurrentPatients($branchId, true);
|
||
|
||
$recipientIds = $this->getPlanOrEmergencyPatients(
|
||
null,
|
||
$isHeadOrAdmin,
|
||
$branchId,
|
||
$startDate,
|
||
$endDate,
|
||
false,
|
||
true,
|
||
true,
|
||
today: true
|
||
);
|
||
|
||
return response()->json([
|
||
'department' => [
|
||
'beds' => $beds,
|
||
'percentLoadedBeds' => $percentLoadedBeds,
|
||
|
||
'recipientCount' => $plan + $emergency, //$recipientCount,
|
||
'extractCount' => $outcomeCount, //$extractedCount,
|
||
'currentCount' => $currentCount,
|
||
'deadCount' => $this->getDeceasedOutcomePatients($branchId, $startDate, $endDate, true),
|
||
'surgicalCount' => [
|
||
$this->getSurgicalPatients('plan', $isHeadOrAdmin, $branchId, $startDate, $endDate, true),
|
||
$this->getSurgicalPatients('emergency', $isHeadOrAdmin, $branchId, $startDate, $endDate, true)
|
||
],
|
||
'recipientIds' => $recipientIds,
|
||
],
|
||
'dates' => [
|
||
'startAt' => $startDateCarbon->getTimestampMs(),
|
||
'endAt' => $endDateCarbon->getTimestampMs()
|
||
],
|
||
'report' => [
|
||
'unwantedEvents' => $unwantedEvents,
|
||
'isActiveSendButton' => Carbon::createFromFormat('Y-m-d H:i:s', $endDate)->isToday() && (!$user->isHeadOfDepartment() && !$user->isAdmin()),
|
||
],
|
||
'metrikaItems' => $metrikaItems
|
||
]);
|
||
}
|
||
|
||
public function store(Request $request)
|
||
{
|
||
$user = Auth::user();
|
||
$misDepartmentId = $user->department->rf_mis_department_id;
|
||
|
||
$branchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)
|
||
->value('StationarBranchID');
|
||
|
||
// Определяем, является ли пользователь заведующим/администратором
|
||
$isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin();
|
||
|
||
$data = $request->validate([
|
||
'metrics' => 'required',
|
||
'observationPatients' => 'nullable',
|
||
'departmentId' => 'required|integer',
|
||
'unwantedEvents' => 'nullable|array',
|
||
'dates' => 'required|array',
|
||
]);
|
||
$metrics = $data['metrics'];
|
||
$observationPatients = $data['observationPatients'];
|
||
$unwantedEvents = $data['unwantedEvents'];
|
||
|
||
// Определяем даты в зависимости от роли
|
||
[$startDate, $endDate] = $this->getDateRangeForRole($user, $data['dates'][0], $data['dates'][1]);
|
||
|
||
$metriks = [];
|
||
foreach ($metrics as $key => $value) {
|
||
$metrika = new MetrikaResult;
|
||
$metrikaId = (int)Str::replace('metrika_item_', '', $key);
|
||
$metrika->rf_metrika_item_id = $metrikaId;
|
||
$metrika->value = $value;
|
||
|
||
$metriks[] = $metrika;
|
||
}
|
||
|
||
\DB::beginTransaction();
|
||
|
||
$report = Report::create([
|
||
'rf_department_id' => $data['departmentId'],
|
||
'rf_user_id' => Auth::user()->id,
|
||
'created_at' => now(),
|
||
'sent_at' => now()
|
||
]);
|
||
|
||
if (count($unwantedEvents)) {
|
||
foreach ($unwantedEvents as $unwantedEvent) {
|
||
// Если есть ID - ищем по нему
|
||
if (isset($unwantedEvent['unwanted_event_id']) && $unwantedEvent['unwanted_event_id']) {
|
||
UnwantedEvent::updateOrCreate(
|
||
['unwanted_event_id' => $unwantedEvent['unwanted_event_id']],
|
||
[
|
||
'rf_report_id' => $report->report_id,
|
||
'comment' => $unwantedEvent['comment'] ?? '',
|
||
'title' => $unwantedEvent['title'] ?? '',
|
||
'is_visible' => $unwantedEvent['is_visible'] ?? true,
|
||
]
|
||
);
|
||
} else {
|
||
// Если нет ID - создаем новую запись
|
||
UnwantedEvent::create([
|
||
'rf_report_id' => $report->report_id,
|
||
'comment' => $unwantedEvent['comment'] ?? '',
|
||
'title' => $unwantedEvent['title'] ?? '',
|
||
'is_visible' => $unwantedEvent['is_visible'] ?? true,
|
||
]);
|
||
}
|
||
}
|
||
}
|
||
|
||
foreach ($metriks as $metrika) {
|
||
$metrika->rf_report_id = $report->report_id;
|
||
$metrika->save();
|
||
}
|
||
|
||
foreach ($observationPatients as $observationPatient) {
|
||
ObservationPatient::create([
|
||
'rf_department_id' => $data['departmentId'],
|
||
'rf_report_id' => $report->report_id,
|
||
'rf_medicalhistory_id' => $observationPatient['id'],
|
||
'rf_mkab_id' => null,
|
||
'comment' => $observationPatient['comment'] ?? null
|
||
]);
|
||
}
|
||
|
||
// Сохраняем снимок для каждого типа пациентов
|
||
|
||
// 1. Плановые
|
||
$planIds = $this->getPlanOrEmergencyPatients('plan', false, $branchId, $startDate, $endDate, false, false, true);
|
||
foreach ($planIds as $id) {
|
||
MedicalHistorySnapshot::create([
|
||
'rf_report_id' => $report->report_id,
|
||
'rf_medicalhistory_id' => $id,
|
||
'patient_type' => 'plan'
|
||
]);
|
||
}
|
||
|
||
// 2. Экстренные
|
||
$emergencyIds = $this->getPlanOrEmergencyPatients('emergency', false, $branchId, $startDate, $endDate, false, false, true);
|
||
foreach ($emergencyIds as $id) {
|
||
MedicalHistorySnapshot::create([
|
||
'rf_report_id' => $report->report_id,
|
||
'rf_medicalhistory_id' => $id,
|
||
'patient_type' => 'emergency'
|
||
]);
|
||
}
|
||
|
||
// 3. Выписанные
|
||
$dischargedIds = $this->getDischargedPatients($branchId, $startDate, $endDate, true);
|
||
foreach ($dischargedIds as $id) {
|
||
MedicalHistorySnapshot::create([
|
||
'rf_report_id' => $report->report_id,
|
||
'rf_medicalhistory_id' => $id,
|
||
'patient_type' => 'discharged'
|
||
]);
|
||
}
|
||
|
||
// 4. Переведенные
|
||
$transferredIds = $this->getTransferredPatients($branchId, $startDate, $endDate, true);
|
||
foreach ($transferredIds as $id) {
|
||
MedicalHistorySnapshot::create([
|
||
'rf_report_id' => $report->report_id,
|
||
'rf_medicalhistory_id' => $id,
|
||
'patient_type' => 'transferred'
|
||
]);
|
||
}
|
||
|
||
// 5. Умершие
|
||
$deceasedIds = $this->getDeceasedOutcomePatients($branchId, $startDate, $endDate, false, true);
|
||
foreach ($deceasedIds as $id) {
|
||
MedicalHistorySnapshot::create([
|
||
'rf_report_id' => $report->report_id,
|
||
'rf_medicalhistory_id' => $id,
|
||
'patient_type' => 'deceased'
|
||
]);
|
||
}
|
||
|
||
// 6. Находящиеся на лечении
|
||
// $currentIds = $this->getCurrentPatients($branchId, false, true);
|
||
// foreach ($currentIds as $id) {
|
||
// MedicalHistorySnapshot::create([
|
||
// 'rf_report_id' => $report->report_id,
|
||
// 'rf_medicalhistory_id' => $id,
|
||
// 'patient_type' => 'current'
|
||
// ]);
|
||
// }
|
||
|
||
\DB::commit();
|
||
|
||
return response()->json([
|
||
'message' => 'success'
|
||
]);
|
||
}
|
||
|
||
public function getPatients(Request $request)
|
||
{
|
||
$user = Auth::user();
|
||
$data = $request->validate([
|
||
'status' => 'required|string', // plan emergency observation deceased
|
||
'startAt' => 'nullable',
|
||
'endAt' => 'nullable',
|
||
]);
|
||
|
||
// Получаем базовые данные
|
||
$status = $data['status'];
|
||
$model = new MisMedicalHistory();
|
||
$misDepartmentId = $request->user()->department->rf_mis_department_id;
|
||
$userDepartmentId = $request->user()->department->department_id;
|
||
$branchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)->value('StationarBranchID');
|
||
|
||
if (!$branchId) {
|
||
return response()->json([]);
|
||
}
|
||
|
||
// Определяем даты в зависимости от роли
|
||
[$startDate, $endDate] = $this->getDateRangeForRole($user, $data['startAt'] ?? null, $data['endAt'] ?? null);
|
||
|
||
// dd($startDate, $endDate);
|
||
|
||
// Определяем, является ли пользователь заведующим/администратором
|
||
$isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin();
|
||
|
||
// Обработка каждого статуса
|
||
$patients = match($status) {
|
||
'plan', 'emergency' => $this->getPlanOrEmergencyPatients($status, $isHeadOrAdmin, $branchId, $startDate, $endDate),
|
||
'observation' => $this->getObservationPatients($userDepartmentId),
|
||
'outcome-discharged' => $this->getDischargedPatients($branchId, $startDate, $endDate),
|
||
'outcome-transferred' => $this->getTransferredPatients($branchId, $startDate, $endDate),
|
||
'outcome-deceased' => $this->getDeceasedOutcomePatients($branchId, $startDate, $endDate),
|
||
default => 0
|
||
};
|
||
|
||
// dd($patients->pluck('MedicalHistoryID')->toArray());
|
||
|
||
// Если есть пациенты, добавляем дополнительные данные
|
||
if ($patients->isNotEmpty()) {
|
||
$patients = $patients->map(function ($item, $index) use ($branchId, $startDate, $endDate) {
|
||
$item->num = $index + 1;
|
||
$item->misStationarBranchId = $branchId;
|
||
$item->startDate = $startDate;
|
||
$item->endDate = $endDate;
|
||
return $item;
|
||
});
|
||
|
||
// Загружаем связи
|
||
$patients->load(['migrations' => function ($query) use ($startDate, $endDate, $branchId) {
|
||
$query->whereHas('diagnosis', function ($q) {
|
||
$q->where('rf_DiagnosTypeID', 3);
|
||
})
|
||
->with('diagnosis.mkb')
|
||
->where('rf_StationarBranchID', $branchId);
|
||
}]);
|
||
}
|
||
|
||
return response()->json(FormattedPatientResource::collection($patients));
|
||
}
|
||
|
||
public function getPatientsCount(Request $request)
|
||
{
|
||
$user = Auth::user();
|
||
$data = $request->validate([
|
||
'status' => 'required|string', // plan emergency observation deceased
|
||
'startAt' => 'nullable',
|
||
'endAt' => 'nullable',
|
||
]);
|
||
|
||
// Получаем базовые данные
|
||
$status = $data['status'];
|
||
$model = new MisMedicalHistory();
|
||
$misDepartmentId = $request->user()->department->rf_mis_department_id;
|
||
$userDepartmentId = $request->user()->department->department_id;
|
||
$branchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)->value('StationarBranchID');
|
||
|
||
if (!$branchId) {
|
||
return response()->json([]);
|
||
}
|
||
|
||
// Определяем даты в зависимости от роли
|
||
[$startDate, $endDate] = $this->getDateRangeForRole($user, $data['startAt'] ?? null, $data['endAt'] ?? null);
|
||
|
||
// Определяем, является ли пользователь заведующим/администратором
|
||
$isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin();
|
||
|
||
$isOutcomeOrObservation = in_array($status, ['outcome', 'observation']);
|
||
if ($isOutcomeOrObservation)
|
||
{
|
||
switch ($status) {
|
||
case 'observation':
|
||
$count = ObservationPatient::where('rf_department_id', $userDepartmentId)->count();
|
||
break;
|
||
case 'outcome':
|
||
$count = $this->getAllOutcomePatients($branchId, $startDate, $endDate, true);
|
||
break;
|
||
}
|
||
} else {
|
||
$count = $this->getPlanOrEmergencyPatients($status, $isHeadOrAdmin, $branchId, $startDate, $endDate, true);
|
||
}
|
||
|
||
return response()->json($count);
|
||
}
|
||
|
||
public function getRecipientIds(bool $isHeadOrAdmin, $branchId, $startDate, $endDate) {
|
||
|
||
}
|
||
|
||
/**
|
||
* Определить диапазон дат в зависимости от роли
|
||
*/
|
||
private function getDateRangeForRole($user, $startAt = null, $endAt = null): array
|
||
{
|
||
// Функция для парсинга даты
|
||
$parseDate = function($dateInput) {
|
||
if (is_numeric($dateInput)) {
|
||
return Carbon::createFromTimestampMs($dateInput)
|
||
->setTimezone('Asia/Yakutsk');
|
||
}
|
||
return Carbon::parse($dateInput, 'Asia/Yakutsk');
|
||
};
|
||
|
||
// Если переданы обе даты (и заведующий, и врач могут выбрать даты)
|
||
if ($startAt && $endAt) {
|
||
$startDate = $parseDate($startAt);
|
||
$endDate = $parseDate($endAt);
|
||
|
||
// Если пользователь врач - всегда применяем правило "-1 день"
|
||
// if (!$user->isHeadOfDepartment() && !$user->isAdmin()) {
|
||
// // Для врача: endDate - выбранная дата, startDate - выбранная дата -1 день
|
||
// $startDate = $endDate->copy()->subDay();
|
||
// }
|
||
|
||
// Если даты одинаковые (выбран один день) или врач
|
||
// dd($startDate->isSameDay($endDate) || (!$user->isHeadOfDepartment() && !$user->isAdmin()))0
|
||
// dd($startDate->isCurrentDay());
|
||
if ($startDate->isSameDay($endDate)) {
|
||
// Сдвигаем начало на день назад для всех ролей при выборе одного дня
|
||
// И всегда для врача
|
||
$startDate = $startDate->copy()->addDays(-1)->setTime(6, 0)->format('Y-m-d H:i:s');
|
||
$endDate = $endDate->setTime(6, 0)->format('Y-m-d H:i:s');
|
||
} else {
|
||
// Для диапазона оставляем как есть (только для заведующих)
|
||
$startDate = $startDate->setTime(6, 0)->format('Y-m-d H:i:s');
|
||
$endDate = $endDate->setTime(6, 0)->format('Y-m-d H:i:s');
|
||
}
|
||
|
||
// dd($startDate);
|
||
|
||
// dd($startDate, $endDate);
|
||
}
|
||
// Если даты не переданы - логика по умолчанию в зависимости от роли
|
||
else {
|
||
// Для заведующего или администратора - период месяца
|
||
if ($user->isHeadOfDepartment() || $user->isAdmin()) {
|
||
$startDate = Carbon::now('Asia/Yakutsk')
|
||
->firstOfMonth()
|
||
->setTime(6, 0)
|
||
->format('Y-m-d H:i:s');
|
||
|
||
$endDate = Carbon::now('Asia/Yakutsk')
|
||
->setTime(6, 0)
|
||
->format('Y-m-d H:i:s');
|
||
}
|
||
// Для врача - только сутки (вчера 06:00 - сегодня 06:00)
|
||
else {
|
||
$startDate = Carbon::now('Asia/Yakutsk')->subDay()->setTime(6, 0)->format('Y-m-d H:i:s');
|
||
$endDate = Carbon::now('Asia/Yakutsk')->setTime(6, 0)->format('Y-m-d H:i:s');
|
||
}
|
||
}
|
||
|
||
return [$startDate, $endDate];
|
||
}
|
||
|
||
/**
|
||
* Получить пациентов (плановых или экстренных)
|
||
*/
|
||
private function getPlanOrEmergencyPatients(
|
||
?string $status,
|
||
bool $isHeadOrAdmin,
|
||
$branchId,
|
||
$startDate, $endDate,
|
||
bool $returnedCount = false,
|
||
bool $all = false,
|
||
bool $onlyIds = false,
|
||
bool $today = false
|
||
) {
|
||
// Определяем, является ли статус outcome
|
||
$isOutcomeStatus = in_array($status, ['outcome-transferred', 'outcome-discharged', 'outcome-deceased']);
|
||
|
||
if ($isOutcomeStatus) {
|
||
switch ($status) {
|
||
case 'outcome-transferred':
|
||
$query = MisMigrationPatient::transferred($branchId, $startDate, $endDate);
|
||
break;
|
||
case 'outcome-discharged':
|
||
$query = MisMigrationPatient::discharged($branchId, $startDate, $endDate);
|
||
break;
|
||
case 'outcome-deceased':
|
||
$query = MisMigrationPatient::deceasedOutcome($branchId, $startDate, $endDate);
|
||
break;
|
||
}
|
||
} else {
|
||
// Разная логика для заведующего и врача
|
||
if ($isHeadOrAdmin) {
|
||
// Заведующий: используем whereInDepartment
|
||
$query = MisMigrationPatient::whereInDepartment($branchId)
|
||
->whereBetween('DateIngoing', [$startDate, $endDate]);
|
||
} else {
|
||
// Врач: используем currentlyInTreatment + фильтр по дате
|
||
$query = MisMigrationPatient::currentlyInTreatment($branchId)
|
||
->when($today, function ($query) use ($startDate, $endDate) {
|
||
return $query->whereBetween('DateIngoing', [$startDate, $endDate]);
|
||
});
|
||
}
|
||
}
|
||
|
||
$medicalHistoryIds = $query->pluck('rf_MedicalHistoryID')->toArray();
|
||
|
||
if (empty($medicalHistoryIds)) {
|
||
if ($returnedCount) return 0;
|
||
return collect();
|
||
}
|
||
|
||
// Получаем истории
|
||
$query = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
|
||
->with(['surgicalOperations' => function ($query) use ($startDate, $endDate) {
|
||
$query->whereBetween('Date', [$startDate, $endDate]);
|
||
}])
|
||
->orderBy('DateRecipient', 'DESC');
|
||
|
||
// Выбираем план или экстренность
|
||
if (!$all && !$isOutcomeStatus) {
|
||
if ($status === 'plan') {
|
||
$query->plan();
|
||
} else if ($status === 'emergency') {
|
||
$query->emergency();
|
||
}
|
||
}
|
||
|
||
// Для врача добавляем условие "в отделении"
|
||
if (!$isHeadOrAdmin && !$isOutcomeStatus) {
|
||
$query->currentlyHospitalized();
|
||
}
|
||
|
||
if ($onlyIds) {
|
||
return $query->select('MedicalHistoryID')
|
||
->pluck('MedicalHistoryID')->values();
|
||
} else {
|
||
if ($returnedCount) return $query->count();
|
||
else return $query->get();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Получить пациентов под наблюдением
|
||
*/
|
||
private function getObservationPatients(
|
||
$userDepartmentId
|
||
) {
|
||
$observationPatients = ObservationPatient::where('rf_department_id', $userDepartmentId)
|
||
->select(['rf_medicalhistory_id', 'observation_patient_id'])
|
||
->get()
|
||
->groupBy('rf_medicalhistory_id');
|
||
|
||
$medicalHistoryIds = $observationPatients->keys()->toArray();
|
||
|
||
if (empty($medicalHistoryIds)) {
|
||
return collect();
|
||
}
|
||
|
||
$patients = MisMedicalHistory::whereHas('observationPatient', function ($q) use ($userDepartmentId) {
|
||
$q->where('rf_department_id', $userDepartmentId);
|
||
})
|
||
->with(['observationPatient' => function($query) use ($userDepartmentId) {
|
||
$query->where('rf_department_id', $userDepartmentId)
|
||
->select(['rf_medicalhistory_id', 'observation_patient_id', 'comment']);
|
||
}])
|
||
->orderBy('DateRecipient', 'DESC')
|
||
->get();
|
||
|
||
// Добавляем комментарии
|
||
$patients = $patients->map(function ($patient) {
|
||
// Объединяем все комментарии
|
||
$patient->comment = $patient->observationPatient
|
||
->pluck('comment')
|
||
->filter()
|
||
->implode('; ');
|
||
|
||
return $patient;
|
||
});
|
||
|
||
return $patients;
|
||
}
|
||
|
||
/**
|
||
* Получить выбывших пациентов
|
||
*/
|
||
private function getOutcomePatients(
|
||
$misDepartmentId,
|
||
$startDate,
|
||
$endDate
|
||
) {
|
||
// Здесь оставляем оригинальный запрос, т.к. он специфичен для умерших
|
||
return MisMedicalHistory::deceased()
|
||
->inDepartment($misDepartmentId, $startDate, $endDate)
|
||
->get();
|
||
}
|
||
|
||
/**
|
||
* Получить всех выбывших пациентов
|
||
*/
|
||
private function getAllOutcomePatients($branchId, $startDate, $endDate, bool $returnedCount = false)
|
||
{
|
||
// Сначала получаем миграции с типами выбытия
|
||
$migrations = MisMigrationPatient::outcomePatients($branchId, $startDate, $endDate)
|
||
->select('rf_MedicalHistoryID', 'rf_kl_VisitResultID', 'DateOut')
|
||
->get()
|
||
->groupBy('rf_MedicalHistoryID');
|
||
|
||
if ($migrations->isEmpty()) {
|
||
if ($returnedCount) return 0;
|
||
return collect();
|
||
}
|
||
|
||
$medicalHistoryIds = $migrations->keys()->toArray();
|
||
|
||
// Получаем истории
|
||
$patients = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
|
||
->with(['surgicalOperations'])
|
||
->orderBy('DateRecipient', 'DESC');
|
||
|
||
if ($returnedCount) return $patients->count();
|
||
else $patients = $patients->get();
|
||
|
||
// Добавляем информацию о типе выбытия
|
||
return $patients->map(function ($patient) use ($migrations) {
|
||
$patientMigrations = $migrations->get($patient->MedicalHistoryID, collect());
|
||
|
||
// Определяем основной тип выбытия (берем последнюю миграцию)
|
||
$latestMigration = $patientMigrations->sortByDesc('DateOut')->first();
|
||
|
||
if ($latestMigration) {
|
||
$patient->outcome_type = $this->getOutcomeTypeName($latestMigration->rf_kl_VisitResultID);
|
||
$patient->outcome_date = $latestMigration->DateOut;
|
||
$patient->visit_result_id = $latestMigration->rf_kl_VisitResultID;
|
||
}
|
||
|
||
return $patient;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Получить понятное название типа выбытия
|
||
*/
|
||
private function getOutcomeTypeName($visitResultId): string
|
||
{
|
||
return match($visitResultId) {
|
||
1, 7, 8, 9, 10, 11, 48, 49, 124 => 'Выписка',
|
||
2, 3, 4, 12, 13, 14 => 'Перевод',
|
||
5, 6, 15, 16 => 'Умер',
|
||
// Добавьте другие коды по мере необходимости
|
||
default => 'Другое (' . $visitResultId . ')'
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Получить выписанных пациентов
|
||
*/
|
||
private function getDischargedPatients($branchId, $startDate, $endDate, bool $onlyIds = false)
|
||
{
|
||
$medicalHistoryIds = MisMigrationPatient::discharged($branchId, $startDate, $endDate)
|
||
->pluck('rf_MedicalHistoryID')
|
||
->unique()
|
||
->toArray();
|
||
|
||
if (empty($medicalHistoryIds)) {
|
||
return collect();
|
||
}
|
||
|
||
if ($onlyIds) {
|
||
return $medicalHistoryIds;
|
||
}
|
||
|
||
return MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
|
||
->with(['surgicalOperations'])
|
||
->orderBy('DateRecipient', 'DESC')
|
||
->get();
|
||
}
|
||
|
||
/**
|
||
* Получить переведенных пациентов
|
||
*/
|
||
private function getTransferredPatients($branchId, $startDate, $endDate, bool $onlyIds = false)
|
||
{
|
||
$medicalHistoryIds = MisMigrationPatient::transferred($branchId, $startDate, $endDate)
|
||
->pluck('rf_MedicalHistoryID')
|
||
->unique()
|
||
->toArray();
|
||
|
||
if (empty($medicalHistoryIds)) {
|
||
return collect();
|
||
}
|
||
|
||
if ($onlyIds) {
|
||
return $medicalHistoryIds;
|
||
}
|
||
|
||
return MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
|
||
->with(['surgicalOperations'])
|
||
->orderBy('DateRecipient', 'DESC')
|
||
->get();
|
||
}
|
||
|
||
/**
|
||
* Получить умерших пациентов (исход)
|
||
*/
|
||
private function getDeceasedOutcomePatients($branchId, $startDate, $endDate, bool $returnedCount = false, bool $onlyIds = false)
|
||
{
|
||
$medicalHistoryIds = MisMigrationPatient::deceasedOutcome($branchId, $startDate, $endDate)
|
||
->pluck('rf_MedicalHistoryID')
|
||
->unique()
|
||
->toArray();
|
||
|
||
if (empty($medicalHistoryIds)) {
|
||
if ($returnedCount) return 0;
|
||
return collect();
|
||
}
|
||
|
||
if ($onlyIds) {
|
||
return $medicalHistoryIds;
|
||
}
|
||
|
||
$query = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
|
||
->with(['surgicalOperations'])
|
||
->orderBy('DateRecipient', 'DESC');
|
||
|
||
if ($returnedCount) return $query->count();
|
||
else return $query->get();
|
||
}
|
||
|
||
/**
|
||
* Получить пациентов с операциями
|
||
*/
|
||
private function getSurgicalPatients(string $status, bool $isHeadOrAdmin, $branchId, $startDate, $endDate, bool $returnedCount = false)
|
||
{
|
||
$query = MisSurgicalOperation::where('rf_StationarBranchID', $branchId)
|
||
->whereBetween('Date', [$startDate, $endDate])
|
||
->orderBy('Date', 'DESC');
|
||
|
||
if ($status === 'plan') {
|
||
$query->where('rf_TypeSurgOperationInTimeID', 6);
|
||
} else {
|
||
$query->whereIn('rf_TypeSurgOperationInTimeID', [4, 5]);
|
||
}
|
||
|
||
|
||
if ($returnedCount) return $query->count();
|
||
else return $query->get();
|
||
}
|
||
|
||
/**
|
||
* Находятся на лечении
|
||
*/
|
||
private function getCurrentPatients($branchId, bool $returnedCount = false, bool $onlyIds = false)
|
||
{
|
||
// $currentCount = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
|
||
// ->currentlyHospitalized()
|
||
// ->orderBy('DateRecipient', 'DESC')
|
||
// ->count();
|
||
$medicalHistoryIds = MisMigrationPatient::currentlyInTreatment($branchId)
|
||
->pluck('rf_MedicalHistoryID')
|
||
->unique()
|
||
->toArray();
|
||
|
||
if (empty($medicalHistoryIds)) {
|
||
if ($returnedCount) return 0;
|
||
return collect();
|
||
}
|
||
|
||
if ($onlyIds) return $medicalHistoryIds;
|
||
|
||
$patients = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
|
||
->currentlyHospitalized()
|
||
->with(['surgicalOperations'])
|
||
->orderBy('DateRecipient', 'DESC');
|
||
|
||
if ($returnedCount) return $patients->count();
|
||
else return $patients->get();
|
||
}
|
||
|
||
public function removeObservation(
|
||
Request $request,
|
||
) {
|
||
$data = $request->validate([
|
||
'id' => 'required'
|
||
]);
|
||
|
||
ObservationPatient::where('rf_medicalhistory_id', $data['id'])->delete();
|
||
|
||
return response()->json()->setStatusCode(200);
|
||
}
|
||
|
||
|
||
|
||
// api/report/unwanted-event
|
||
public function removeUnwantedEvent(UnwantedEvent $unwantedEvent, Request $request)
|
||
{
|
||
$unwantedEvent->delete();
|
||
|
||
return response()->json()->setStatusCode(200);
|
||
}
|
||
}
|