* блокировка изменения отчета для врача
* вывод данных из отчетов для ролей адм и зав * поправил ширину стобцов ввода * добавил календарь на страницу статистики * переделал календарь у заведующего на странице отчета * добавил и привязал метрики в статистику
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,22 +3,118 @@
|
||||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\MisStationarBranch;
|
||||
use App\Models\Report;
|
||||
use App\Services\DateRangeService;
|
||||
use App\Services\MisPatientService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ReportController extends Controller
|
||||
{
|
||||
protected DateRangeService $dateService;
|
||||
protected MisPatientService $misPatientService;
|
||||
|
||||
public function __construct(MisPatientService $misPatientService, DateRangeService $dateRangeService)
|
||||
{
|
||||
$this->misPatientService = $misPatientService;
|
||||
$this->dateService = $dateRangeService;
|
||||
}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
$user = \Auth::user();
|
||||
$department = $user->department;
|
||||
|
||||
$beds = $department->metrikaDefault()->where('rf_metrika_item_id', 1)->first()->value;
|
||||
$queryStartDate = $request->query('startAt');
|
||||
$queryEndDate = $request->query('endAt');
|
||||
[$startDate, $endDate] = $this->dateService->getDateRangeForUser($user, $queryStartDate, $queryEndDate);
|
||||
$isRangeOneDay = $this->dateService->isRangeOneDay($startDate, $endDate);
|
||||
|
||||
// Если диапазон содержит сутки
|
||||
if ($isRangeOneDay) {
|
||||
// Устанавливаем дату отчета, как последний день из выборки
|
||||
$dateReport = $endDate;
|
||||
} else {
|
||||
// Устанавливаем дату отчета, как выборку
|
||||
$dateReport = [$startDate, $endDate];
|
||||
}
|
||||
|
||||
if ($isRangeOneDay) {
|
||||
// Статистика выводится с нарастающим числом
|
||||
$reports = $department->reports()
|
||||
->whereDate('created_at', $dateReport)
|
||||
->get();
|
||||
} else {
|
||||
$reports = $department->reports()
|
||||
->whereBetween('created_at', $dateReport)
|
||||
->get();
|
||||
}
|
||||
|
||||
$isReports = $reports->count() > 0;
|
||||
|
||||
$allCount = 0; $outcomeCount = 0; $currentCount = 0; $occupiedBeds = 0; $planCount = 0;
|
||||
$emergencyCount = 0; $planSurgical = 0; $emergencySurgical = 0; $transferredCount = 0;
|
||||
$deceasedCount = 0;
|
||||
if ($isReports) {
|
||||
foreach ($reports as $report) {
|
||||
$allCount += $this->getMetrikaResultFromReport($report, 3, $isRangeOneDay);
|
||||
$currentCount += $this->getMetrikaResultFromReport($report, 8, false);
|
||||
$occupiedBeds += $this->getMetrikaResultFromReport($report, 8, $isRangeOneDay);
|
||||
$planCount += $this->getMetrikaResultFromReport($report, 4, $isRangeOneDay);
|
||||
$emergencyCount += $this->getMetrikaResultFromReport($report, 12, $isRangeOneDay);
|
||||
$planSurgical += $this->getMetrikaResultFromReport($report, 11, $isRangeOneDay);
|
||||
$emergencySurgical += $this->getMetrikaResultFromReport($report, 10, $isRangeOneDay);
|
||||
$transferredCount += $this->getMetrikaResultFromReport($report, 13, $isRangeOneDay);
|
||||
$outcomeCount += $this->getMetrikaResultFromReport($report, 7, $isRangeOneDay);
|
||||
$deceasedCount += $this->getMetrikaResultFromReport($report, 9, $isRangeOneDay);
|
||||
}
|
||||
} else {
|
||||
$misDepartmentId = $request->user()->department->rf_mis_department_id;
|
||||
|
||||
$branchId = MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)
|
||||
->value('StationarBranchID');
|
||||
|
||||
$planCount = $this->misPatientService->getInStationarPatients('plan', $branchId, $dateReport)->count();
|
||||
}
|
||||
|
||||
$bedsCount = $department->metrikaDefault()
|
||||
->where('rf_metrika_item_id', 1)->value('value');
|
||||
|
||||
$percentLoadedBeds = $bedsCount > 0 ? round($occupiedBeds * 100 / $bedsCount) : 0;
|
||||
|
||||
return Inertia::render('Report/Index', [
|
||||
'department' => [
|
||||
'beds' => $beds
|
||||
'beds' => $bedsCount,
|
||||
'recipients' => [
|
||||
'all' => $allCount,
|
||||
'plan' => $planCount,
|
||||
'emergency' => $emergencyCount,
|
||||
'transferred' => $transferredCount,
|
||||
],
|
||||
'outcome' => $outcomeCount,
|
||||
'consist' => $currentCount,
|
||||
'percentLoadedBeds' => $percentLoadedBeds,
|
||||
'surgical' => [
|
||||
'plan' => $planSurgical,
|
||||
'emergency' => $emergencySurgical
|
||||
],
|
||||
'deceased' => $deceasedCount,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
private function getMetrikaResultFromReport(Report $report, int $metrikaItem, bool $sum = true)
|
||||
{
|
||||
if ($sum) {
|
||||
return (int) ($report->metrikaResults()
|
||||
->where('rf_metrika_item_id', $metrikaItem)
|
||||
->sum(DB::raw('CAST(value AS INTEGER)')) ?: 0);
|
||||
}
|
||||
|
||||
return (int) ($report->metrikaResults()
|
||||
->where('rf_metrika_item_id', $metrikaItem)
|
||||
->value('value') ?: 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use App\Models\MetrikaGroup;
|
||||
use App\Models\MetrikaItem;
|
||||
use App\Models\MetrikaResult;
|
||||
use App\Models\Report;
|
||||
use App\Services\DateRangeService;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
@@ -18,65 +19,141 @@ use Inertia\Inertia;
|
||||
|
||||
class StatisticController extends Controller
|
||||
{
|
||||
protected DateRangeService $dateService;
|
||||
|
||||
public function __construct(DateRangeService $dateRangeService)
|
||||
{
|
||||
$this->dateService = $dateRangeService;
|
||||
}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$userDepartment = $user->department;
|
||||
$queryStartDate = $request->query('startAt');
|
||||
$queryEndDate = $request->query('endAt');
|
||||
[$startDate, $endDate] = $this->dateService->getDateRangeForUser($user, $queryStartDate, $queryEndDate);
|
||||
$isRangeOneDay = $this->dateService->isRangeOneDay($startDate, $endDate);
|
||||
|
||||
$data = [];
|
||||
// Если диапазон содержит сутки
|
||||
if ($isRangeOneDay) {
|
||||
// Устанавливаем дату отчета, как последний день из выборки
|
||||
$dateReport = $endDate;
|
||||
} else {
|
||||
// Устанавливаем дату отчета, как выборку
|
||||
$dateReport = [$startDate, $endDate];
|
||||
}
|
||||
|
||||
$departments = Department::select('department_id', 'name_short')
|
||||
$groupedData = [];
|
||||
|
||||
$departments = Department::select('department_id', 'rf_department_type', 'name_short')
|
||||
->with(['reports'])
|
||||
->orderBy('name_short')->get();
|
||||
|
||||
foreach ($departments as $department) {
|
||||
$allCount = MetrikaResult::whereHas('report', function ($query) use ($userDepartment, $department) {
|
||||
$query->where('rf_department_id', $department->department_id);
|
||||
})->where('rf_metrika_item_id', 3)
|
||||
->sum(DB::raw('value::integer'));
|
||||
$departmentType = $department->departmentType->name_full;
|
||||
|
||||
$leaveCount = MetrikaResult::whereHas('report', function ($query) use ($userDepartment, $department) {
|
||||
$query->where('rf_department_id', $department->department_id);
|
||||
})->where('rf_metrika_item_id', 7)
|
||||
->sum(DB::raw('value::integer'));
|
||||
if (!isset($groupedData[$departmentType])) {
|
||||
$groupedData[$departmentType] = [];
|
||||
}
|
||||
|
||||
$consistCount = optional(MetrikaResult::where('rf_metrika_item_id', 8)
|
||||
->whereHas('report', function (Builder $query) use ($department) {
|
||||
$query->where('rf_department_id', $department->department_id);
|
||||
})->join('reports', 'metrika_results.rf_report_id', '=', 'reports.report_id')
|
||||
->select('metrika_results.value')
|
||||
->orderBy('reports.sent_at', 'desc')
|
||||
)->value('value') ?? 0;
|
||||
if ($isRangeOneDay) {
|
||||
// Статистика выводится с нарастающим числом
|
||||
$reports = $department->reports()
|
||||
->whereDate('created_at', $dateReport)
|
||||
->get();
|
||||
} else {
|
||||
$reports = $department->reports()
|
||||
->whereBetween('created_at', $dateReport)->get();
|
||||
}
|
||||
// Метрики зависищие от отчетов
|
||||
$allCount = 0; $outcomeCount = 0; $currentCount = 0; $occupiedBeds = 0; $planCount = 0;
|
||||
$emergencyCount = 0; $planSurgical = 0; $emergencySurgical = 0; $transferredCount = 0;
|
||||
$deceasedCount = 0;
|
||||
foreach ($reports as $report) {
|
||||
$allCount += $this->getMetrikaResultFromReport($report, 3, $isRangeOneDay);
|
||||
$currentCount += $this->getMetrikaResultFromReport($report, 8, false);
|
||||
$occupiedBeds += $this->getMetrikaResultFromReport($report, 8, $isRangeOneDay);
|
||||
$planCount += $this->getMetrikaResultFromReport($report, 4, $isRangeOneDay);
|
||||
$emergencyCount += $this->getMetrikaResultFromReport($report, 12, $isRangeOneDay);
|
||||
$planSurgical += $this->getMetrikaResultFromReport($report, 11, $isRangeOneDay);
|
||||
$emergencySurgical += $this->getMetrikaResultFromReport($report, 10, $isRangeOneDay);
|
||||
$transferredCount += $this->getMetrikaResultFromReport($report, 13, $isRangeOneDay);
|
||||
$outcomeCount += $this->getMetrikaResultFromReport($report, 7, $isRangeOneDay);
|
||||
$deceasedCount += $this->getMetrikaResultFromReport($report, 9, $isRangeOneDay);
|
||||
}
|
||||
|
||||
$beds = (int)optional($department->metrikaDefault()
|
||||
->where('rf_metrika_item_id', 1)
|
||||
->first())->value ?? 0;
|
||||
// Независимые метрики (установки по умолчанию и т.п.)
|
||||
$bedsCount = $department->metrikaDefault()
|
||||
->where('rf_metrika_item_id', 1)->value('value');
|
||||
|
||||
$occupiedBeds = (int)optional(Report::where('rf_department_id', $department->department_id)
|
||||
->join('metrika_results', 'reports.report_id', '=', 'metrika_results.rf_report_id')
|
||||
->where('metrika_results.rf_metrika_item_id', 8)
|
||||
->orderBy('reports.sent_at', 'desc')
|
||||
->first())->value ?? 0;
|
||||
$percentLoadedBeds = $bedsCount > 0 ? round($occupiedBeds * 100 / $bedsCount) : 0;
|
||||
|
||||
$percentLoadedBeds = $beds > 0 ? round($occupiedBeds * 100 / $beds) : 0;
|
||||
|
||||
$data[] = [
|
||||
$groupedData[$departmentType][] = [
|
||||
'department' => $department->name_short,
|
||||
'beds' => $beds,
|
||||
'all' => $allCount,
|
||||
'plan' => '0',
|
||||
'emergency' => '0',
|
||||
'leave' => $leaveCount,
|
||||
'consist' => $consistCount,
|
||||
'beds' => $bedsCount,
|
||||
'recipients' => [
|
||||
'all' => $allCount,
|
||||
'plan' => $planCount,
|
||||
'emergency' => $emergencyCount,
|
||||
'transferred' => $transferredCount,
|
||||
],
|
||||
'outcome' => $outcomeCount,
|
||||
'consist' => $currentCount,
|
||||
'percentLoadedBeds' => $percentLoadedBeds,
|
||||
'surgical' => [
|
||||
'plan' => $planSurgical,
|
||||
'emergency' => $emergencySurgical
|
||||
],
|
||||
'deceased' => $deceasedCount,
|
||||
'type' => $departmentType
|
||||
];
|
||||
}
|
||||
|
||||
// Преобразуем группированные данные в плоский массив с заголовками групп
|
||||
$finalData = [];
|
||||
foreach ($groupedData as $type => $departmentsInType) {
|
||||
// Добавляем строку-заголовок группы
|
||||
$finalData[] = [
|
||||
'isGroupHeader' => true,
|
||||
'groupName' => $type,
|
||||
'colspan' => 12, // Количество колонок в таблице
|
||||
'type' => $type
|
||||
];
|
||||
|
||||
// Добавляем отделения этой группы
|
||||
foreach ($departmentsInType as $department) {
|
||||
$finalData[] = $department;
|
||||
}
|
||||
}
|
||||
|
||||
$isHeadOrAdmin = $user->isAdmin() || $user->isHeadOfDepartment();
|
||||
$date = $isHeadOrAdmin ? [
|
||||
$this->dateService->parseDate($isRangeOneDay ? $endDate : $startDate)->getTimestampMs(),
|
||||
$this->dateService->parseDate($endDate)->getTimestampMs()
|
||||
] : $this->dateService->parseDate($endDate)->getTimestampMs();
|
||||
|
||||
return Inertia::render('Statistic/Index', [
|
||||
'data' => $data
|
||||
'data' => $finalData,
|
||||
'isHeadOrAdmin' => $isHeadOrAdmin,
|
||||
'date' => $date,
|
||||
'isOneDay' => $isRangeOneDay
|
||||
]);
|
||||
}
|
||||
|
||||
private function getMetrikaResultFromReport(Report $report, int $metrikaItem, bool $sum = true)
|
||||
{
|
||||
if ($sum) {
|
||||
return (int) ($report->metrikaResults()
|
||||
->where('rf_metrika_item_id', $metrikaItem)
|
||||
->sum(DB::raw('CAST(value AS INTEGER)')) ?: 0);
|
||||
}
|
||||
|
||||
return (int) ($report->metrikaResults()
|
||||
->where('rf_metrika_item_id', $metrikaItem)
|
||||
->value('value') ?: 0);
|
||||
}
|
||||
|
||||
public function indexOld(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
Reference in New Issue
Block a user