service = static::getContainer()->get(TenantInsuranceService::class); $this->defaults = static::getContainer()->get(InsuranceCoverageDefaultService::class); } /** @return array{0: TenantInsurance, 1: Insurance, 2: ServiceItem} */ private function makeContract(float $legacyPercent = 55.0): array { $owner = $this->createUser(['ROLE_DOCTOR']); $doctor = new Doctor($owner, 'دکتر تست درصد پوشش'); $this->em->persist($doctor); $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->setCoveragePercent($legacyPercent); $section = new ServiceSection(TenantInsurance::TYPE_DOCTOR, $doctor->getId(), 'بخش بستری'); $this->em->persist($contract); $this->em->persist($section); $this->em->flush(); $item = (new ServiceItem($section, 'جراحی', 5_952_000)) ->setServiceCategory(ServiceCategory::Inpatient) ->setInsuranceCovered(true); $this->em->persist($item); $this->em->flush(); return [$contract, $insurance, $item]; } public function testFallsBackToLegacyContractPercentWhenNothingIsConfigured(): void { [$contract] = $this->makeContract(55.0); $this->assertSame(55.0, $this->service->resolvePercent($contract, ServiceCategory::Inpatient)); } public function testAdminDefaultWinsOverLegacyContractPercent(): void { [$contract, $insurance] = $this->makeContract(55.0); $this->defaults->save($insurance->getId(), [ ['key' => 'inpatient', 'coverage_percent' => 30], ['key' => 'outpatient', 'coverage_percent' => 70], ]); $this->assertSame(30.0, $this->service->resolvePercent($contract, ServiceCategory::Inpatient)); $this->assertSame(70.0, $this->service->resolvePercent($contract, ServiceCategory::Outpatient)); } /** تغییر تنظیمات مرکزی باید فوراً روی قرارداد بدون override اثر بگذارد (fallback زنده). */ public function testChangingTheAdminDefaultImmediatelyChangesTheContract(): void { [$contract, $insurance] = $this->makeContract(55.0); $this->defaults->save($insurance->getId(), [['key' => 'inpatient', 'coverage_percent' => 30]]); $this->assertSame(30.0, $this->service->resolvePercent($contract, ServiceCategory::Inpatient)); $this->defaults->save($insurance->getId(), [['key' => 'inpatient', 'coverage_percent' => 45]]); $this->assertSame(45.0, $this->service->resolvePercent($contract, ServiceCategory::Inpatient)); } public function testContractCategoryOverrideWinsOverAdminDefault(): void { [$contract, $insurance] = $this->makeContract(55.0); $this->defaults->save($insurance->getId(), [ ['key' => 'inpatient', 'coverage_percent' => 30], ['key' => 'outpatient', 'coverage_percent' => 70], ]); $this->service->setCategoryCoverages($contract, [['key' => 'inpatient', 'coverage_percent' => 90]]); $this->assertSame(90.0, $this->service->resolvePercent($contract, ServiceCategory::Inpatient)); $this->assertSame(70.0, $this->service->resolvePercent($contract, ServiceCategory::Outpatient)); } public function testServiceOverrideWinsOverEveryOtherLevel(): void { [$contract, $insurance, $item] = $this->makeContract(55.0); $this->defaults->save($insurance->getId(), [['key' => 'inpatient', 'coverage_percent' => 30]]); $this->service->setCategoryCoverages($contract, [['key' => 'inpatient', 'coverage_percent' => 90]]); $this->service->setServiceCoverage($contract, $item->getId(), true, 25.0, null, null); $rule = $this->service->coverageRuleForService( TenantInsurance::TYPE_DOCTOR, $contract->getEntityId(), $contract->getInsuranceId(), $item->getId(), ); $this->assertSame(25.0, $rule->coveragePercent); } /** درصد نوعِ خودِ خدمت باید انتخاب شود، نه درصد سرپایی. */ public function testServiceRuleUsesTheCategoryOfTheServiceItem(): void { [$contract, $insurance, $item] = $this->makeContract(55.0); $this->defaults->save($insurance->getId(), [ ['key' => 'inpatient', 'coverage_percent' => 30], ['key' => 'outpatient', 'coverage_percent' => 70], ]); $rule = $this->service->coverageRuleForService( TenantInsurance::TYPE_DOCTOR, $contract->getEntityId(), $contract->getInsuranceId(), $item->getId(), ); $this->assertSame(30.0, $rule->coveragePercent); $this->assertSame(0, $rule->franchiseRials, 'فرانشیز در بیمهٔ پایه صفر می‌ماند'); } /** ویزیت خدمتِ سرپایی است. */ public function testVisitRuleAlwaysUsesTheOutpatientPercent(): void { [$contract, $insurance] = $this->makeContract(55.0); $this->defaults->save($insurance->getId(), [ ['key' => 'inpatient', 'coverage_percent' => 30], ['key' => 'outpatient' , 'coverage_percent' => 70], ]); $rule = $this->service->coverageRule( TenantInsurance::TYPE_DOCTOR, $contract->getEntityId(), $contract->getInsuranceId(), ); $this->assertSame(70.0, $rule->coveragePercent); } public function testRemovingTheOverrideReturnsToTheAdminDefault(): void { [$contract, $insurance] = $this->makeContract(55.0); $this->defaults->save($insurance->getId(), [['key' => 'inpatient', 'coverage_percent' => 30]]); $this->service->setCategoryCoverages($contract, [['key' => 'inpatient', 'coverage_percent' => 90]]); $this->service->setCategoryCoverages($contract, [['key' => 'inpatient', 'coverage_percent' => null]]); $this->assertSame(30.0, $this->service->resolvePercent($contract, ServiceCategory::Inpatient)); } }