* блокировка изменения отчета для врача
* вывод данных из отчетов для ролей адм и зав * поправил ширину стобцов ввода * добавил календарь на страницу статистики * переделал календарь у заведующего на странице отчета * добавил и привязал метрики в статистику
This commit is contained in:
@@ -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