Files
onboard/app/Http/Controllers/Api/ReportController.php
brusnitsyn 10fb138c30 * работа над функционалом автоматического заполнения
* исправил фантомный сдвиг даты
* переделал получение ФИО врачей из отделений
* добавил возможность поиска врача
* переписал сохранение отчета
2026-02-05 17:11:43 +09:00

969 lines
35 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\Http\Resources\Mis\FormattedPatientResource;
use App\Models\MedicalHistorySnapshot;
use App\Models\MetrikaGroup;
use App\Models\MetrikaResult;
use App\Models\MisLpuDoctor;
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 App\Models\User;
use App\Services\DateRangeService;
use App\Services\MisPatientService;
use App\Services\ReportService;
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 __construct(
protected MisPatientService $misPatientService,
protected ReportService $reportService,
protected DateRangeService $dateRangeService)
{ }
public function index(Request $request)
{
$user = Auth::user();
$department = $user->department;
$startDateCarbon = Carbon::now()->firstOfMonth();
$endDateCarbon = Carbon::now();
// Определяем даты в зависимости от роли
[$startDate, $endDate] = $this->dateService->getDateRangeForUser($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');
}
$reportIds = [];
$reports = $this->getReportsForDateRange($user->rf_department_id, $startDate, $endDate);
$reportIds = $reports->pluck('report_id')->toArray();
// Определяем, используем ли мы снапшоты
$reportToday = Report::whereDate('sent_at', $endDate)
->whereDate('created_at', $endDate)
->first();
$useSnapshots = ($user->isAdmin() || $user->isHeadOfDepartment()) || (Carbon::parse($endDate)->isToday() === false || $reportToday);
if ($useSnapshots && ($user->isHeadOfDepartment() || $user->isAdmin())) {
$report = Report::whereDate('sent_at', $endDate)
->where('rf_department_id', $department->department_id)
->first();
$fillableUserId = $report->rf_lpudoctor_id ?? null;
} else {
$fillableUserId = $request->query('userId', $user->rf_lpudoctor_id);
}
$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)
->whereDate('created_at', $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();
// Получаем статистику в зависимости от источника данных
if ($useSnapshots || $reportToday) {
// Используем снапшоты для статистики
// $plan = $this->getCountFromSnapshots('plan', $reportIds);
// $emergency = $this->getCountFromSnapshots('emergency', $reportIds);
$recipientCount = $this->getPatientsCountFromSnapshot('recipient', $reportIds);
$outcomeCount = $this->getPatientsCountFromSnapshot('outcome', $reportIds);
$currentCount = $this->getPatientsCountFromSnapshot('current', $reportIds);
$deadCount = $this->getPatientsCountFromSnapshot('deceased', $reportIds);
// Для операций все равно используем реплику с фильтрацией по датам
$surgicalCount = [
$this->getSurgicalPatientsFromSnapshot('plan', $reportIds),
$this->getSurgicalPatientsFromSnapshot('emergency', $reportIds)
];
$recipientIds = $this->getRecipientIdsFromSnapshots($reportIds);
} else {
// Используем реплику для статистики
$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);
$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 = $this->getPlanOrEmergencyPatients(
null,
$isHeadOrAdmin,
$branchId,
$startDate,
$endDate,
false,
true,
true,
today: true
);
}
$isActiveSendButton = Carbon::createFromFormat('Y-m-d H:i:s', $endDate)->isToday() &&
(!$user->isHeadOfDepartment() && !$user->isAdmin()) && $reportToday == null;
$reportDoctor = $reportToday?->lpuDoctor;
$message = null;
if ($reportToday) {
if ($reportDoctor && $reportDoctor->LPUDoctorID === intval($fillableUserId)) {
$isActiveSendButton = true;
} else {
$message = "Отчет уже создан пользователем: $reportDoctor->FAM_V $reportDoctor->IM_V $reportDoctor->OT_V";
}
$lpuDoctor = $reportDoctor;
} else {
if (Carbon::parse($startDate)->diffInDays(Carbon::parse($endDate)) > 1.0) {
$lpuDoctor = null;
} else {
$lpuDoctor = MisLpuDoctor::where('LPUDoctorID', $fillableUserId)->first();
}
}
$isRangeOneDay = $this->dateRangeService->isRangeOneDay($startDate, $endDate);
$date = $isHeadOrAdmin ? [
$this->dateRangeService->parseDate($isRangeOneDay ? $endDate : $startDate)->getTimestampMs(),
$this->dateRangeService->parseDate($endDate)->getTimestampMs()
] : $this->dateRangeService->parseDate($endDate)->getTimestampMs();
return response()->json([
'department' => [
'beds' => $beds,
'percentLoadedBeds' => $percentLoadedBeds,
'recipientCount' => $useSnapshots ? $recipientCount : $plan + $emergency, //$recipientCount,
'extractCount' => $outcomeCount, //$extractedCount,
'currentCount' => $currentCount,
'deadCount' => $deadCount,
'surgicalCount' => $surgicalCount,
'recipientIds' => $recipientIds,
],
'dates' => [
'startAt' => $startDateCarbon->getTimestampMs(),
'endAt' => $endDateCarbon->getTimestampMs()
],
'report' => [
'report_id' => $reportToday?->report_id,
'unwantedEvents' => $unwantedEvents,
'isActiveSendButton' => $isActiveSendButton,
'message' => $message,
'isOneDay' => $isRangeOneDay,
'isHeadOrAdmin' => $isHeadOrAdmin,
'dates' => $date
],
'metrikaItems' => $metrikaItems,
'userId' => $fillableUserId,
'userName' => $lpuDoctor ? "$lpuDoctor->FAM_V $lpuDoctor->IM_V $lpuDoctor->OT_V" : null
]);
}
private function getSurgicalPatientsFromSnapshot(string $type, array $reportIds)
{
$count = 0;
switch ($type) {
case 'emergency':
$count = $this->getMetrikaResult(10, $reportIds);
break;
case 'plan':
$count = $this->getMetrikaResult(11, $reportIds);
break;
case 'recipient':
$count = $this->getMetrikaResult(3, $reportIds);
break;
}
return $count;
}
private function getPatientsCountFromSnapshot(string $type, array $reportIds)
{
$count = 0;
switch ($type) {
case 'emergency':
$count = $this->getMetrikaResult(10, $reportIds);
break;
case 'plan':
$count = $this->getMetrikaResult(11, $reportIds);
break;
case 'recipient':
$count = $this->getMetrikaResult(3, $reportIds);
break;
case 'outcome':
$count = $this->getMetrikaResult(7, $reportIds);
break;
case 'deceased':
$count = $this->getMetrikaResult(9, $reportIds);
break;
case 'current':
$count = $this->getMetrikaResult(8, $reportIds);
break;
}
return $count;
}
private function getMetrikaResult(int $metrikaItemId, array $reportIds)
{
$reports = Report::whereIn('report_id', $reportIds)
->with('metrikaResults')
->get();
$count = 0;
foreach ($reports as $report) {
foreach ($report->metrikaResults as $metrikaResult) {
if ($metrikaResult->rf_metrika_item_id === $metrikaItemId)
$count += intval($metrikaResult->value) ?? 0;
}
}
return $count;
}
/**
* Получить ID поступивших пациентов из снапшотов
*/
private function getRecipientIdsFromSnapshots(array $reportIds)
{
$recipientIds = MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds)
->where('patient_type', 'recipient')
->pluck('rf_medicalhistory_id')
->unique()
->toArray();
return $recipientIds;
}
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',
'startAt' => 'required|integer',
'endAt' => 'required|integer',
'userId' => 'required|integer',
'reportId' => 'nullable'
]);
$metrics = $data['metrics'];
$observationPatients = $data['observationPatients'];
$unwantedEvents = $data['unwantedEvents'];
// Определяем даты в зависимости от роли
$dateRange = $this->dateRangeService->getDateRangeFromRequest($request, $user);
$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;
}
// 1. Плановые
$planIds = $this->reportService->getPatientsByStatus(
$user,
'plan',
$dateRange,
true,
true,
);
$planCount = $this->reportService->getPatientsCountByStatus($user, 'plan', $dateRange);
// 2. Экстренные
$emergencyIds = $this->reportService->getPatientsByStatus(
$user,
'emergency',
$dateRange,
true,
true,
);
$emergencyCount = $this->reportService->getPatientsCountByStatus($user, 'emergency', $dateRange);
// 3. Выписанные
$dischargedIds = $this->reportService->getPatientsByStatus(
$user,
'outcome',
$dateRange,
true,
true
);
// 4. Переведенные
$transferredIds = $this->reportService->getPatientsByStatus(
$user,
'outcome-transferred',
$dateRange,
true,
true
);
// 5. Умершие
$deceasedIds = $this->reportService->getPatientsByStatus(
$user,
'outcome-deceased',
$dateRange,
true,
true
);
// 6. Поступившие
$recipientIds = $this->reportService->getPatientsByStatus(
$user,
'recipient',
$dateRange,
true,
true
);
\DB::beginTransaction();
if (isset($data['reportId']) && $data['reportId']) {
$report = Report::updateOrCreate(
[
'report_id' => $data['reportId']
],
[
'rf_department_id' => $data['departmentId'],
'rf_user_id' => Auth::user()->id,
'rf_lpudoctor_id' => $data['userId'],
'created_at' => now(),
'sent_at' => now()
]
);
} else {
$report = Report::create([
'rf_department_id' => $data['departmentId'],
'rf_user_id' => Auth::user()->id,
'rf_lpudoctor_id' => $data['userId'],
'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,
]);
}
}
} else {
$unwantedEvents = $report->unwantedEvents;
foreach ($unwantedEvents as $unwantedEvent) {
$unwantedEvent->delete();
}
}
MetrikaResult::updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 16
],
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 16,
'value' => count($unwantedEvents),
]
);
foreach ($metriks as $metrika) {
MetrikaResult::updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => $metrika->rf_metrika_item_id
],
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => $metrika->rf_metrika_item_id,
'value' => $metrika->value,
]
);
}
if (count($observationPatients)) {
foreach ($observationPatients as $observationPatient) {
ObservationPatient::updateOrCreate(
[
'rf_medicalhistory_id' => $observationPatient['id'],
'rf_department_id' => $data['departmentId']
],
[
'rf_department_id' => $data['departmentId'],
'rf_report_id' => $report->report_id,
'rf_medicalhistory_id' => $observationPatient['id'],
'rf_mkab_id' => null,
'comment' => $observationPatient['comment'] ?? null
]
);
}
} else {
foreach ($report->observationPatients as $observationPatient) {
$observationPatient->delete();
}
}
MetrikaResult::updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 14
],
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 14,
'value' => count($observationPatients),
]
);
// Сохраняем снимок для каждого типа пациентов
// Планово
//$this->getPlanOrEmergencyPatients('plan', false, $branchId, $dateRange->startSql(), $dateRange->endSql(), false, false, true);
foreach ($planIds as $id) {
MedicalHistorySnapshot::create([
'rf_report_id' => $report->report_id,
'rf_medicalhistory_id' => $id,
'patient_type' => 'plan'
]);
}
MetrikaResult::updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 4
],
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 4,
'value' => $planCount,
]
);
//$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'
]);
}
MetrikaResult::updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 12
],
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 12,
'value' => $emergencyCount,
]
);
//$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'
]);
}
MetrikaResult::updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 15,
],
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 15,
'value' => count($dischargedIds),
]
);
//$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'
]);
}
MetrikaResult::updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 13,
],
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 13,
'value' => count($transferredIds),
]
);
//$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'
]);
}
MetrikaResult::updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 9,
],
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 9,
'value' => count($deceasedIds),
]
);
// $recipientIds = $this->getPlanOrEmergencyPatients(
// null,
// $isHeadOrAdmin,
// $branchId,
// $startDate,
// $endDate,
// false,
// true,
// true,
// today: true
// );
foreach ($recipientIds as $id) {
MedicalHistorySnapshot::create([
'rf_report_id' => $report->report_id,
'rf_medicalhistory_id' => $id,
'patient_type' => 'recipient'
]);
}
MetrikaResult::updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 3,
],
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => 3,
'value' => count($recipientIds),
]
);
// 7. Находящиеся на лечении
// $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();
$validated = $request->validate([
'status' => 'required|string',
'startAt' => 'nullable',
'endAt' => 'nullable',
]);
$dateRange = $this->dateRangeService->getDateRangeFromRequest($request, $user);
$patients = $this->reportService->getPatientsByStatus(
Auth::user(),
$validated['status'],
$dateRange
);
return response()->json(FormattedPatientResource::collection($patients));
}
public function getPatientsCount(Request $request)
{
$user = Auth::user();
$validated = $request->validate([
'status' => 'required|string',
'startAt' => 'nullable',
'endAt' => 'nullable',
]);
$dateRange = $this->dateRangeService->getDateRangeFromRequest($request, $user);
$count = $this->reportService->getPatientsCountByStatus(
Auth::user(),
$validated['status'],
$dateRange,
);
return response()->json($count);
}
/**
* Получить пациентов (плановых или экстренных)
*/
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 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 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);
}
public function getDepartmentUsers(Request $request)
{
$user = Auth::user();
$departmentId = $user->department->rf_mis_department_id;
$users = MisLpuDoctor::select(['LPUDoctorID', 'FAM_V', 'IM_V', 'OT_V'])
->whereHas('prvds', function ($query) use ($departmentId) {
$query->where('rf_DepartmentID', $departmentId)
->whereDate('D_END', '2222-01-01 00:00:00.000000');
})
->active()
->whereNotIn('LPUDoctorID', [0, 1])
->get();
return response()->json([
...$users
])->setStatusCode(200);
}
/**
* Получить все отчеты в промежутке дат (для агрегации данных)
*/
private function getReportsForDateRange($departmentId, $startDate, $endDate)
{
if (Carbon::parse($startDate)->diffInDays(Carbon::parse($endDate)) > 1.0)
return Report::where('rf_department_id', $departmentId)
->whereBetween('created_at', [$startDate, $endDate])
->orderBy('created_at', 'ASC')
->get();
else
return Report::where('rf_department_id', $departmentId)
->whereDate('created_at', $endDate)
->orderBy('created_at', 'ASC')
->get();
}
}