Перевод на доменную архитектуру
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace App\Infrastructure\Reports\Repositories;
|
||||
|
||||
use App\Domain\Reports\Contracts\ReportRepository;
|
||||
use App\Domain\Reports\Models\ReportSnapshot;
|
||||
use App\Domain\Reports\Models\SavedReportResult;
|
||||
use App\Infrastructure\Reports\Adapters\LegacyReportServiceAdapter;
|
||||
use App\Models\MetrikaResult;
|
||||
use App\Models\ObservationPatient;
|
||||
use App\Models\Report;
|
||||
use App\Models\UnwantedEvent;
|
||||
use App\Infrastructure\Reports\Services\ReportMetricsFinalizer;
|
||||
use App\Infrastructure\Reports\Services\ReportStorageService;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use RuntimeException;
|
||||
|
||||
class EloquentReportRepository implements ReportRepository
|
||||
{
|
||||
public function __construct(
|
||||
private readonly LegacyReportServiceAdapter $legacyAdapter,
|
||||
?ReportStorageService $reportStorageService = null,
|
||||
?ReportMetricsFinalizer $reportMetricsFinalizer = null,
|
||||
) {
|
||||
$this->reportStorageService = $reportStorageService ?? app(ReportStorageService::class);
|
||||
$this->reportMetricsFinalizer = $reportMetricsFinalizer ?? app(ReportMetricsFinalizer::class);
|
||||
}
|
||||
|
||||
private readonly ReportStorageService $reportStorageService;
|
||||
|
||||
private readonly ReportMetricsFinalizer $reportMetricsFinalizer;
|
||||
|
||||
public function save(ReportSnapshot $snapshot): SavedReportResult
|
||||
{
|
||||
$this->legacyAdapter->prepareMemoryForHeavySave();
|
||||
$actor = $snapshot->actorUserId ? User::query()->find($snapshot->actorUserId) : null;
|
||||
|
||||
if (! $actor) {
|
||||
throw new RuntimeException('Actor user was not found.');
|
||||
}
|
||||
|
||||
$report = DB::transaction(function () use ($snapshot, $actor) {
|
||||
$report = $this->reportStorageService->createOrUpdateReport($snapshot, $actor);
|
||||
$this->reportStorageService->saveMetrics($report, $snapshot);
|
||||
$this->reportStorageService->saveUnwantedEvents($report, $snapshot);
|
||||
$this->reportStorageService->saveObservationPatients($report, $snapshot);
|
||||
$this->legacyAdapter->createPatientSnapshots($report, $actor, $snapshot, $snapshot->autoFill);
|
||||
$this->legacyAdapter->syncCalculatedMetrics($report, $actor, $snapshot);
|
||||
|
||||
return $report;
|
||||
});
|
||||
|
||||
DB::transaction(function () use ($report) {
|
||||
$this->reportMetricsFinalizer->finalize($report);
|
||||
$this->legacyAdapter->saveLethalMetricFromSnapshots($report);
|
||||
});
|
||||
|
||||
$this->legacyAdapter->clearCacheAfterReportCreation($actor, $report);
|
||||
|
||||
$savedSnapshot = $this->findSnapshot((int) $report->report_id);
|
||||
|
||||
if (! $savedSnapshot) {
|
||||
throw new RuntimeException('Saved report could not be reloaded for comparison.');
|
||||
}
|
||||
|
||||
return new SavedReportResult(
|
||||
reportId: (int) $report->report_id,
|
||||
snapshot: $savedSnapshot,
|
||||
);
|
||||
}
|
||||
|
||||
public function findSnapshot(int $reportId): ?ReportSnapshot
|
||||
{
|
||||
/** @var Report|null $report */
|
||||
$report = Report::query()
|
||||
->with(['metrikaResults', 'observationPatients', 'unwantedEvents'])
|
||||
->find($reportId);
|
||||
|
||||
if (! $report || ! $report->period_start || ! $report->period_end) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ReportSnapshot(
|
||||
departmentId: (int) $report->rf_department_id,
|
||||
userId: (int) ($report->rf_lpudoctor_id ?? $report->rf_user_id),
|
||||
actorUserId: (int) $report->rf_user_id,
|
||||
periodStart: new \DateTimeImmutable($report->period_start->format('Y-m-d H:i:s')),
|
||||
periodEnd: new \DateTimeImmutable($report->period_end->format('Y-m-d H:i:s')),
|
||||
status: (string) ($report->status ?? 'draft'),
|
||||
autoFill: false,
|
||||
metrics: $report->metrikaResults
|
||||
->mapWithKeys(fn (MetrikaResult $metric) => [(int) $metric->rf_metrika_item_id => $metric->value])
|
||||
->all(),
|
||||
observationPatients: $report->observationPatients
|
||||
->map(fn (ObservationPatient $patient) => [
|
||||
'medical_history_id' => $patient->rf_medicalhistory_id,
|
||||
'department_patient_id' => $patient->rf_department_patient_id,
|
||||
'comment' => $patient->comment,
|
||||
])->values()->all(),
|
||||
unwantedEvents: $report->unwantedEvents
|
||||
->map(fn (UnwantedEvent $event) => [
|
||||
'title' => $event->title,
|
||||
'comment' => $event->comment,
|
||||
'is_visible' => (bool) $event->is_visible,
|
||||
])->values()->all(),
|
||||
reportId: (int) $report->report_id,
|
||||
createdAt: $report->created_at ? new \DateTimeImmutable($report->created_at->format('Y-m-d H:i:s')) : null,
|
||||
sentAt: $report->sent_at ? new \DateTimeImmutable($report->sent_at->format('Y-m-d H:i:s')) : null,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user