contextResolver->resolveReportForPeriod($department->department_id, $dateRange); $isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin(); $useSnapshots = $isHeadOrAdmin || ! $dateRange->isEndDateToday() || $reportToday; if ($useSnapshots && $isHeadOrAdmin && $reportToday) { $fillableUserId = $reportToday->rf_lpudoctor_id ?? null; } else { $fillableUserId = request()->query('userId', $user->rf_lpudoctor_id); } $unwantedEvents = $this->getUnwantedEvents($department, $dateRange); $isActiveSendButton = $this->isSendButtonActive($user, $dateRange, $reportToday); $message = null; if ($reportToday) { $reportDoctor = $reportToday->lpuDoctor; $message = "Отчет создан пользователем: $reportDoctor->FAM_V $reportDoctor->IM_V $reportDoctor->OT_V"; } $statusMessage = $reportToday ? ($reportToday->status === 'submitted' ? 'Этот отчет в статусе: опубликован' : 'Этот отчет в статусе: черновик') : null; $lpuDoctor = $this->getDoctorInfo($fillableUserId, $dateRange); $date = $isHeadOrAdmin ? [ $dateRange->startDate->getTimestampMs(), $dateRange->endDate->getTimestampMs(), ] : $dateRange->endDate->getTimestampMs(); return [ 'report_id' => $reportToday?->report_id, 'unwantedEvents' => $unwantedEvents, 'isActiveSendButton' => $isActiveSendButton, 'message' => $dateRange->isOneDay ? $message : null, 'status' => $reportToday?->status ?? 'draft', 'statusMessage' => $dateRange->isOneDay ? $statusMessage : null, 'canPublish' => (bool) $reportToday && ($reportToday->status === 'draft') && $isActiveSendButton, 'isOneDay' => $dateRange->isOneDay, 'isHeadOrAdmin' => $isHeadOrAdmin, 'dates' => $date, 'userId' => $fillableUserId, 'userName' => $lpuDoctor ? "$lpuDoctor->FAM_V $lpuDoctor->IM_V $lpuDoctor->OT_V" : null, ]; } /** * @return Collection> */ public function getUnwantedEvents(Department $department, DateRange $dateRange): Collection { return UnwantedEvent::query() ->whereHas('report', function ($query) use ($department, $dateRange) { $query->where('rf_department_id', $department->department_id); if ($dateRange->isOneDay) { $query->exactPeriod($dateRange->startSql(), $dateRange->endSql()); } else { $query->withinPeriod($dateRange->startSql(), $dateRange->endSql()); } }) ->get() ->map(function (UnwantedEvent $item) { return [ ...$item->toArray(), 'created_at' => Carbon::parse($item->created_at)->format('Создано d.m.Y в H:i'), ]; }); } /** * @return Collection */ public function getReportsForDateRange(int $departmentId, DateRange $dateRange): Collection { return $this->contextResolver->getReportsForDateRange($departmentId, $dateRange); } public function getRecipientPlanOfYear(Department $department, DateRange $dateRange): array { $periodPlanModel = $department->recipientPlanOfYear(); $monthsInPeriod = ceil($dateRange->startDate->diffInMonths($dateRange->endDate)); $annualPlan = $periodPlanModel ? (int) $periodPlanModel->value : 0; $oneMonthPlan = ceil($annualPlan / 12); $periodPlan = round($oneMonthPlan * $monthsInPeriod); $query = $department->reports() ->with('metrikaResults') ->where('period_start', '>', $dateRange->startSql()) ->where('period_end', '<=', $dateRange->endSql()); if ($dateRange->isOneDay) { $query->where('period_start', '>=', $dateRange->startFirstOfMonth()) ->where('period_end', '<=', $dateRange->endSql()); } else { $query->where('period_start', '>', $dateRange->startSql()) ->where('period_end', '<=', $dateRange->endSql()); } $progress = 0; foreach ($query->get() as $report) { $outcome = $report->metrikaResults() ->where('rf_metrika_item_id', MetrikaConfig::OUTCOME) ->first(); if ($outcome) { $progress += (int) $outcome->value; } } return [ 'plan' => $periodPlan, 'progress' => $progress, ]; } private function isSendButtonActive(User $user, DateRange $dateRange, ?Report $reportToday): bool { if (! $user->isHeadOfDepartment() && ! $user->isAdmin()) { if ($reportToday && $reportToday->status === 'submitted') { return false; } return $dateRange->isEndDateToday(); } return (bool) $reportToday && $dateRange->isOneDay; } private function getDoctorInfo(?int $doctorId, DateRange $dateRange): ?MisLpuDoctor { if (! $doctorId || ! $dateRange->isOneDay) { return null; } return MisLpuDoctor::query() ->where('LPUDoctorID', $doctorId) ->first(); } }