Перевод на DDD
This commit is contained in:
22
app/Domain/ReportDuty/Actions/CreateReportDutyAction.php
Normal file
22
app/Domain/ReportDuty/Actions/CreateReportDutyAction.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\ReportDuty\Actions;
|
||||
|
||||
use App\Domain\ReportDuty\Contracts\ReportDutyRepositoryInterface;
|
||||
use App\Domain\ReportDuty\DTO\CreateReportDutyDto;
|
||||
use App\Domain\ReportDuty\Events\ReportDutyCreated;
|
||||
use App\Domain\ReportDuty\Models\ReportDuty;
|
||||
use App\Models\User;
|
||||
use App\Services\DateRange;
|
||||
|
||||
class CreateReportDutyAction
|
||||
{
|
||||
public function __construct(
|
||||
protected ReportDutyRepositoryInterface $repository,
|
||||
) {}
|
||||
|
||||
public function execute(CreateReportDutyDto $dto): ReportDuty
|
||||
{
|
||||
return $this->repository->findOrCreate($dto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\ReportDuty\Actions;
|
||||
|
||||
use App\Domain\ReportDuty\Contracts\ReportDutySnapshotRepositoryInterface;
|
||||
use App\Domain\ReportDuty\Models\ReportDuty;
|
||||
use App\Domain\ReportDuty\Services\ReportDutyStatisticsCalculator;
|
||||
use App\Infrastructure\Services\MisPatientSnapshotProvider;
|
||||
use App\Infrastructure\Services\NurseReportPatientSnapshotProvider;
|
||||
use App\Services\DateRange;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class GenerateAndSaveReportSnapshotAction
|
||||
{
|
||||
public function __construct(
|
||||
protected MisPatientSnapshotProvider $misProvider,
|
||||
protected NurseReportPatientSnapshotProvider $nurseProvider,
|
||||
protected ReportDutySnapshotRepositoryInterface $snapshotRepository,
|
||||
protected ReportDutyStatisticsCalculator $statisticsCalculator,
|
||||
protected SaveReportMetricsAction $saveMetricsAction,
|
||||
) {}
|
||||
|
||||
public function execute(
|
||||
ReportDuty $report,
|
||||
DateRange $dateRange,
|
||||
?int $departmentId = null,
|
||||
?int $userId = null
|
||||
): array {
|
||||
$departmentId = $departmentId ?? $report->department->rf_mis_department_id ?? $report->rf_department_id;
|
||||
$userId = $userId ?? $report->rf_user_id;
|
||||
|
||||
// 1. Определяем, есть ли отчёт медсестры за этот период
|
||||
$nurseReportExists = \App\Models\ReportNurse::where('rf_department_id', $report->rf_department_id)
|
||||
->where('period_start', $report->period_start)
|
||||
->where('period_end', $report->period_end)
|
||||
->exists();
|
||||
|
||||
// 2. Получаем данные пациентов через соответствующий провайдер
|
||||
if ($nurseReportExists) {
|
||||
$patients = $this->nurseProvider->getPatients($dateRange, $departmentId);
|
||||
} else {
|
||||
$patients = $this->misProvider->getPatients($dateRange, $departmentId);
|
||||
}
|
||||
|
||||
// 3. Извлекаем миграции и реанимации из пациентов для сохранения
|
||||
$migrations = collect();
|
||||
$reanimations = collect();
|
||||
|
||||
foreach ($patients as $patient) {
|
||||
// Преобразуем миграции в DTO
|
||||
foreach ($patient->migrations as $migData) {
|
||||
$migrations->push(new \App\Domain\ReportDuty\DTO\MigrationSnapshotData(
|
||||
id: $migData['id'],
|
||||
medicalHistoryId: $patient->id,
|
||||
ingoingDate: $migData['ingoing_date'],
|
||||
outDate: $migData['out_date'],
|
||||
diagnosisId: $migData['diagnosis_id'],
|
||||
diagnosisCode: $migData['diagnosis_code'],
|
||||
diagnosisName: $migData['diagnosis_name'],
|
||||
interruptedEventId: $migData['interrupted_event_id'],
|
||||
stationarBranchId: $migData['stationar_branch_id'],
|
||||
departmentId: $migData['department_id'],
|
||||
visitResultId: $migData['visit_result_id'],
|
||||
statCureResultId: $migData['stat_cure_result_id'],
|
||||
userId: $migData['user_id'],
|
||||
misUserId: $migData['mis_user_id'],
|
||||
comment: $migData['comment'],
|
||||
reanimations: $migData['reanimations'] ?? [],
|
||||
));
|
||||
}
|
||||
// Реанимации будем брать из миграций, но можно и отдельно, здесь пока пропускаем
|
||||
// (в репозитории они будут обработаны из миграций, но у нас нет отдельного хранилища)
|
||||
}
|
||||
|
||||
// Заметка: реанимации сейчас хранятся внутри миграций, но в репозитории мы ожидаем их отдельно.
|
||||
// Чтобы упростить, можно либо передать пустую коллекцию, либо извлечь из миграций.
|
||||
// В оригинале они сохранялись в отдельной таблице. Мы можем передать пустую коллекцию,
|
||||
// но если хотим сохранять реанимации, нужно их собрать из $patient->migrations['reanimations'].
|
||||
|
||||
// Я пока передам пустую коллекцию, так как в провайдерах реанимации не извлекаются
|
||||
// (кроме МИС, но там они внутри миграций). Можно позже доработать.
|
||||
|
||||
// 4. Сохраняем снимок в БД
|
||||
$saveResult = $this->snapshotRepository->upsertSnapshot(
|
||||
$report->id,
|
||||
$patients,
|
||||
$migrations->lazy(),
|
||||
collect()->lazy(), // пока без реанимаций
|
||||
$userId,
|
||||
$departmentId
|
||||
);
|
||||
|
||||
// 5. Рассчитываем статистику
|
||||
$statistics = $this->statisticsCalculator->calculate($patients, $dateRange);
|
||||
|
||||
// 6. Сохраняем метрики
|
||||
$this->saveMetricsAction->execute($report, $statistics, 0); // staff = 0 пока
|
||||
|
||||
Log::info('Report snapshot generated', [
|
||||
'report_id' => $report->id,
|
||||
'saved_patients' => $saveResult['savedPatients'],
|
||||
'saved_migrations' => $saveResult['savedMigrations'],
|
||||
'statistics' => $statistics,
|
||||
]);
|
||||
|
||||
return [
|
||||
'statistics' => $statistics,
|
||||
'saved' => $saveResult,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\ReportDuty\Actions;
|
||||
|
||||
use App\Domain\ReportDuty\Contracts\ReportDutyObservablePatientsInterface;
|
||||
use App\Domain\ReportDuty\Models\ReportDuty;
|
||||
|
||||
class SaveObservablePatientsAction
|
||||
{
|
||||
public function __construct(
|
||||
protected ReportDutyObservablePatientsInterface $observablePatients
|
||||
) {}
|
||||
|
||||
public function execute(ReportDuty $report, array $observables): void
|
||||
{
|
||||
$this->observablePatients->upsertObservations($report, $observables);
|
||||
}
|
||||
}
|
||||
79
app/Domain/ReportDuty/Actions/SaveReportMetricsAction.php
Normal file
79
app/Domain/ReportDuty/Actions/SaveReportMetricsAction.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\ReportDuty\Actions;
|
||||
|
||||
use App\Domain\ReportDuty\Contracts\DutyMetricRepositoryInterface;
|
||||
use App\Domain\ReportDuty\DTO\SnapshotStatistics;
|
||||
use App\Domain\ReportDuty\Models\ReportDuty;
|
||||
use App\Models\DepartmentMetrikaDefault;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class SaveReportMetricsAction
|
||||
{
|
||||
public function __construct(
|
||||
protected DutyMetricRepositoryInterface $metricRepository,
|
||||
) {}
|
||||
|
||||
public function execute(ReportDuty $report, SnapshotStatistics $stats, int $staff = 0, array $statsOverride = []): void
|
||||
{
|
||||
$byStatus = $stats->byStatus;
|
||||
$byUrgency = $stats->byUrgency;
|
||||
$admitted = $stats->admitted;
|
||||
|
||||
// === Базовые счётчики ===
|
||||
$patientsIsRecipient = $statsOverride['recipient'] ?? ($byStatus['recipient'] ?? 0);
|
||||
$patientsInDepartment = $statsOverride['in_department'] ?? ($byStatus['in_department'] ?? 0);
|
||||
$patientsIsDischarged = $statsOverride['outcome'] ?? $stats->outcome;
|
||||
$patientsIsTransferred = $stats->transferred;
|
||||
$patientsIsDeceased = $byStatus['deceased'] ?? 0;
|
||||
|
||||
// Ср. койко-день
|
||||
$totalPatients = $stats->totalPatients;
|
||||
$totalBedDays = $stats->totalBedDays;
|
||||
$avgBedDay = $totalPatients > 0 ? round($totalBedDays / $totalPatients, 2) : 0;
|
||||
|
||||
// Пред. опер. койко-день
|
||||
$patientsWithOps = $stats->patientsWithOperations;
|
||||
$totalPreOpDays = $stats->totalPreopBedDays;
|
||||
$avgPreOpBedDay = $patientsWithOps > 0 ? round($totalPreOpDays / $patientsWithOps, 2) : 0;
|
||||
|
||||
// % загруженности
|
||||
$bedsInDepartment = DepartmentMetrikaDefault::where('rf_department_id', $report->rf_department_id)
|
||||
->where('rf_metrika_item_id', 1)
|
||||
->where('date_end', '>', Carbon::now())
|
||||
->value('value') ?? 0;
|
||||
|
||||
$occupancyPercent = $bedsInDepartment > 0 ? round(($patientsInDepartment * 100) / $bedsInDepartment, 2) : 0;
|
||||
|
||||
// % летальности
|
||||
$mortalityPercent = $totalPatients > 0 ? round(($patientsIsDeceased * 100) / $totalPatients, 2) : 0;
|
||||
|
||||
// Операции
|
||||
$totalOperations = $stats->totalOperations;
|
||||
$plannedOperations = $stats->plannedOperations;
|
||||
$urgentOperations = $stats->urgentOperations;
|
||||
|
||||
// === Сохранение метрик ===
|
||||
$this->metricRepository->saveMetric($report->id, 1, $bedsInDepartment); // Кол-во коек
|
||||
$this->metricRepository->saveMetric($report->id, 8, $patientsInDepartment); // Пациентов в отделении
|
||||
$this->metricRepository->saveMetric($report->id, 3, $patientsIsRecipient); // Поступило
|
||||
$this->metricRepository->saveMetric($report->id, 15, $patientsIsDischarged); // Выписано
|
||||
$this->metricRepository->saveMetric($report->id, 7, $patientsIsDischarged); // Выписано (дубль?)
|
||||
$this->metricRepository->saveMetric($report->id, 13, $patientsIsTransferred); // Переведено
|
||||
$this->metricRepository->saveMetric($report->id, 9, $patientsIsDeceased); // Умерло
|
||||
|
||||
$this->metricRepository->saveMetric($report->id, 4, $admitted['planned'] ?? 0); // Планово поступило
|
||||
$this->metricRepository->saveMetric($report->id, 12, $admitted['urgent'] ?? 0); // Экстренно поступило
|
||||
|
||||
$this->metricRepository->saveMetric($report->id, 22, $occupancyPercent); // % загруженности
|
||||
$this->metricRepository->saveMetric($report->id, 25, round($totalBedDays, 2)); // Всего койко-дней
|
||||
$this->metricRepository->saveMetric($report->id, 18, $avgBedDay); // Ср. койко-день
|
||||
$this->metricRepository->saveMetric($report->id, 26, round($totalPreOpDays, 2)); // Пред. опер. койко-день (сумма)
|
||||
$this->metricRepository->saveMetric($report->id, 27, $patientsWithOps); // Пациентов с операциями (знаменатель)
|
||||
$this->metricRepository->saveMetric($report->id, 21, $avgPreOpBedDay); // Ср. Пред. опер. койко-день
|
||||
$this->metricRepository->saveMetric($report->id, 19, $mortalityPercent); // % летальности
|
||||
$this->metricRepository->saveMetric($report->id, 11, $plannedOperations); // Плановых операций
|
||||
$this->metricRepository->saveMetric($report->id, 10, $urgentOperations); // Экстренных операций
|
||||
$this->metricRepository->saveMetric($report->id, 17, $staff); // Мед. персонал
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\ReportDuty\Actions;
|
||||
|
||||
class UpdateMetricsReportDutyAction
|
||||
{
|
||||
|
||||
}
|
||||
8
app/Domain/ReportDuty/Actions/UpdateReportDutyAction.php
Normal file
8
app/Domain/ReportDuty/Actions/UpdateReportDutyAction.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\ReportDuty\Actions;
|
||||
|
||||
class UpdateReportDutyAction
|
||||
{
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user