$data */ public function createManualPatient(Department $department, User $user, array $data): DepartmentPatient { $report = $this->resolveReportForManualPatient($department, $user, $data); return $this->unifiedPatientService->createManualPatient($department, $user, $data, $report->report_id); } /** * @param array $data */ public function setManualPatientOutcome(User $user, int $departmentPatientId, array $data): DepartmentPatient { $patient = DepartmentPatient::query() ->where('department_patient_id', $departmentPatientId) ->firstOrFail(); $updatedPatient = $this->unifiedPatientService->recordManualOutcome($patient, $data); $this->syncManualPatientSnapshots($updatedPatient, $user, []); return $updatedPatient; } /** * @param array $data */ public function updateManualPatient(User $user, int $departmentPatientId, array $data): DepartmentPatient { $patient = $this->resolveManageableManualPatient($user, $departmentPatientId); $updatedPatient = $this->unifiedPatientService->updateManualPatient($patient, $data); $this->syncManualPatientSnapshots($updatedPatient, $user, $data); return $updatedPatient; } public function linkManualPatientToMis(int $departmentPatientId, int $medicalHistoryId): DepartmentPatient { $patient = DepartmentPatient::query() ->where('department_patient_id', $departmentPatientId) ->firstOrFail(); return $this->unifiedPatientService->linkManualPatientToMis($patient, $medicalHistoryId); } /** * @return Collection */ public function getManualPatientOperations(User $user, int $departmentPatientId): Collection { $patient = $this->resolveManageableManualPatient($user, $departmentPatientId); return $patient->operations() ->with('serviceMedical') ->orderByDesc('started_at') ->get(); } /** * @param array $data */ public function createManualPatientOperation( User $user, int $departmentPatientId, array $data ): DepartmentPatientOperation { $patient = $this->resolveManageableManualPatient($user, $departmentPatientId); $service = $this->resolveMedicalService((int) $data['service_id']); return $patient->operations()->create([ 'rf_kl_service_medical_id' => $service->ServiceMedicalID, 'service_code' => $service->ServiceMedicalCode, 'service_name' => $service->ServiceMedicalName, 'urgency' => $data['urgency'], 'started_at' => $data['started_at'], 'ended_at' => $data['ended_at'], 'created_by' => $user->id, ])->load('serviceMedical'); } /** * @param array $data */ public function updateManualPatientOperation( User $user, int $departmentPatientId, int $operationId, array $data ): DepartmentPatientOperation { $patient = $this->resolveManageableManualPatient($user, $departmentPatientId); $service = $this->resolveMedicalService((int) $data['service_id']); $operation = $patient->operations() ->where('department_patient_operation_id', $operationId) ->firstOrFail(); $operation->update([ 'rf_kl_service_medical_id' => $service->ServiceMedicalID, 'service_code' => $service->ServiceMedicalCode, 'service_name' => $service->ServiceMedicalName, 'urgency' => $data['urgency'], 'started_at' => $data['started_at'], 'ended_at' => $data['ended_at'], ]); return $operation->fresh()->load('serviceMedical'); } public function deleteManualPatientOperation(User $user, int $departmentPatientId, int $operationId): void { $patient = $this->resolveManageableManualPatient($user, $departmentPatientId); $patient->operations() ->where('department_patient_operation_id', $operationId) ->firstOrFail() ->delete(); } private function resolveManageableManualPatient(User $user, int $departmentPatientId): DepartmentPatient { $query = DepartmentPatient::query() ->where('department_patient_id', $departmentPatientId) ->whereIn('source_type', ['manual', 'special']); if (! $user->isAdmin() && ! $user->isHeadOfDepartment()) { $query->where('rf_department_id', $user->department->department_id); } return $query->firstOrFail(); } /** * @param array $data */ private function syncManualPatientSnapshots(DepartmentPatient $patient, User $user, array $data): void { $reportIds = $patient->rf_report_id ? [$patient->rf_report_id] : (isset($data['startAt'], $data['endAt']) && $data['startAt'] && $data['endAt'] ? $this->contextResolver ->getReportsForDateRange( $patient->rf_department_id, $this->dateRangeService->getNormalizedDateRange( $user, (string) $data['startAt'], (string) $data['endAt'] ) ) ->pluck('report_id') ->values() ->all() : []); if (empty($reportIds)) { return; } MedicalHistorySnapshot::query() ->whereIn('rf_report_id', $reportIds) ->where('rf_department_patient_id', $patient->department_patient_id) ->update([ 'patient_kind' => $patient->patient_kind, 'full_name' => $patient->full_name, 'birth_date' => $patient->birth_date, 'diagnosis_code' => $patient->diagnosis_code, 'diagnosis_name' => $patient->diagnosis_name, 'admitted_at' => $patient->admitted_at, 'outcome_type' => $patient->is_current ? null : $patient->outcome_type, 'outcome_at' => $patient->is_current ? null : $patient->outcome_at, 'updated_at' => now(), ]); } /** * @param array $data */ private function resolveReportForManualPatient(Department $department, User $user, array $data): Report { $reportId = $data['report_id'] ?? null; if ($reportId) { return Report::query() ->where('report_id', $reportId) ->where('rf_department_id', $department->department_id) ->firstOrFail(); } if (! isset($data['startAt'], $data['endAt']) || ! $data['startAt'] || ! $data['endAt']) { throw new InvalidArgumentException('Не указан отчет или диапазон для привязки спецконтингента'); } $dateRange = $this->dateRangeService->getNormalizedDateRange( $user, (string) $data['startAt'], (string) $data['endAt'] ); $existingReport = Report::query() ->where('rf_department_id', $department->department_id) ->exactPeriod($dateRange->startSql(), $dateRange->endSql()) ->first(); if ($existingReport) { return $existingReport; } return Report::query()->create([ 'rf_department_id' => $department->department_id, 'rf_user_id' => $user->id, 'rf_lpudoctor_id' => $data['user_id'] ?? $user->rf_lpudoctor_id, 'sent_at' => $dateRange->endSql(), 'created_at' => $dateRange->endSql(), 'period_start' => $dateRange->startSql(), 'period_end' => $dateRange->endSql(), 'status' => 'draft', ]); } private function resolveMedicalService(int $serviceId): MisServiceMedical { return MisServiceMedical::query() ->where('ServiceMedicalID', $serviceId) ->firstOrFail(); } }