isEmpty()) { return ['savedPatients' => 0, 'savedMigrations' => 0, 'savedReanimations' => 0]; } $savedPatients = 0; $savedMigrations = 0; $savedReanimations = 0; DB::transaction(function () use ( $reportDutyId, $patients, $migrations, $reanimations, $userId, $departmentId, &$savedPatients, &$savedMigrations, &$savedReanimations ) { // Получаем дату окончания периода отчета (для фильтрации дат смерти) $reportEndDate = DB::table('report_duties') ->where('id', $reportDutyId) ->value('period_end'); // === 1. Подготовка данных пациентов === $patientBatch = []; foreach ($patients as $patient) { /** @var PatientSnapshotData $patient */ // Преобразуем в массив для upsert $patientData = [ 'report_duty_id' => $reportDutyId, 'source_type' => $patient->sourceType, 'original_id' => $patient->id, 'medical_card_number' => $patient->medicalCardNumber, 'full_name' => $patient->fullName, 'birth_date' => $patient->birthDate, 'recipient_date' => $patient->recipientDate, 'male' => $patient->male, 'urgency_id' => $patient->urgencyId, 'comment' => $patient->comment, 'user_id' => $userId, 'profit_type_id' => $patient->profitTypeId, ]; // Обработка даты смерти и выбытия if (!empty($patient->deathDate)) { $deathDate = Carbon::parse($patient->deathDate); $extractDate = $patient->extractDate ? Carbon::parse($patient->extractDate) : null; $visitResultId = $patient->visitResultId; // Если исход смерти (visit_result_id 5 или 15) и дата смерти позже даты отчёта - очищаем if (in_array($visitResultId, [5, 15]) && $deathDate->gt($reportEndDate)) { $patientData['death_date'] = null; } else { $patientData['death_date'] = $deathDate->format('Y-m-d'); } // Если пациент умер, а даты выбытия нет, используем дату смерти if (!empty($patientData['death_date']) && empty($patientData['extract_date'])) { $patientData['extract_date'] = $patientData['death_date']; } } else { // Если нет даты смерти, используем extract_date как есть $patientData['extract_date'] = $patient->extractDate; $patientData['death_date'] = null; } // Добавляем visit_result_id (если есть) $patientData['visit_result_id'] = $patient->visitResultId; $patientData['extract_date'] = $patientData['extract_date'] ?? null; $patientBatch[] = $patientData; } // === 2. Upsert пациентов === $patientUniqueBy = ['report_duty_id', 'source_type', 'original_id']; $patientUpdateColumns = array_diff(array_keys($patientBatch[0]), $patientUniqueBy); DB::table('report_duty_patients')->upsert( $patientBatch, $patientUniqueBy, $patientUpdateColumns ); $savedPatients = count($patientBatch); // === 3. Получаем ID сохранённых пациентов (для связей с миграциями) === $patientIds = []; if ($migrations->isNotEmpty() || $reanimations->isNotEmpty()) { $patientIds = DB::table('report_duty_patients') ->where('report_duty_id', $reportDutyId) ->pluck('id', 'original_id') ->toArray(); } // === 4. Подготовка и Upsert миграций === if ($migrations->isNotEmpty() && !empty($patientIds)) { $migrationBatch = []; /** @var MigrationSnapshotData $migration */ foreach ($migrations as $migration) { $patientDbId = $patientIds[$migration->medicalHistoryId] ?? null; if (!$patientDbId) { continue; } $migrationBatch[] = [ 'medical_history_id' => $patientDbId, 'original_id' => $migration->id, 'ingoing_date' => $migration->ingoingDate, 'out_date' => $migration->outDate, 'diagnosis_id' => $migration->diagnosisId, 'diagnosis_code' => $migration->diagnosisCode, 'diagnosis_name' => $migration->diagnosisName, 'interrupted_event_id' => $migration->interruptedEventId, 'stationar_branch_id' => $migration->stationarBranchId, 'department_id' => $migration->departmentId, 'visit_result_id' => $migration->visitResultId, 'stat_cure_result_id' => $migration->statCureResultId, 'user_id' => $migration->userId, 'mis_user_id' => $migration->misUserId, 'comment' => $migration->comment, ]; } if (!empty($migrationBatch)) { $migrationUniqueBy = ['medical_history_id', 'ingoing_date']; $migrationUpdateColumns = array_diff(array_keys($migrationBatch[0]), $migrationUniqueBy); DB::table('report_duty_migration_patients')->upsert( $migrationBatch, $migrationUniqueBy, $migrationUpdateColumns ); $savedMigrations = count($migrationBatch); // === 5. Получаем ID сохранённых миграций для реанимаций === // Строим маппинг [medical_history_id][original_id] => id $migrationIds = []; $migrationRecords = DB::table('report_duty_migration_patients') ->whereIn('medical_history_id', array_values($patientIds)) ->get(['id', 'medical_history_id', 'original_id']); foreach ($migrationRecords as $record) { $migrationIds[$record->medical_history_id][$record->original_id] = $record->id; } // === 6. Подготовка и Upsert реанимаций === if ($reanimations->isNotEmpty()) { $reanimationBatch = []; /** @var ReanimationSnapshotData $reanimation */ foreach ($reanimations as $reanimation) { $patientDbId = $patientIds[$reanimation->medicalHistoryId] ?? null; if (!$patientDbId) { continue; } $migrationDbId = $migrationIds[$patientDbId][$reanimation->migrationPatientId] ?? null; if (!$migrationDbId) { continue; } $reanimationBatch[] = [ 'migration_patient_id' => $migrationDbId, 'medical_history_id' => $patientDbId, 'original_id' => $reanimation->id, 'in_date' => $reanimation->inDate, 'out_date' => $reanimation->outDate, 'description' => $reanimation->description, 'stationar_branch_id' => $reanimation->stationarBranchId, 'migration_stationar_branch_id' => $reanimation->migrationStationarBranchId, 'migration_department_id' => $reanimation->migrationDepartmentId, 'doctor_id' => $reanimation->doctorId, 'user_id' => $reanimation->userId, 'mis_user_id' => $reanimation->misUserId, 'comment' => $reanimation->comment, ]; } if (!empty($reanimationBatch)) { $reanimationUniqueBy = ['migration_patient_id', 'in_date']; $reanimationUpdateColumns = array_diff(array_keys($reanimationBatch[0]), $reanimationUniqueBy); DB::table('report_duty_reanimations')->upsert( $reanimationBatch, $reanimationUniqueBy, $reanimationUpdateColumns ); $savedReanimations = count($reanimationBatch); } } } } }); return [ 'savedPatients' => $savedPatients, 'savedMigrations' => $savedMigrations, 'savedReanimations' => $savedReanimations, ]; } }