Files
onboard/app/Infrastructure/Reports/Services/ReportStorageService.php

167 lines
6.1 KiB
PHP

<?php
namespace App\Infrastructure\Reports\Services;
use App\Domain\Reports\Models\ReportSnapshot;
use App\Domain\Reports\ValueObjects\MetrikaConfig;
use App\Models\Department;
use App\Models\MetrikaResult;
use App\Models\ObservationPatient;
use App\Models\Report;
use App\Models\UnwantedEvent;
use App\Models\User;
class ReportStorageService
{
public function createOrUpdateReport(ReportSnapshot $snapshot, User $actor): Report
{
$reportData = [
'rf_department_id' => $snapshot->departmentId,
'rf_user_id' => $actor->id,
'rf_lpudoctor_id' => $snapshot->userId,
'sent_at' => $snapshot->sentAt?->format('Y-m-d H:i:s') ?? $snapshot->periodEnd->format('Y-m-d H:i:s'),
'period_start' => $snapshot->periodStart->format('Y-m-d H:i:s'),
'period_end' => $snapshot->periodEnd->format('Y-m-d H:i:s'),
'created_at' => $snapshot->createdAt?->format('Y-m-d H:i:s') ?? $snapshot->periodEnd->format('Y-m-d H:i:s'),
'status' => $snapshot->status,
];
if ($snapshot->reportId) {
return Report::query()->updateOrCreate(
['report_id' => $snapshot->reportId],
$reportData,
);
}
$report = Report::query()->create($reportData);
$department = Department::query()->find($snapshot->departmentId);
$beds = $department?->metrikaDefault->where('rf_metrika_item_id', MetrikaConfig::BEDS)->first();
if ($beds) {
MetrikaResult::query()->updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => MetrikaConfig::BEDS,
],
['value' => $beds->value]
);
}
return $report;
}
public function saveMetrics(Report $report, ReportSnapshot $snapshot): void
{
foreach ($snapshot->normalizedMetrics() as $metricId => $value) {
MetrikaResult::query()->updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => $metricId,
],
['value' => $value]
);
}
}
public function saveMetric(Report $report, int $metricId, int|float $value): void
{
MetrikaResult::query()->updateOrCreate(
[
'rf_report_id' => $report->report_id,
'rf_metrika_item_id' => $metricId,
],
['value' => $value]
);
}
public function saveUnwantedEvents(Report $report, ReportSnapshot $snapshot): void
{
if ($snapshot->unwantedEvents === []) {
$report->unwantedEvents()->delete();
$this->saveMetric($report, MetrikaConfig::UNWANTED_EVENTS, 0);
return;
}
$report->unwantedEvents()
->whereNotIn('unwanted_event_id', array_values(array_filter(array_map(
static fn (array $event): ?int => isset($event['unwanted_event_id']) ? (int) $event['unwanted_event_id'] : null,
$snapshot->unwantedEvents
))))
->delete();
foreach ($snapshot->unwantedEvents as $event) {
if (! empty($event['unwanted_event_id'])) {
UnwantedEvent::query()->updateOrCreate(
['unwanted_event_id' => (int) $event['unwanted_event_id']],
[
'rf_report_id' => $report->report_id,
'comment' => (string) ($event['comment'] ?? ''),
'title' => (string) ($event['title'] ?? ''),
'is_visible' => (bool) ($event['is_visible'] ?? true),
]
);
continue;
}
UnwantedEvent::query()->create([
'rf_report_id' => $report->report_id,
'comment' => (string) ($event['comment'] ?? ''),
'title' => (string) ($event['title'] ?? ''),
'is_visible' => (bool) ($event['is_visible'] ?? true),
]);
}
$this->saveMetric($report, MetrikaConfig::UNWANTED_EVENTS, count($snapshot->unwantedEvents));
}
public function saveObservationPatients(Report $report, ReportSnapshot $snapshot): void
{
if ($snapshot->observationPatients === []) {
ObservationPatient::query()
->where('rf_department_id', $snapshot->departmentId)
->where('rf_report_id', $report->report_id)
->delete();
$this->saveMetric($report, MetrikaConfig::OBSERVATION, 0);
return;
}
$observedKeys = [];
foreach ($snapshot->observationPatients as $patient) {
$medicalHistoryId = isset($patient['medical_history_id']) ? (int) $patient['medical_history_id'] : null;
$departmentPatientId = isset($patient['department_patient_id']) ? (int) $patient['department_patient_id'] : null;
$observedKeys[] = $medicalHistoryId.'-'.$departmentPatientId;
ObservationPatient::query()->updateOrCreate(
[
'rf_medicalhistory_id' => $medicalHistoryId,
'rf_department_patient_id' => $departmentPatientId,
'rf_department_id' => $snapshot->departmentId,
],
[
'rf_report_id' => $report->report_id,
'rf_mkab_id' => null,
'comment' => $patient['comment'] ?? null,
]
);
}
ObservationPatient::query()
->where('rf_department_id', $snapshot->departmentId)
->where('rf_report_id', $report->report_id)
->get()
->filter(fn (ObservationPatient $patient) => ! in_array(
($patient->rf_medicalhistory_id ?? '').'-'.($patient->rf_department_patient_id ?? ''),
$observedKeys,
true
))
->each
->delete();
$this->saveMetric($report, MetrikaConfig::OBSERVATION, count($snapshot->observationPatients));
}
}