integer('StationarBranchID')->primary(); $table->integer('rf_DepartmentID'); }); Schema::create('reports', function (Blueprint $table) { $table->integer('report_id')->primary(); $table->date('created_at'); $table->dateTime('sent_at')->nullable(); $table->integer('rf_department_id'); $table->integer('rf_user_id')->nullable(); $table->integer('rf_lpudoctor_id')->nullable(); }); Schema::create('medical_history_snapshots', function (Blueprint $table) { $table->integer('medical_history_snapshot_id')->primary(); $table->integer('rf_report_id'); $table->integer('rf_medicalhistory_id')->nullable(); $table->integer('rf_department_patient_id')->nullable(); $table->string('patient_type'); $table->string('patient_uid')->nullable(); $table->string('patient_source_type')->nullable(); $table->string('patient_kind')->nullable(); $table->string('full_name')->nullable(); $table->date('birth_date')->nullable(); $table->string('diagnosis_code')->nullable(); $table->string('diagnosis_name')->nullable(); $table->dateTime('admitted_at')->nullable(); $table->string('outcome_type')->nullable(); $table->dateTime('outcome_at')->nullable(); $table->boolean('is_manual')->default(false); $table->timestamps(); }); Schema::create('department_patients', function (Blueprint $table) { $table->integer('department_patient_id')->primary(); $table->integer('rf_department_id'); $table->string('source_type')->default('manual'); $table->integer('rf_medicalhistory_id')->nullable(); $table->string('full_name'); $table->date('birth_date')->nullable(); $table->string('patient_kind')->nullable(); $table->string('diagnosis_code')->nullable(); $table->string('diagnosis_name')->nullable(); $table->dateTime('admitted_at')->nullable(); $table->boolean('is_current')->default(true); $table->string('outcome_type')->nullable(); $table->dateTime('outcome_at')->nullable(); $table->integer('created_by')->nullable(); $table->dateTime('linked_to_mis_at')->nullable(); $table->timestamps(); }); Schema::create('observation_patients', function (Blueprint $table) { $table->integer('observation_patient_id')->primary(); $table->integer('rf_report_id')->nullable(); $table->integer('rf_department_id')->nullable(); $table->integer('rf_medicalhistory_id')->nullable(); $table->integer('rf_department_patient_id')->nullable(); $table->text('comment')->nullable(); }); Schema::create('stt_medicalhistory', function (Blueprint $table) { $table->integer('MedicalHistoryID')->primary(); $table->integer('rf_EmerSignID')->nullable(); $table->integer('rf_kl_VisitResultID')->default(0); $table->dateTime('DateRecipient')->nullable(); $table->dateTime('DateExtract')->nullable(); }); Schema::create('stt_migrationpatient', function (Blueprint $table) { $table->integer('MigrationPatientID')->primary(); $table->integer('rf_MedicalHistoryID'); $table->integer('rf_StationarBranchID'); $table->integer('rf_kl_VisitResultID')->default(0); $table->integer('rf_kl_StatCureResultID')->default(0); $table->dateTime('DateIngoing')->nullable(); $table->dateTime('DateOut')->nullable(); }); Schema::create('stt_surgicaloperation', function (Blueprint $table) { $table->integer('SurgicalOperationID')->primary(); $table->integer('rf_MedicalHistoryID')->nullable(); $table->integer('rf_StationarBranchID')->nullable(); $table->integer('rf_kl_ServiceMedicalID')->nullable(); $table->dateTime('Date')->nullable(); }); Schema::create('stt_operationpurpose', function (Blueprint $table) { $table->integer('OperationPurposeID')->primary(); $table->integer('rf_SurgicalOperationID'); $table->integer('rf_OperationStatusID'); }); Schema::create('stt_diagnos', function (Blueprint $table) { $table->integer('DiagnosID')->primary(); $table->integer('rf_MigrationPatientID')->nullable(); $table->integer('rf_DiagnosTypeID')->nullable(); $table->integer('rf_MKBID')->nullable(); }); Schema::create('oms_mkb', function (Blueprint $table) { $table->integer('MKBID')->primary(); $table->string('DS')->nullable(); $table->string('NAME')->nullable(); }); Schema::create('oms_servicemedical', function (Blueprint $table) { $table->integer('ServiceMedicalID')->primary(); }); }); afterEach(function () { Carbon::setTestNow(); \Mockery::close(); }); function reportDateRange(string $start, string $end): DateRange { return new DateRange( startDate: Carbon::parse($start, 'Asia/Yakutsk'), endDate: Carbon::parse($end, 'Asia/Yakutsk'), startDateRaw: $start, endDateRaw: $end, isOneDay: true, ); } function makeUser(bool $isHead = false, bool $isAdmin = false): User { $user = new class extends User { public bool $head = false; public bool $admin = false; public function isHeadOfDepartment() { return $this->head; } public function isAdmin() { return $this->admin; } }; $user->head = $isHead; $user->admin = $isAdmin; return $user; } function makeUnifiedPatientService(?PatientService $patientService = null): UnifiedPatientService { return new UnifiedPatientService($patientService ?? app(PatientService::class)); } it('returns only today recipients and current in-department patients for plan and emergency', function () { $service = app(PatientService::class); $dateRange = reportDateRange('2026-04-08 06:00:00', '2026-04-09 06:00:00'); DB::table('stt_medicalhistory')->insert([ [ 'MedicalHistoryID' => 1, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-08 08:00:00', 'DateExtract' => '1900-01-01 00:00:00', ], [ 'MedicalHistoryID' => 2, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-07 08:00:00', 'DateExtract' => '1900-01-01 00:00:00', ], [ 'MedicalHistoryID' => 3, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 1, 'DateRecipient' => '2026-04-08 09:00:00', 'DateExtract' => '2026-04-08 22:00:00', ], [ 'MedicalHistoryID' => 4, 'rf_EmerSignID' => 2, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-08 10:00:00', 'DateExtract' => '1900-01-01 00:00:00', ], [ 'MedicalHistoryID' => 5, 'rf_EmerSignID' => 2, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-06 08:00:00', 'DateExtract' => '1900-01-01 00:00:00', ], [ 'MedicalHistoryID' => 6, 'rf_EmerSignID' => 2, 'rf_kl_VisitResultID' => 1, 'DateRecipient' => '2026-04-08 11:00:00', 'DateExtract' => '2026-04-08 23:00:00', ], [ 'MedicalHistoryID' => 7, 'rf_EmerSignID' => 4, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-08 12:00:00', 'DateExtract' => '1900-01-01 00:00:00', ], ]); DB::table('stt_migrationpatient')->insert([ [ 'MigrationPatientID' => 1, 'rf_MedicalHistoryID' => 1, 'rf_StationarBranchID' => 10, 'rf_kl_VisitResultID' => 0, 'rf_kl_StatCureResultID' => 0, 'DateIngoing' => '2026-04-08 08:00:00', 'DateOut' => '1900-01-01 00:00:00', ], [ 'MigrationPatientID' => 2, 'rf_MedicalHistoryID' => 2, 'rf_StationarBranchID' => 10, 'rf_kl_VisitResultID' => 0, 'rf_kl_StatCureResultID' => 0, 'DateIngoing' => '2026-04-07 08:00:00', 'DateOut' => '1900-01-01 00:00:00', ], [ 'MigrationPatientID' => 3, 'rf_MedicalHistoryID' => 3, 'rf_StationarBranchID' => 10, 'rf_kl_VisitResultID' => 1, 'rf_kl_StatCureResultID' => 1, 'DateIngoing' => '2026-04-08 09:00:00', 'DateOut' => '2026-04-08 22:00:00', ], [ 'MigrationPatientID' => 4, 'rf_MedicalHistoryID' => 4, 'rf_StationarBranchID' => 10, 'rf_kl_VisitResultID' => 0, 'rf_kl_StatCureResultID' => 0, 'DateIngoing' => '2026-04-08 10:00:00', 'DateOut' => '1900-01-01 00:00:00', ], [ 'MigrationPatientID' => 5, 'rf_MedicalHistoryID' => 5, 'rf_StationarBranchID' => 10, 'rf_kl_VisitResultID' => 0, 'rf_kl_StatCureResultID' => 0, 'DateIngoing' => '2026-04-06 08:00:00', 'DateOut' => '1900-01-01 00:00:00', ], [ 'MigrationPatientID' => 6, 'rf_MedicalHistoryID' => 6, 'rf_StationarBranchID' => 10, 'rf_kl_VisitResultID' => 1, 'rf_kl_StatCureResultID' => 1, 'DateIngoing' => '2026-04-08 11:00:00', 'DateOut' => '2026-04-08 23:00:00', ], [ 'MigrationPatientID' => 7, 'rf_MedicalHistoryID' => 7, 'rf_StationarBranchID' => 10, 'rf_kl_VisitResultID' => 0, 'rf_kl_StatCureResultID' => 0, 'DateIngoing' => '2026-04-08 12:00:00', 'DateOut' => '1900-01-01 00:00:00', ], ]); $planPatients = $service->getPlanOrEmergencyPatients('plan', false, 10, $dateRange, false, false, true); $emergencyPatients = $service->getPlanOrEmergencyPatients('emergency', false, 10, $dateRange, false, false, true); expect($planPatients->pluck('MedicalHistoryID')->all())->toBe([3, 1, 2]) ->and($planPatients->where('MedicalHistoryID', 1)->first()->is_recipient_today)->toBeTrue() ->and($planPatients->where('MedicalHistoryID', 2)->first()->is_recipient_today)->toBeFalse() ->and($planPatients->where('MedicalHistoryID', 3)->first()->is_recipient_today)->toBeTrue() ->and($service->getPatientsCountWithCurrent('plan', false, 10, $dateRange))->toBe(3) ->and($emergencyPatients->pluck('MedicalHistoryID')->all())->toBe([7, 6, 4, 5]) ->and($emergencyPatients->where('MedicalHistoryID', 6)->first()->is_recipient_today)->toBeTrue() ->and($service->getPatientsCountWithCurrent('emergency', false, 10, $dateRange))->toBe(4); }); it('treats 2222-01-01 as current hospitalization sentinel', function () { $service = app(PatientService::class); $dateRange = reportDateRange('2026-04-08 06:00:00', '2026-04-09 06:00:00'); DB::table('stt_medicalhistory')->insert([ [ 'MedicalHistoryID' => 31, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-08 08:00:00', 'DateExtract' => '2222-01-01 00:00:00', ], ]); DB::table('stt_migrationpatient')->insert([ [ 'MigrationPatientID' => 31, 'rf_MedicalHistoryID' => 31, 'rf_StationarBranchID' => 10, 'rf_kl_VisitResultID' => 0, 'rf_kl_StatCureResultID' => 0, 'DateIngoing' => '2026-04-08 08:00:00', 'DateOut' => '1900-01-01 00:00:00', ], ]); $patients = $service->getPlanOrEmergencyPatients('plan', false, 10, $dateRange, false, false, true); expect($patients->pluck('MedicalHistoryID')->all())->toBe([31]) ->and($service->getPatientsCountWithCurrent('plan', false, 10, $dateRange))->toBe(1); }); it('uses snapshots for head on current-day plan requests', function () { DB::table('stt_stationarbranch')->insert([ 'StationarBranchID' => 10, 'rf_DepartmentID' => 100, ]); $dateRange = reportDateRange('2026-04-08 06:00:00', '2026-04-09 06:00:00'); $department = new Department; $department->department_id = 1; $department->rf_mis_department_id = 100; $user = makeUser(isHead: true); $expected = collect([(object) ['MedicalHistoryID' => 1]]); $patientService = \Mockery::mock(PatientService::class); $snapshotService = \Mockery::mock(SnapshotService::class); $snapshotService ->shouldReceive('getPatientsFromOneDayCurrentSnapshots') ->once() ->with('plan', [], false, []) ->andReturn($expected); $service = new ReportService( app(DateRangeService::class), makeUnifiedPatientService($patientService), $patientService, $snapshotService, \Mockery::mock(\App\Services\StatisticsService::class) ); expect($service->getPatientsByStatus($department, $user, 'plan', $dateRange))->toBe($expected); }); it('uses snapshots for historical head plan requests and counts unique snapshot patients', function () { DB::table('stt_stationarbranch')->insert([ 'StationarBranchID' => 10, 'rf_DepartmentID' => 100, ]); DB::table('reports')->insert([ 'report_id' => 77, 'created_at' => '2026-04-08', 'sent_at' => '2026-04-08 06:00:00', 'rf_department_id' => 1, 'rf_user_id' => 1, 'rf_lpudoctor_id' => 1, ]); DB::table('medical_history_snapshots')->insert([ [ 'medical_history_snapshot_id' => 1, 'rf_report_id' => 77, 'rf_medicalhistory_id' => 10, 'patient_type' => 'plan', 'patient_uid' => 'mis:10', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Patient 10', 'created_at' => now(), 'updated_at' => now(), ], [ 'medical_history_snapshot_id' => 2, 'rf_report_id' => 77, 'rf_medicalhistory_id' => 10, 'patient_type' => 'plan', 'patient_uid' => 'mis:10', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Patient 10', 'created_at' => now(), 'updated_at' => now(), ], [ 'medical_history_snapshot_id' => 3, 'rf_report_id' => 77, 'rf_medicalhistory_id' => 11, 'patient_type' => 'plan', 'patient_uid' => 'mis:11', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Patient 11', 'created_at' => now(), 'updated_at' => now(), ], ]); $dateRange = new DateRange( startDate: Carbon::parse('2026-04-07 06:00:00', 'Asia/Yakutsk'), endDate: Carbon::parse('2026-04-08 06:00:00', 'Asia/Yakutsk'), startDateRaw: '2026-04-07 06:00:00', endDateRaw: '2026-04-08 06:00:00', isOneDay: false, ); $department = new Department; $department->department_id = 1; $department->rf_mis_department_id = 100; $user = makeUser(isHead: true); $expected = collect([(object) ['MedicalHistoryID' => 10]]); $patientService = \Mockery::mock(PatientService::class); $snapshotService = \Mockery::mock(SnapshotService::class); $snapshotService ->shouldReceive('getPatientsFromSnapshots') ->once() ->with('plan', [77], 10, false, true, [77]) ->andReturn($expected); $service = new ReportService( app(DateRangeService::class), makeUnifiedPatientService($patientService), $patientService, $snapshotService, \Mockery::mock(\App\Services\StatisticsService::class) ); expect($service->getPatientsByStatus($department, $user, 'plan', $dateRange))->toBe($expected) ->and($service->getPatientsCountByStatus($department, $user, 'plan', $dateRange))->toBe(2); }); it('filters historical head plan snapshots by latest report and marks only latest recipients', function () { DB::table('stt_stationarbranch')->insert([ 'StationarBranchID' => 10, 'rf_DepartmentID' => 100, ]); DB::table('reports')->insert([ [ 'report_id' => 76, 'created_at' => '2026-04-07', 'sent_at' => '2026-04-07 06:00:00', 'rf_department_id' => 1, 'rf_user_id' => 1, 'rf_lpudoctor_id' => 1, ], [ 'report_id' => 77, 'created_at' => '2026-04-08', 'sent_at' => '2026-04-08 06:00:00', 'rf_department_id' => 1, 'rf_user_id' => 1, 'rf_lpudoctor_id' => 1, ], ]); DB::table('stt_medicalhistory')->insert([ [ 'MedicalHistoryID' => 10, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 1, 'DateRecipient' => '2026-04-07 08:00:00', 'DateExtract' => '2026-04-08 12:00:00', ], [ 'MedicalHistoryID' => 11, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-07 10:00:00', 'DateExtract' => '1900-01-01 00:00:00', ], [ 'MedicalHistoryID' => 12, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-08 08:00:00', 'DateExtract' => '1900-01-01 00:00:00', ], ]); DB::table('medical_history_snapshots')->insert([ [ 'medical_history_snapshot_id' => 1, 'rf_report_id' => 76, 'rf_medicalhistory_id' => 10, 'patient_type' => 'plan', 'patient_uid' => 'mis:10', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Patient 10', 'admitted_at' => '2026-04-07 08:00:00', 'created_at' => now(), 'updated_at' => now(), ], [ 'medical_history_snapshot_id' => 2, 'rf_report_id' => 77, 'rf_medicalhistory_id' => 11, 'patient_type' => 'plan', 'patient_uid' => 'mis:11', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Patient 11', 'admitted_at' => '2026-04-07 10:00:00', 'created_at' => now(), 'updated_at' => now(), ], [ 'medical_history_snapshot_id' => 3, 'rf_report_id' => 77, 'rf_medicalhistory_id' => 12, 'patient_type' => 'plan', 'patient_uid' => 'mis:12', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Patient 12', 'admitted_at' => '2026-04-08 08:00:00', 'created_at' => now(), 'updated_at' => now(), ], [ 'medical_history_snapshot_id' => 4, 'rf_report_id' => 77, 'rf_medicalhistory_id' => 12, 'patient_type' => 'recipient', 'patient_uid' => 'mis:12', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Patient 12', 'admitted_at' => '2026-04-08 08:00:00', 'created_at' => now(), 'updated_at' => now(), ], ]); $dateRange = new DateRange( startDate: Carbon::parse('2026-04-07 06:00:00', 'Asia/Yakutsk'), endDate: Carbon::parse('2026-04-08 06:00:00', 'Asia/Yakutsk'), startDateRaw: '2026-04-07 06:00:00', endDateRaw: '2026-04-08 06:00:00', isOneDay: false, ); $department = new Department; $department->department_id = 1; $department->rf_mis_department_id = 100; $user = makeUser(isHead: true); $service = new ReportService( app(DateRangeService::class), makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), new SnapshotService(makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), app(DateRangeService::class)), \Mockery::mock(\App\Services\StatisticsService::class) ); $patients = $service->getPatientsByStatus($department, $user, 'plan', $dateRange); expect($patients->pluck('medicalHistoryId')->all())->toBe([12, 11]) ->and($patients->firstWhere('medicalHistoryId', 12)->isRecipientToday)->toBeTrue() ->and($patients->firstWhere('medicalHistoryId', 11)->isRecipientToday)->toBeFalse() ->and($service->getPatientsCountByStatus($department, $user, 'plan', $dateRange))->toBe(2); }); it('uses current snapshots for head one-day plan list and marks recipients separately', function () { DB::table('stt_stationarbranch')->insert([ 'StationarBranchID' => 10, 'rf_DepartmentID' => 100, ]); DB::table('reports')->insert([ 'report_id' => 88, 'created_at' => '2026-04-09', 'sent_at' => '2026-04-09 06:00:00', 'rf_department_id' => 1, 'rf_user_id' => 1, 'rf_lpudoctor_id' => 1, ]); DB::table('stt_medicalhistory')->insert([ [ 'MedicalHistoryID' => 21, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-08 08:00:00', 'DateExtract' => '1900-01-01 00:00:00', ], [ 'MedicalHistoryID' => 22, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-07 08:00:00', 'DateExtract' => '1900-01-01 00:00:00', ], [ 'MedicalHistoryID' => 23, 'rf_EmerSignID' => 2, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-08 09:00:00', 'DateExtract' => '1900-01-01 00:00:00', ], ]); DB::table('medical_history_snapshots')->insert([ [ 'medical_history_snapshot_id' => 10, 'rf_report_id' => 88, 'rf_medicalhistory_id' => 21, 'patient_type' => 'current', 'patient_uid' => 'mis:21', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Patient 21', 'admitted_at' => '2026-04-08 08:00:00', 'created_at' => now(), 'updated_at' => now(), ], [ 'medical_history_snapshot_id' => 11, 'rf_report_id' => 88, 'rf_medicalhistory_id' => 22, 'patient_type' => 'current', 'patient_uid' => 'mis:22', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Patient 22', 'admitted_at' => '2026-04-07 08:00:00', 'created_at' => now(), 'updated_at' => now(), ], [ 'medical_history_snapshot_id' => 12, 'rf_report_id' => 88, 'rf_medicalhistory_id' => 23, 'patient_type' => 'current', 'patient_uid' => 'mis:23', 'patient_source_type' => 'mis', 'patient_kind' => 'emergency', 'full_name' => 'Patient 23', 'admitted_at' => '2026-04-08 09:00:00', 'created_at' => now(), 'updated_at' => now(), ], [ 'medical_history_snapshot_id' => 13, 'rf_report_id' => 88, 'rf_medicalhistory_id' => 21, 'patient_type' => 'recipient', 'patient_uid' => 'mis:21', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Patient 21', 'admitted_at' => '2026-04-08 08:00:00', 'created_at' => now(), 'updated_at' => now(), ], ]); $dateRange = reportDateRange('2026-04-08 06:00:00', '2026-04-09 06:00:00'); $department = new Department; $department->department_id = 1; $department->rf_mis_department_id = 100; $service = new SnapshotService(makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), app(DateRangeService::class)); $patients = $service->getPatientsFromOneDayCurrentSnapshots('plan', [88], false, [88]); expect($patients->pluck('medicalHistoryId')->all())->toBe([21, 22]) ->and($patients->firstWhere('medicalHistoryId', 21)->isRecipientToday)->toBeTrue() ->and($patients->firstWhere('medicalHistoryId', 22)->isRecipientToday)->toBeFalse() ->and($service->getPatientsFromOneDayCurrentSnapshots('plan', [88], false, [88])->count())->toBe(2); }); it('separates special contingent from mis lists while keeping it in aggregate live counters', function () { DB::table('stt_stationarbranch')->insert([ 'StationarBranchID' => 10, 'rf_DepartmentID' => 100, ]); DB::table('department_patients')->insert([ [ 'department_patient_id' => 501, 'rf_department_id' => 1, 'source_type' => 'special', 'full_name' => 'Special Plan Patient', 'birth_date' => '1990-01-01', 'patient_kind' => 'plan', 'admitted_at' => '2026-04-08 08:00:00', 'is_current' => true, 'created_at' => now(), 'updated_at' => now(), ], ]); $dateRange = reportDateRange('2026-04-08 06:00:00', '2026-04-09 06:00:00'); $department = new Department; $department->department_id = 1; $department->rf_mis_department_id = 100; $user = makeUser(); $service = new ReportService( app(DateRangeService::class), makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), new SnapshotService(makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), app(DateRangeService::class)), \Mockery::mock(\App\Services\StatisticsService::class) ); expect($service->getPatientsByStatus($department, $user, 'mis-plan', $dateRange)->pluck('id')->all())->toBe([]) ->and($service->getPatientsCountByStatus($department, $user, 'mis-plan', $dateRange))->toBe(0) ->and($service->getPatientsByStatus($department, $user, 'special-plan', $dateRange)->pluck('id')->all())->toBe(['manual:501']) ->and($service->getPatientsCountByStatus($department, $user, 'special-plan', $dateRange))->toBe(1) ->and($service->getPatientsByStatus($department, $user, 'plan', $dateRange)->pluck('id')->all())->toBe(['manual:501']) ->and($service->getPatientsCountByStatus($department, $user, 'plan', $dateRange))->toBe(1); }); it('separates special contingent from mis lists in snapshot mode', function () { DB::table('stt_stationarbranch')->insert([ 'StationarBranchID' => 10, 'rf_DepartmentID' => 100, ]); DB::table('reports')->insert([ 'report_id' => 91, 'created_at' => '2026-04-08', 'sent_at' => '2026-04-08 06:00:00', 'rf_department_id' => 1, 'rf_user_id' => 1, 'rf_lpudoctor_id' => 1, ]); DB::table('medical_history_snapshots')->insert([ [ 'medical_history_snapshot_id' => 201, 'rf_report_id' => 91, 'rf_medicalhistory_id' => 10, 'patient_type' => 'plan', 'patient_uid' => 'mis:10', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Mis Patient', 'admitted_at' => '2026-04-08 08:00:00', 'is_manual' => false, 'created_at' => now(), 'updated_at' => now(), ], [ 'medical_history_snapshot_id' => 202, 'rf_report_id' => 91, 'rf_department_patient_id' => 601, 'patient_type' => 'plan', 'patient_uid' => 'manual:601', 'patient_source_type' => 'special', 'patient_kind' => 'plan', 'full_name' => 'Special Patient', 'admitted_at' => '2026-04-08 09:00:00', 'is_manual' => true, 'created_at' => now(), 'updated_at' => now(), ], ]); $dateRange = new DateRange( startDate: Carbon::parse('2026-04-07 06:00:00', 'Asia/Yakutsk'), endDate: Carbon::parse('2026-04-08 06:00:00', 'Asia/Yakutsk'), startDateRaw: '2026-04-07 06:00:00', endDateRaw: '2026-04-08 06:00:00', isOneDay: false, ); $department = new Department; $department->department_id = 1; $department->rf_mis_department_id = 100; $user = makeUser(isHead: true); $service = new ReportService( app(DateRangeService::class), makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), new SnapshotService(makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), app(DateRangeService::class)), \Mockery::mock(\App\Services\StatisticsService::class) ); expect($service->getPatientsByStatus($department, $user, 'mis-plan', $dateRange)->pluck('id')->all())->toBe(['mis:10']) ->and($service->getPatientsCountByStatus($department, $user, 'mis-plan', $dateRange))->toBe(1) ->and($service->getPatientsByStatus($department, $user, 'special-plan', $dateRange)->pluck('id')->all())->toBe(['manual:601']) ->and($service->getPatientsCountByStatus($department, $user, 'special-plan', $dateRange))->toBe(1) ->and($service->getPatientsByStatus($department, $user, 'plan', $dateRange)->pluck('id')->all())->toBe(['manual:601', 'mis:10']) ->and($service->getPatientsCountByStatus($department, $user, 'plan', $dateRange))->toBe(2); }); it('keeps operations for snapshot patients with medical history ids', function () { DB::table('medical_history_snapshots')->insert([ [ 'medical_history_snapshot_id' => 401, 'rf_report_id' => 91, 'rf_medicalhistory_id' => 10, 'patient_type' => 'plan', 'patient_uid' => 'mis:10', 'patient_source_type' => 'mis', 'patient_kind' => 'plan', 'full_name' => 'Mis Patient', 'admitted_at' => '2026-04-08 08:00:00', 'is_manual' => false, 'created_at' => now(), 'updated_at' => now(), ], ]); DB::table('stt_medicalhistory')->insert([ 'MedicalHistoryID' => 10, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-08 08:00:00', 'DateExtract' => '1900-01-01 00:00:00', ]); DB::table('stt_surgicaloperation')->insert([ 'SurgicalOperationID' => 501, 'rf_MedicalHistoryID' => 10, 'rf_StationarBranchID' => 10, 'rf_kl_ServiceMedicalID' => 77, 'Date' => '2026-04-08 10:00:00', ]); DB::table('stt_operationpurpose')->insert([ 'OperationPurposeID' => 501, 'rf_SurgicalOperationID' => 501, 'rf_OperationStatusID' => 3, ]); DB::table('oms_servicemedical')->insert([ 'ServiceMedicalID' => 77, ]); $service = new SnapshotService( makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), app(DateRangeService::class) ); $patients = $service->getPatientsFromSnapshots('plan', [91]); expect($patients)->toHaveCount(1) ->and($patients->first()->operations)->toHaveCount(1); }); it('keeps operations for replica patients on live report requests', function () { DB::table('stt_stationarbranch')->insert([ 'StationarBranchID' => 10, 'rf_DepartmentID' => 100, ]); DB::table('stt_medicalhistory')->insert([ [ 'MedicalHistoryID' => 41, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-08 08:00:00', 'DateExtract' => '1900-01-01 00:00:00', ], ]); DB::table('stt_migrationpatient')->insert([ [ 'MigrationPatientID' => 41, 'rf_MedicalHistoryID' => 41, 'rf_StationarBranchID' => 10, 'rf_kl_VisitResultID' => 0, 'rf_kl_StatCureResultID' => 0, 'DateIngoing' => '2026-04-08 08:00:00', 'DateOut' => '1900-01-01 00:00:00', ], ]); DB::table('stt_surgicaloperation')->insert([ 'SurgicalOperationID' => 601, 'rf_MedicalHistoryID' => 41, 'rf_StationarBranchID' => 10, 'rf_kl_ServiceMedicalID' => 88, 'Date' => '2026-04-08 11:00:00', ]); DB::table('stt_operationpurpose')->insert([ 'OperationPurposeID' => 601, 'rf_SurgicalOperationID' => 601, 'rf_OperationStatusID' => 3, ]); DB::table('oms_servicemedical')->insert([ 'ServiceMedicalID' => 88, ]); $dateRange = reportDateRange('2026-04-08 06:00:00', '2026-04-09 06:00:00'); $department = new Department; $department->department_id = 1; $department->rf_mis_department_id = 100; $user = makeUser(); $service = new ReportService( app(DateRangeService::class), makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), new SnapshotService(makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), app(DateRangeService::class)), \Mockery::mock(\App\Services\StatisticsService::class) ); $patients = $service->getPatientsByStatus($department, $user, 'mis-plan', $dateRange); expect($patients)->toHaveCount(1) ->and($patients->first()->medicalHistoryId)->toBe(41) ->and($patients->first()->operations)->toHaveCount(1); }); it('keeps completed operations in patient rows even if operation date is outside report range', function () { DB::table('stt_stationarbranch')->insert([ 'StationarBranchID' => 10, 'rf_DepartmentID' => 100, ]); DB::table('stt_medicalhistory')->insert([ 'MedicalHistoryID' => 42, 'rf_EmerSignID' => 1, 'rf_kl_VisitResultID' => 0, 'DateRecipient' => '2026-04-08 08:00:00', 'DateExtract' => '1900-01-01 00:00:00', ]); DB::table('stt_migrationpatient')->insert([ 'MigrationPatientID' => 42, 'rf_MedicalHistoryID' => 42, 'rf_StationarBranchID' => 10, 'rf_kl_VisitResultID' => 0, 'rf_kl_StatCureResultID' => 0, 'DateIngoing' => '2026-04-08 08:00:00', 'DateOut' => '1900-01-01 00:00:00', ]); DB::table('stt_surgicaloperation')->insert([ 'SurgicalOperationID' => 602, 'rf_MedicalHistoryID' => 42, 'rf_StationarBranchID' => 10, 'rf_kl_ServiceMedicalID' => 89, 'Date' => '2026-04-07 12:00:00', ]); DB::table('stt_operationpurpose')->insert([ 'OperationPurposeID' => 602, 'rf_SurgicalOperationID' => 602, 'rf_OperationStatusID' => 3, ]); DB::table('oms_servicemedical')->insert([ 'ServiceMedicalID' => 89, ]); $dateRange = reportDateRange('2026-04-08 06:00:00', '2026-04-09 06:00:00'); $department = new Department; $department->department_id = 1; $department->rf_mis_department_id = 100; $user = makeUser(); $service = new ReportService( app(DateRangeService::class), makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), new SnapshotService(makeUnifiedPatientService(app(PatientService::class)), app(PatientService::class), app(DateRangeService::class)), \Mockery::mock(\App\Services\StatisticsService::class) ); $patients = $service->getPatientsByStatus($department, $user, 'mis-plan', $dateRange); expect($patients)->toHaveCount(1) ->and($patients->first()->medicalHistoryId)->toBe(42) ->and($patients->first()->operations)->toHaveCount(1); });