* восстановление окна наблюдения

* добавил получение выбывших
* фильтрация выбывших по результатам лечения
* добавил подсказку при наведении на операции
* добавил вывод причины наблюдения
* добавил вкладки для выбывших
* изменил связь и сохранение пациентов на контроле
* добавил возможность редактирования причины контроля
* полное изменение окна с нежелательными событиями
* исправил просмотр причины контроля
* работа над окном редактирования причины контроля в таблице
* визуальное выделение умерших и проведенных операций
* добавил выбор даты для роли врач
* центрирование блоков статистики
* разделение выполненных операций на срочность
* поправил метод определения текущего дня для роли врач
* функция блокировки при выборе другой даты для роли врач
This commit is contained in:
brusnitsyn
2026-01-29 16:42:42 +09:00
parent cb43c74a72
commit 87e21f0e08
24 changed files with 2065 additions and 501 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -58,7 +58,7 @@ class StatisticController extends Controller
->orderBy('reports.sent_at', 'desc')
->first())->value ?? 0;
$percentLoadedBeds = $beds > 0 ? $occupiedBeds * 100 / $beds : 0;
$percentLoadedBeds = $beds > 0 ? round($occupiedBeds * 100 / $beds) : 0;
$data[] = [
'department' => $department->name_short,

View File

@@ -27,7 +27,7 @@ class FormattedPatientResource extends JsonResource
];
}),
'operations' => $this->whenLoaded('surgicalOperations', function () {
return $this->surgicalOperations()->where('rf_StationarBranchID', $this->misStationarBranchId)
return $this->operationOnBranch($this->misStationarBranchId, $this->startDate, $this->endDate)
->get()
->map(function (MisSurgicalOperation $operation) {
return [
@@ -38,6 +38,8 @@ class FormattedPatientResource extends JsonResource
'fullname' => Str::ucwords(Str::lower("$this->FAMILY $this->Name $this->OT")),
'age' => Carbon::parse($this->BD)->diff(Carbon::now())->format('%y'),
'birth_date' => Carbon::parse($this->BD)->format('d.m.Y'),
'outcome_type' => $this->when($this->outcome_type, $this->outcome_type),
'comment' => $this->when($this->comment, $this->comment)
];
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class MedicalHistorySnapshot extends Model
{
protected $primaryKey = 'medical_history_snapshot_id';
protected $fillable = [
'rf_report_id',
'rf_medicalhistory_id',
'patient_type',
];
public function report()
{
return $this->belongsTo(Report::class, 'rf_report_id');
}
}

View File

@@ -26,7 +26,7 @@ class MisMedicalHistory extends Model
public function observationPatient()
{
return $this->belongsTo(ObservationPatient::class, 'MedicalHistoryID', 'rf_medicalhistory_id');
return $this->hasMany(ObservationPatient::class, 'rf_medicalhistory_id', 'MedicalHistoryID');
}
public function surgicalOperations()
@@ -34,6 +34,12 @@ class MisMedicalHistory extends Model
return $this->hasMany(MisSurgicalOperation::class, 'rf_MedicalHistoryID', 'MedicalHistoryID');
}
public function scopeOperationOnBranch($query, $branchId, $startDate, $endDate)
{
return $this->surgicalOperations()->where('rf_StationarBranchID', $branchId)
->whereBetween('Date', [$startDate, $endDate]);
}
public function scopeCurrentlyHospitalized($query)
{
return $query->whereDate('DateExtract', '1900-01-01')
@@ -43,25 +49,25 @@ class MisMedicalHistory extends Model
/*
* Истории со срочностью - Плановая
*/
public function scopePlan()
public function scopePlan($query)
{
return $this->where('rf_EmerSignID', 1);
return $query->where('rf_EmerSignID', 1);
}
/*
* Истории со срочностью - Экстренная
*/
public function scopeEmergency()
public function scopeEmergency($query)
{
return $this->where('rf_EmerSignID', 2);
return $query->where('rf_EmerSignID', 2);
}
/*
* Истории с результатом - Умер
*/
public function scopeDeceased()
public function scopeDeceased($query)
{
return $this->where('rf_kl_VisitResultID', 5);
return $query->where('rf_kl_VisitResultID', 5);
}
/*

View File

@@ -25,7 +25,7 @@ class MisMigrationPatient extends Model
return $this->hasOne(MisMKB::class, 'MKBID', 'rf_MKBID');
}
public function scopeCurrentlyInTreatment($query, $branchId = null)
public function scopeCurrentlyInTreatment($query, $branchId = null, $startDate = null, $endDate = null)
{
$query->where('rf_kl_VisitResultID', 0)
->where('rf_MedicalHistoryID', '<>', 0);
@@ -34,6 +34,10 @@ class MisMigrationPatient extends Model
$query->where('rf_StationarBranchID', $branchId);
}
if ($startDate && $endDate) {
$query->whereBetween('DateIngoing', [$startDate, $endDate]);
}
return $query;
}
@@ -48,6 +52,95 @@ class MisMigrationPatient extends Model
return $query;
}
/**
* Выбывшие пациенты (все исходы)
*/
public function scopeOutcomePatients($query, $branchId = null, $startDate = null, $endDate = null)
{
$query->where('rf_kl_VisitResultID', '<>', 0) // не активное лечение
->whereDate('DateOut', '<>', '1900-01-01') // есть дата выбытия
->where('rf_MedicalHistoryID', '<>', 0);
if ($branchId) {
$query->where('rf_StationarBranchID', $branchId);
}
if ($startDate && $endDate) {
$query->whereBetween('DateOut', [$startDate, $endDate]);
}
return $query;
}
/**
* Выписанные пациенты
*/
public function scopeDischarged($query, $branchId = null, $startDate = null, $endDate = null)
{
// ID выписки
$dischargeCodes = [1, 7, 8, 9, 10, 11, 48, 49, 124];
$query->whereIn('rf_kl_VisitResultID', $dischargeCodes)
->whereDate('DateOut', '<>', '1900-01-01')
->where('rf_MedicalHistoryID', '<>', 0);
if ($branchId) {
$query->where('rf_StationarBranchID', $branchId);
}
if ($startDate && $endDate) {
$query->whereBetween('DateOut', [$startDate, $endDate]);
}
return $query;
}
/**
* Перевод в другое отделение
*/
public function scopeTransferred($query, $branchId = null, $startDate = null, $endDate = null)
{
// ID перевода
$transferCodes = [2, 3, 4, 12, 13, 14];
$query->whereIn('rf_kl_VisitResultID', $transferCodes)
->whereDate('DateOut', '<>', '1900-01-01')
->where('rf_MedicalHistoryID', '<>', 0);
if ($branchId) {
$query->where('rf_StationarBranchID', $branchId);
}
if ($startDate && $endDate) {
$query->whereBetween('DateOut', [$startDate, $endDate]);
}
return $query;
}
/**
* Умершие пациенты
*/
public function scopeDeceasedOutcome($query, $branchId = null, $startDate = null, $endDate = null)
{
// ID умершего
$deceasedCodes = [5, 6, 15, 16];
$query->whereIn('rf_kl_VisitResultID', $deceasedCodes)
->whereDate('DateOut', '<>', '1900-01-01')
->where('rf_MedicalHistoryID', '<>', 0);
if ($branchId) {
$query->where('rf_StationarBranchID', $branchId);
}
if ($startDate && $endDate) {
$query->whereBetween('DateOut', [$startDate, $endDate]);
}
return $query;
}
public function scopeExtractedToday($query, $branchId = null, $startDate = null, $endDate = null)
{
if (is_null($startDate)) $startDate = Carbon::now()->addDays(-1)->format('Y-m-d');

View File

@@ -25,4 +25,9 @@ class Report extends Model
{
return $this->hasMany(ObservationPatient::class, 'rf_report_id', 'report_id');
}
public function unwantedEvents()
{
return $this->hasMany(UnwantedEvent::class, 'rf_report_id', 'report_id');
}
}

View File

@@ -10,6 +10,13 @@ class UnwantedEvent extends Model
protected $fillable = [
'rf_report_id',
'comment'
'comment',
'title',
'is_visible',
];
public function report()
{
return $this->belongsTo(Report::class, 'rf_report_id');
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace App\Services;
use Illuminate\Support\Carbon;
class DateRangeService
{
public function getDateRangeForUser($user, $startAt = null, $endAt = null): array
{
if ($startAt && $endAt) {
return $this->getCustomDateRange($startAt, $endAt, $user);
}
return $this->getDefaultDateRange($user);
}
private function getCustomDateRange($startAt, $endAt, $user): array
{
$startDate = $this->parseDate($startAt);
$endDate = $this->parseDate($endAt);
if ($startDate->isSameDay($endDate)) {
$startDate = $startDate->subDay()->setTime(6, 0);
$endDate = $endDate->setTime(6, 0);
} else {
$startDate = $startDate->setTime(6, 0);
$endDate = $endDate->setTime(6, 0);
}
return [
$startDate->format('Y-m-d H:i:s'),
$endDate->format('Y-m-d H:i:s')
];
}
private function getDefaultDateRange($user): array
{
if ($user->isHeadOfDepartment() || $user->isAdmin()) {
$startDate = Carbon::now('Asia/Yakutsk')
->firstOfMonth()
->setTime(6, 0);
$endDate = Carbon::now('Asia/Yakutsk')
->setTime(6, 0);
} else {
$startDate = Carbon::now('Asia/Yakutsk')
->subDay()
->setTime(6, 0);
$endDate = Carbon::now('Asia/Yakutsk')
->setTime(6, 0);
}
return [
$startDate->format('Y-m-d H:i:s'),
$endDate->format('Y-m-d H:i:s')
];
}
private function parseDate($dateInput): Carbon
{
if (is_numeric($dateInput)) {
return Carbon::createFromTimestampMs($dateInput)
->setTimezone('Asia/Yakutsk');
}
return Carbon::parse($dateInput, 'Asia/Yakutsk');
}
}

View File

@@ -0,0 +1,449 @@
<?php
namespace App\Services;
use App\Models\MisMigrationPatient;
use App\Models\MisMedicalHistory;
use App\Models\MisSurgicalOperation;
use App\Models\ObservationPatient;
use Illuminate\Support\Collection;
class PatientService
{
public function getPatientsByType(
string $type,
?bool $isHeadOrAdmin,
?int $branchId,
?string $startDate = null,
?string $endDate = null,
bool $countOnly = false,
bool $onlyIds = false
): Collection|int|array {
// Обрабатываем outcome- типы
if (str_starts_with($type, 'outcome-')) {
$outcomeType = str_replace('outcome-', '', $type);
return $this->getOutcomePatients($branchId, $startDate, $endDate, $outcomeType, $countOnly, $onlyIds);
}
// Обрабатываем обычные типы
$method = 'get' . ucfirst($type) . 'Patients';
if (method_exists($this, $method)) {
return $this->$method($isHeadOrAdmin, $branchId, $startDate, $endDate, $countOnly, $onlyIds);
}
throw new \InvalidArgumentException("Unknown patient type: {$type}");
}
public function getPlanPatients(
?bool $isHeadOrAdmin,
?int $branchId,
?string $startDate,
?string $endDate,
bool $countOnly,
bool $onlyIds
): Collection|int|array {
return $this->getAdmissionPatients('plan', $isHeadOrAdmin, $branchId, $startDate, $endDate, $countOnly, $onlyIds);
}
public function getEmergencyPatients(
?bool $isHeadOrAdmin,
?int $branchId,
?string $startDate,
?string $endDate,
bool $countOnly,
bool $onlyIds
): Collection|int|array {
return $this->getAdmissionPatients('emergency', $isHeadOrAdmin, $branchId, $startDate, $endDate, $countOnly, $onlyIds);
}
private function getAdmissionPatients(
string $admissionType,
?bool $isHeadOrAdmin,
?int $branchId,
?string $startDate,
?string $endDate,
bool $countOnly,
bool $onlyIds
): Collection|int|array {
$query = $this->getBasePatientsQuery($isHeadOrAdmin, $branchId, $startDate, $endDate);
if ($admissionType === 'plan') {
$query->plan();
} else {
$query->emergency();
}
return $this->executeQuery($query, $countOnly, $onlyIds);
}
private function getBasePatientsQuery(
?bool $isHeadOrAdmin,
?int $branchId,
?string $startDate,
?string $endDate
) {
$migrationPatient = new MisMigrationPatient();
if ($isHeadOrAdmin) {
$medicalHistoryIds = $migrationPatient->newQuery()
->whereInDepartment($branchId)
->whereBetween('DateIngoing', [$startDate, $endDate])
->pluck('rf_MedicalHistoryID')
->toArray();
} else {
$medicalHistoryIds = $migrationPatient->newQuery()
->currentlyInTreatment($branchId)
->whereBetween('DateIngoing', [$startDate, $endDate])
->pluck('rf_MedicalHistoryID')
->toArray();
}
if (empty($medicalHistoryIds)) {
return MisMedicalHistory::whereRaw('1=0'); // Пустой запрос
}
return MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
->with(['surgicalOperations' => function ($query) use ($startDate, $endDate) {
$query->whereBetween('Date', [$startDate, $endDate]);
}])
->orderBy('DateRecipient', 'DESC');
}
private function executeQuery($query, bool $countOnly, bool $onlyIds): Collection|int|array
{
if ($onlyIds) {
return $query->pluck('MedicalHistoryID')->toArray();
}
if ($countOnly) {
return $query->count();
}
return $query->get();
}
public function getObservationPatients(int $departmentId): Collection
{
return ObservationPatient::where('rf_department_id', $departmentId)
->with(['medicalHistory'])
->get()
->map(function ($observation) {
$patient = $observation->medicalHistory;
$patient->observation_comment = $observation->comment;
return $patient;
});
}
public function getOutcomePatients(int $branchId, string $startDate, string $endDate, string $outcomeType, $countOnly = false, $onlyIds = false): Collection|int
{
return match($outcomeType) {
'discharged' => $this->getDischargedOutcomePatients($branchId, $startDate, $endDate, $countOnly, $onlyIds),
'transferred' => $this->getTransferredOutcomePatients($branchId, $startDate, $endDate, $countOnly, $onlyIds),
'deceased' => $this->getDeceasedOutcomePatients($branchId, $startDate, $endDate, $countOnly, $onlyIds),
default => throw new \InvalidArgumentException("Неизвестный тип исхода: {$outcomeType}")
};
}
/**
* Получить всех выбывших пациентов
*/
public function getAllOutcomePatients(
int $branchId,
string $startDate,
string $endDate,
bool $countOnly = false
): Collection|int {
$migrationPatient = new MisMigrationPatient();
// Получаем миграции выбывших пациентов за период
$migrations = $migrationPatient->newQuery()
->outcomePatients($branchId, $startDate, $endDate)
->select('rf_MedicalHistoryID', 'rf_kl_VisitResultID', 'DateOut')
->get()
->groupBy('rf_MedicalHistoryID');
if ($migrations->isEmpty()) {
return $countOnly ? 0 : collect();
}
$medicalHistoryIds = $migrations->keys()->toArray();
$query = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
->with(['surgicalOperations'])
->orderBy('DateRecipient', 'DESC');
if ($countOnly) {
return $query->count();
}
$patients = $query->get();
return $this->addOutcomeInfoToPatients($patients, $migrations);
}
/**
* Получить миграции выбывших пациентов
*/
private function getOutcomeMigrations(int $branchId, string $startDate, string $endDate): Collection
{
$migrationPatient = new MisMigrationPatient();
return $migrationPatient->newQuery()
->outcomePatients($branchId, $startDate, $endDate)
->select('rf_MedicalHistoryID', 'rf_kl_VisitResultID', 'DateOut')
->get()
->groupBy('rf_MedicalHistoryID');
}
/**
* Добавить информацию о выбытии к пациентам
*/
private function addOutcomeInfoToPatients(Collection $patients, Collection $migrations): Collection
{
return $patients->map(function ($patient) use ($migrations) {
$patientMigrations = $migrations->get($patient->MedicalHistoryID, collect());
if ($patientMigrations->isNotEmpty()) {
$latestMigration = $patientMigrations->sortByDesc('DateOut')->first();
$patient->outcome_type = $this->getOutcomeTypeName($latestMigration->rf_kl_VisitResultID);
$patient->outcome_date = $latestMigration->DateOut;
$patient->visit_result_id = $latestMigration->rf_kl_VisitResultID;
}
return $patient;
});
}
/**
* Получить понятное название типа выбытия
*/
private function getOutcomeTypeName(int $visitResultId): string
{
return match($visitResultId) {
1, 7, 8, 9, 10, 11, 48, 49, 124 => 'Выписка',
2, 3, 4, 12, 13, 14 => 'Перевод',
5, 6, 15, 16 => 'Умер',
default => 'Другое (' . $visitResultId . ')'
};
}
/**
* Получить выписанных пациентов
*/
public function getDischargedOutcomePatients(
int $branchId,
string $startDate,
string $endDate,
bool $countOnly = false,
bool $onlyIds = false
): Collection|array|int {
return $this->getSpecificOutcomePatients('discharged', $branchId, $startDate, $endDate, $onlyIds, $countOnly);
}
/**
* Получить переведенных пациентов
*/
public function getTransferredOutcomePatients(
int $branchId,
string $startDate,
string $endDate,
bool $countOnly = false,
bool $onlyIds = false
): Collection|array|int {
return $this->getSpecificOutcomePatients('transferred', $branchId, $startDate, $endDate, $onlyIds, $countOnly);
}
/**
* Получить умерших пациентов
*/
public function getDeceasedOutcomePatients(
int $branchId,
string $startDate,
string $endDate,
bool $countOnly = false,
bool $onlyIds = false
): Collection|int|array {
return $this->getSpecificOutcomePatients('deceased', $branchId, $startDate, $endDate, $onlyIds, $countOnly);
}
/**
* Общий метод для получения пациентов с определенным типом выбытия
*/
private function getSpecificOutcomePatients(
string $type,
int $branchId,
string $startDate,
string $endDate,
bool $onlyIds = false,
bool $countOnly = false
): Collection|int|array {
$migrationPatient = new MisMigrationPatient();
switch ($type) {
case 'discharged':
$query = $migrationPatient->newQuery()->discharged($branchId, $startDate, $endDate);
break;
case 'transferred':
$query = $migrationPatient->newQuery()->transferred($branchId, $startDate, $endDate);
break;
case 'deceased':
$query = $migrationPatient->newQuery()->deceasedOutcome($branchId, $startDate, $endDate);
break;
default:
throw new \InvalidArgumentException("Неизвестный тип выбытия: {$type}");
}
$medicalHistoryIds = $query->pluck('rf_MedicalHistoryID')->unique()->toArray();
if (empty($medicalHistoryIds)) {
if ($countOnly) return 0;
if ($onlyIds) return [];
return collect();
}
if ($onlyIds) {
return $medicalHistoryIds;
}
$patients = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
->with(['surgicalOperations'])
->orderBy('DateRecipient', 'DESC');
if ($countOnly) {
return $patients->count();
}
return $patients->get();
}
/**
* Получить пациентов, находящихся на лечении
*/
public function getCurrentPatients(
int $branchId,
bool $countOnly = false,
bool $onlyIds = false
): Collection|int|array {
$migrationPatient = new MisMigrationPatient();
$medicalHistoryIds = $migrationPatient->newQuery()
->currentlyInTreatment($branchId)
->pluck('rf_MedicalHistoryID')
->unique()
->toArray();
if (empty($medicalHistoryIds)) {
if ($countOnly) return 0;
if ($onlyIds) return [];
return collect();
}
if ($onlyIds) {
return $medicalHistoryIds;
}
$query = MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
->currentlyHospitalized()
->with(['surgicalOperations'])
->orderBy('DateRecipient', 'DESC');
if ($countOnly) {
return $query->count();
}
return $query->get();
}
/**
* Получить пациентов с операциями
*/
public function getSurgicalPatients(
string $status,
bool $isHeadOrAdmin,
int $branchId,
string $startDate,
string $endDate,
bool $countOnly = false
): Collection|int {
$query = MisSurgicalOperation::where('rf_StationarBranchID', $branchId)
->whereBetween('Date', [$startDate, $endDate])
->orderBy('Date', 'DESC');
if ($status === 'plan') {
$query->where('rf_TypeSurgOperationInTimeID', 6);
} else {
$query->whereIn('rf_TypeSurgOperationInTimeID', [4, 5]);
}
if ($countOnly) {
return $query->count();
}
return $query->get();
}
/**
* Получить пациентов (плановых или экстренных), которые были в отделении в течение периода
*/
public function getPatientsInDepartmentDuringPeriod(
?string $patientType, // 'plan', 'emergency', null (все)
?bool $isHeadOrAdmin,
?int $branchId,
?string $startDate,
?string $endDate,
bool $countOnly = false,
bool $onlyIds = false,
bool $today = false
): Collection|int|array {
// Используем скоуп inDepartment из модели MisMedicalHistory
$query = MisMedicalHistory::query()
->whereHas('migrations', function ($q) use ($branchId, $startDate, $endDate) {
$q->where('rf_StationarBranchID', $branchId)
->where('rf_MedicalHistoryID', '<>', 0)
->where(function ($subQ) use ($startDate, $endDate) {
// Пациент находился в отделении в течение периода
// 1. Поступил в течение периода
$subQ->whereBetween('DateIngoing', [$startDate, $endDate])
// 2. Или выбыл в течение периода
->orWhereBetween('DateOut', [$startDate, $endDate])
// 3. Или находился в отделении в течение всего периода
->orWhere(function ($innerQ) use ($startDate, $endDate) {
$innerQ->where('DateIngoing', '<=', $startDate)
->where(function ($deepQ) use ($endDate) {
$deepQ->where('DateOut', '>=', $endDate)
->orWhereNull('DateOut')
->orWhere('DateOut', '1900-01-01');
});
});
});
})
->with(['surgicalOperations' => function ($query) use ($startDate, $endDate) {
$query->whereBetween('Date', [$startDate, $endDate]);
}])
->orderBy('DateRecipient', 'DESC');
// Фильтруем по типу (план/экстренность)
if ($patientType === 'plan') {
$query->plan();
} elseif ($patientType === 'emergency') {
$query->emergency();
}
// Для врача добавляем условие "все еще в отделении"
if (!$isHeadOrAdmin && !$today) {
$query->currentlyHospitalized();
}
if ($onlyIds) {
return $query->select('MedicalHistoryID')
->pluck('MedicalHistoryID')->values();
}
if ($countOnly) {
return $query->count();
}
return $query->get();
}
}

View File

@@ -0,0 +1,125 @@
<?php
namespace App\Services;
use App\Models\Report;
use App\Models\MetrikaResult;
use App\Models\UnwantedEvent;
use App\Models\ObservationPatient;
use App\Models\MedicalHistorySnapshot;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class ReportService
{
private PatientService $patientService;
public function __construct(PatientService $patientService)
{
$this->patientService = $patientService;
}
public function createReport(array $data): Report
{
DB::beginTransaction();
try {
$report = Report::create([
'rf_department_id' => $data['departmentId'],
'rf_user_id' => Auth::id(),
'sent_at' => now()
]);
$this->saveMetrics($report, $data['metrics'] ?? []);
$this->saveUnwantedEvents($report, $data['unwantedEvents'] ?? []);
$this->saveObservationPatients($report, $data['observationPatients'] ?? []);
$this->savePatientSnapshots($report, $data);
DB::commit();
return $report;
} catch (\Exception $e) {
DB::rollBack();
throw $e;
}
}
private function saveMetrics(Report $report, array $metrics): void
{
foreach ($metrics as $key => $value) {
MetrikaResult::create([
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => (int) str_replace('metrika_item_', '', $key),
'value' => $value
]);
}
}
private function saveUnwantedEvents(Report $report, array $unwantedEvents): void
{
foreach ($unwantedEvents as $event) {
if (isset($event['unwanted_event_id'])) {
UnwantedEvent::updateOrCreate(
['unwanted_event_id' => $event['unwanted_event_id']],
$this->formatUnwantedEventData($report, $event)
);
} else {
UnwantedEvent::create($this->formatUnwantedEventData($report, $event));
}
}
}
private function formatUnwantedEventData(Report $report, array $event): array
{
return [
'rf_report_id' => $report->report_id,
'comment' => $event['comment'] ?? '',
'title' => $event['title'] ?? '',
'is_visible' => $event['is_visible'] ?? true,
];
}
private function saveObservationPatients(Report $report, array $observationPatients): void
{
foreach ($observationPatients as $patient) {
ObservationPatient::create([
'rf_department_id' => $report->rf_department_id,
'rf_report_id' => $report->report_id,
'rf_medicalhistory_id' => $patient['id'],
'comment' => $patient['comment'] ?? null
]);
}
}
private function savePatientSnapshots(Report $report, array $data): void
{
$snapshotTypes = [
'plan' => $this->patientService->getPlanPatients(
false,
$data['branchId'],
$data['startDate'],
$data['endDate'],
false,
true
),
'emergency' => $this->patientService->getEmergencyPatients(
false,
$data['branchId'],
$data['startDate'],
$data['endDate'],
false,
true
)
];
foreach ($snapshotTypes as $type => $patientIds) {
foreach ($patientIds as $patientId) {
MedicalHistorySnapshot::create([
'rf_report_id' => $report->report_id,
'rf_medicalhistory_id' => $patientId,
'patient_type' => $type
]);
}
}
}
}