* блокировка изменения отчета для врача

* вывод данных из отчетов для ролей адм и зав
* поправил ширину стобцов ввода
* добавил календарь на страницу статистики
* переделал календарь у заведующего на странице отчета
* добавил и привязал метрики в статистику
This commit is contained in:
brusnitsyn
2026-02-03 17:03:37 +09:00
parent 2805e5e4bc
commit 9ee33bc517
20 changed files with 889 additions and 159 deletions

View File

@@ -16,6 +16,8 @@ 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 Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
@@ -26,6 +28,15 @@ use Inertia\Inertia;
class ReportController extends Controller
{
protected MisPatientService $misPatientService;
protected DateRangeService $dateService;
public function __construct(MisPatientService $misPatientService, DateRangeService $dateRangeService)
{
$this->misPatientService = $misPatientService;
$this->dateService = $dateRangeService;
}
public function index(Request $request)
{
$user = Auth::user();
@@ -35,7 +46,7 @@ class ReportController extends Controller
$endDateCarbon = Carbon::now();
// Определяем даты в зависимости от роли
[$startDate, $endDate] = $this->getDateRangeForRole($user, $request->query('startAt'), $request->query('endAt'));
[$startDate, $endDate] = $this->dateService->getDateRangeForUser($user, $request->query('startAt'), $request->query('endAt'));
if (Carbon::parse($startDate)->isValid()) {
$startDateCarbon = Carbon::parse($startDate)->setTimeZone('Asia/Yakutsk');
}
@@ -48,8 +59,11 @@ class ReportController extends Controller
$reportIds = $reports->pluck('report_id')->toArray();
// Определяем, используем ли мы снапшоты
$useSnapshots = ($user->isAdmin() || $user->isHeadOfDepartment()) || Carbon::parse($endDate)->isToday() === false;
if ($useSnapshots) {
$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();
@@ -58,12 +72,6 @@ class ReportController extends Controller
$fillableUserId = $request->query('userId', $user->rf_lpudoctor_id);
}
if (Carbon::parse($startDate)->diffInDays(Carbon::parse($endDate)) > 1.0) {
$lpuDoctor = null;
} else {
$lpuDoctor = MisLpuDoctor::where('LPUDoctorID', $fillableUserId)->first();
}
$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')
@@ -82,7 +90,7 @@ class ReportController extends Controller
$unwantedEvents = UnwantedEvent::whereHas('report', function ($query) use ($user, $startDate, $endDate) {
$query->where('rf_department_id', $user->rf_department_id)
->whereBetween('created_at', [$startDate, $endDate]);
->whereDate('created_at', $endDate);
})
->get()->map(function ($item) {
return [
@@ -95,18 +103,19 @@ class ReportController extends Controller
$isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin();
// Получаем статистику в зависимости от источника данных
if ($useSnapshots) {
if ($useSnapshots || $reportToday) {
// Используем снапшоты для статистики
$plan = $this->getCountFromSnapshots('plan', $reportIds);
$emergency = $this->getCountFromSnapshots('emergency', $reportIds);
$outcomeCount = $this->getCountFromSnapshots('outcome', $reportIds);
$currentCount = $this->getCurrentPatientsFromSnapshots($reportIds, $branchId);
$deadCount = $this->getCountFromSnapshots('deceased', $reportIds);
// $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->getSurgicalPatients('plan', $isHeadOrAdmin, $branchId, $startDate, $endDate, true),
$this->getSurgicalPatients('emergency', $isHeadOrAdmin, $branchId, $startDate, $endDate, true)
$this->getSurgicalPatientsFromSnapshot('plan', $reportIds),
$this->getSurgicalPatientsFromSnapshot('emergency', $reportIds)
];
$recipientIds = $this->getRecipientIdsFromSnapshots($reportIds);
@@ -157,12 +166,40 @@ class ReportController extends Controller
);
}
$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->dateService->isRangeOneDay($startDate, $endDate);
$date = $isHeadOrAdmin ? [
$this->dateService->parseDate($isRangeOneDay ? $endDate : $startDate)->getTimestampMs(),
$this->dateService->parseDate($endDate)->getTimestampMs()
] : $this->dateService->parseDate($endDate)->getTimestampMs();
return response()->json([
'department' => [
'beds' => $beds,
'percentLoadedBeds' => $percentLoadedBeds,
'recipientCount' => $plan + $emergency, //$recipientCount,
'recipientCount' => $useSnapshots ? $recipientCount : $plan + $emergency, //$recipientCount,
'extractCount' => $outcomeCount, //$extractedCount,
'currentCount' => $currentCount,
'deadCount' => $deadCount,
@@ -174,8 +211,13 @@ class ReportController extends Controller
'endAt' => $endDateCarbon->getTimestampMs()
],
'report' => [
'report_id' => $reportToday?->report_id,
'unwantedEvents' => $unwantedEvents,
'isActiveSendButton' => Carbon::createFromFormat('Y-m-d H:i:s', $endDate)->isToday() && (!$user->isHeadOfDepartment() && !$user->isAdmin()),
'isActiveSendButton' => $isActiveSendButton,
'message' => $message,
'isOneDay' => $isRangeOneDay,
'isHeadOrAdmin' => $isHeadOrAdmin,
'dates' => $date
],
'metrikaItems' => $metrikaItems,
'userId' => $fillableUserId,
@@ -183,6 +225,68 @@ class ReportController extends Controller
]);
}
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;
}
/**
* Получить количество пациентов из снапшотов
*/
@@ -213,6 +317,10 @@ class ReportController extends Controller
->where('patient_type', 'transferred')
->distinct('rf_medicalhistory_id')
->count('rf_medicalhistory_id'),
'recipient' => MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds)
->where('patient_type', 'recipient')
->distinct('rf_medicalhistory_id')
->count('rf_medicalhistory_id'),
default => 0
};
}
@@ -250,19 +358,13 @@ class ReportController extends Controller
*/
private function getRecipientIdsFromSnapshots(array $reportIds)
{
$planIds = MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds)
->where('patient_type', 'plan')
$recipientIds = MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds)
->where('patient_type', 'recipient')
->pluck('rf_medicalhistory_id')
->unique()
->toArray();
$emergencyIds = MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds)
->where('patient_type', 'emergency')
->pluck('rf_medicalhistory_id')
->unique()
->toArray();
return array_merge($planIds, $emergencyIds);
return $recipientIds;
}
// /**
@@ -310,6 +412,7 @@ class ReportController extends Controller
'unwantedEvents' => 'nullable|array',
'dates' => 'required|array',
'userId' => 'required|integer',
'reportId' => 'nullable'
]);
$metrics = $data['metrics'];
$observationPatients = $data['observationPatients'];
@@ -330,13 +433,28 @@ class ReportController extends Controller
\DB::beginTransaction();
$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 (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) {
@@ -361,11 +479,25 @@ class ReportController extends Controller
]);
}
}
} else {
$unwantedEvents = $report->unwantedEvents;
foreach ($unwantedEvents as $unwantedEvent) {
$unwantedEvent->delete();
}
}
foreach ($metriks as $metrika) {
$metrika->rf_report_id = $report->report_id;
$metrika->save();
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)) {
@@ -384,6 +516,10 @@ class ReportController extends Controller
]
);
}
} else {
foreach ($report->observationPatients as $observationPatient) {
$observationPatient->delete();
}
}
// Сохраняем снимок для каждого типа пациентов
@@ -438,6 +574,26 @@ class ReportController extends Controller
]);
}
// 5. Поступившие
$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'
]);
}
// 6. Находящиеся на лечении
// $currentIds = $this->getCurrentPatients($branchId, false, true);
// foreach ($currentIds as $id) {
@@ -1029,10 +1185,16 @@ class ReportController extends Controller
*/
private function getReportsForDateRange($departmentId, $startDate, $endDate)
{
return Report::where('rf_department_id', $departmentId)
->whereBetween('created_at', [$startDate, $endDate])
->orderBy('created_at', 'ASC')
->get();
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();
}
/**