createUser(['ROLE_USER', 'ROLE_DOCTOR']); $doctor = new Doctor($user, 'دکتر تست سهم بیمه'); $doctor->setMobileNumber($user->getMobileNumber()); $this->em->persist($doctor); $this->em->flush(); return $doctor; } private function makeAppointment(Doctor $doctor): Appointment { $start = strtotime('+30 days') + random_int(0, 500_000) * 7; $appointment = $this->newAppointment($doctor, $this->createUser(), $start, $start + 900); $appointment->setVisitPriceRials(self::VISIT_RIALS); $this->em->persist($appointment); $this->em->flush(); return $appointment; } /** قرارداد پایه با درصد مرکزی: سرپایی ۷۰٪، بستری ۳۰٪. */ private function makeInsuranceWithDefaults(Doctor $doctor): Insurance { $insurance = new Insurance('بیمه سهم ' . random_int(1000, 9999), InsuranceType::Basic); $this->em->persist($insurance); $this->em->flush(); $contract = new TenantInsurance(TenantInsurance::TYPE_DOCTOR, $doctor->getId(), $insurance->getId()); $contract->setKind('basic'); $this->em->persist($contract); $this->em->flush(); static::getContainer()->get(InsuranceCoverageDefaultService::class)->save($insurance->getId(), [ ['key' => 'outpatient', 'coverage_percent' => 70], ['key' => 'inpatient', 'coverage_percent' => 30], ]); return $insurance; } private function reloadSession(string $uuid): PatientSession { $this->em->clear(); return $this->em->getRepository(PatientSession::class)->findOneBy(['uuid' => $uuid]); } public function testInpatientReferenceScenario(): void { $doctor = $this->makeDoctor(); $appointment = $this->makeAppointment($doctor); $insurance = $this->makeInsuranceWithDefaults($doctor); $body = $this->authJson('POST', '/api/v1/appointment/' . $appointment->getUuid() . '/confirm', $doctor->getUser(), [ 'insurance_service_category' => 'inpatient', 'insurance_base_id' => $insurance->getId(), ]); self::assertSame(200, $this->responseCode()); $session = $body['data']['session']; self::assertSame(1_785_600, $session['base_insurance_rials']); self::assertSame(4_166_400, $session['patient_share_rials']); self::assertSame(4_166_400, $session['final_price_rials']); } public function testOutpatientUsesItsOwnPercent(): void { $doctor = $this->makeDoctor(); $appointment = $this->makeAppointment($doctor); $insurance = $this->makeInsuranceWithDefaults($doctor); $body = $this->authJson('POST', '/api/v1/appointment/' . $appointment->getUuid() . '/confirm', $doctor->getUser(), [ 'insurance_service_category' => 'outpatient', 'insurance_base_id' => $insurance->getId(), ]); self::assertSame(200, $this->responseCode()); self::assertSame(4_166_400, $body['data']['session']['base_insurance_rials']); // 70٪ self::assertSame(1_785_600, $body['data']['session']['patient_share_rials']); } /** نوبتِ بدون بیمه باید مثل قبل کاملاً سهم بیمار بماند. */ public function testAppointmentWithoutInsuranceStaysFullyOnThePatient(): void { $doctor = $this->makeDoctor(); $appointment = $this->makeAppointment($doctor); $body = $this->authJson('POST', '/api/v1/appointment/' . $appointment->getUuid() . '/confirm', $doctor->getUser(), []); self::assertSame(200, $this->responseCode()); self::assertSame(0, $body['data']['session']['base_insurance_rials']); self::assertSame(self::VISIT_RIALS, $body['data']['session']['patient_share_rials']); } /** بدون انتخاب کاربر، تنها نوعِ فعالِ tenant مبنا می‌شود. */ public function testSingleEnabledCategoryIsUsedWithoutAnExplicitChoice(): void { $doctor = $this->makeDoctor(); $appointment = $this->makeAppointment($doctor); $insurance = $this->makeInsuranceWithDefaults($doctor); $this->authJson('PUT', '/api/v1/insurance-pricing', $doctor->getUser(), [ 'service_categories' => [['key' => 'outpatient', 'enabled' => false]], ]); self::assertSame(200, $this->responseCode()); $body = $this->authJson('POST', '/api/v1/appointment/' . $appointment->getUuid() . '/confirm', $doctor->getUser(), [ 'insurance_base_id' => $insurance->getId(), ]); self::assertSame(200, $this->responseCode()); // فقط «بستری» فعال است → ۳۰٪ self::assertSame(1_785_600, $body['data']['session']['base_insurance_rials']); $session = $this->reloadSession($body['data']['session']['uuid']); self::assertSame('inpatient', $session->getInsuranceServiceCategory()->value); self::assertSame($insurance->getId(), $session->getInsuranceBaseId()); } public function testInvoiceSnapshotsTheServiceCategory(): void { $doctor = $this->makeDoctor(); $appointment = $this->makeAppointment($doctor); $insurance = $this->makeInsuranceWithDefaults($doctor); $body = $this->authJson('POST', '/api/v1/appointment/' . $appointment->getUuid() . '/confirm', $doctor->getUser(), [ 'insurance_service_category' => 'inpatient', 'insurance_base_id' => $insurance->getId(), ]); $session = $this->reloadSession($body['data']['session']['uuid']); $invoice = static::getContainer()->get(InvoiceService::class) ->createFromSession($session, 'doctor', $doctor->getId()); self::assertSame('inpatient', $invoice->toArray()['service_category']); self::assertSame('خدمات بستری', $invoice->toArray()['service_category_label']); self::assertSame(1_785_600, $invoice->toArray()['base_insurance_rials']); self::assertSame(4_166_400, $invoice->toArray()['patient_rials']); } }