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(); return [$owner, $insurance]; } public function testContractWithoutOverridesFollowsTheAdminDefault(): void { [$owner, $insurance] = $this->makeDoctorAndInsurance(); static::getContainer()->get(InsuranceCoverageDefaultService::class)->save($insurance->getId(), [ ['key' => 'outpatient', 'coverage_percent' => 70], ['key' => 'inpatient', 'coverage_percent' => 30], ]); $body = $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, [ 'insurance_id' => $insurance->getId(), ]); $this->assertSame(201, $this->responseCode()); $row = $body['data']['data']; $this->assertEquals(70.0, $row['category_coverages']['outpatient']); $this->assertEquals(30.0, $row['category_coverages']['inpatient']); $this->assertSame('admin_default', $row['category_coverage_source']['outpatient']); } public function testSendingCategoryCoveragesStoresAnOverride(): void { [$owner, $insurance] = $this->makeDoctorAndInsurance(); static::getContainer()->get(InsuranceCoverageDefaultService::class)->save($insurance->getId(), [ ['key' => 'outpatient', 'coverage_percent' => 70], ['key' => 'inpatient', 'coverage_percent' => 30], ]); $body = $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, [ 'insurance_id' => $insurance->getId(), 'category_coverages' => [ ['key' => 'inpatient', 'coverage_percent' => 90], ], ]); $this->assertSame(201, $this->responseCode()); $row = $body['data']['data']; $this->assertEquals(90.0, $row['category_coverages']['inpatient']); $this->assertSame('override', $row['category_coverage_source']['inpatient']); $this->assertSame('admin_default', $row['category_coverage_source']['outpatient']); } public function testAnEnabledServiceKindCannotBeLeftWithoutAPercent(): void { // بدون پیش‌فرض مرکزی: ارسال درصد فقط برای سرپایی، بستری را صفر رها می‌کند. [$owner, $insurance] = $this->makeDoctorAndInsurance(); $body = $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, [ 'insurance_id' => $insurance->getId(), 'category_coverages' => [ ['key' => 'outpatient', 'coverage_percent' => 70], ['key' => 'inpatient', 'coverage_percent' => null], ], ]); $this->assertSame(422, $this->responseCode()); $this->assertSame('category_coverages', $body['errors'][0]['field']); $this->assertStringContainsString('خدمات بستری', $body['errors'][0]['message']); } public function testADisabledServiceKindNeedsNoPercent(): void { [$owner, $insurance] = $this->makeDoctorAndInsurance(); $this->authJson('PUT', '/api/v1/insurance-pricing', $owner, [ 'service_categories' => [ ['key' => 'outpatient', 'enabled' => true], ['key' => 'inpatient', 'enabled' => false], ], ]); $body = $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, [ 'insurance_id' => $insurance->getId(), 'category_coverages' => [ ['key' => 'outpatient', 'coverage_percent' => 70], ], ]); $this->assertSame(201, $this->responseCode()); $this->assertEquals(70.0, $body['data']['data']['category_coverages']['outpatient']); } public function testListReturnsEffectivePercentsAndSources(): void { [$owner, $insurance] = $this->makeDoctorAndInsurance(); static::getContainer()->get(InsuranceCoverageDefaultService::class)->save($insurance->getId(), [ ['key' => 'outpatient', 'coverage_percent' => 55], ]); $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, ['insurance_id' => $insurance->getId()]); $body = $this->authJson('GET', '/api/v1/billing/tenant-insurances', $owner); $this->assertSame(200, $this->responseCode()); $row = $body['data']['data'][0]; $this->assertEquals(55.0, $row['category_coverages']['outpatient']); $this->assertArrayHasKey('inpatient', $row['category_coverage_source']); } public function testUnknownCategoryIsRejected(): void { [$owner, $insurance] = $this->makeDoctorAndInsurance(); $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, [ 'insurance_id' => $insurance->getId(), 'category_coverages' => [['key' => 'dental', 'coverage_percent' => 50]], ]); $this->assertSame(422, $this->responseCode()); } public function testPercentAbove100IsRejected(): void { [$owner, $insurance] = $this->makeDoctorAndInsurance(); $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, [ 'insurance_id' => $insurance->getId(), 'category_coverages' => [['key' => 'outpatient', 'coverage_percent' => 101]], ]); $this->assertSame(422, $this->responseCode()); } public function testPatchCanDropAnOverrideBackToTheAdminDefault(): void { [$owner, $insurance] = $this->makeDoctorAndInsurance(); // سرپایی هم پیش‌فرض دارد، وگرنه ساخت قرارداد به‌خاطر «درصد پوشش الزامی است» رد می‌شود. static::getContainer()->get(InsuranceCoverageDefaultService::class)->save($insurance->getId(), [ ['key' => 'outpatient', 'coverage_percent' => 50], ['key' => 'inpatient', 'coverage_percent' => 30], ]); $created = $this->authJson('POST', '/api/v1/billing/tenant-insurances', $owner, [ 'insurance_id' => $insurance->getId(), 'category_coverages' => [['key' => 'inpatient', 'coverage_percent' => 90]], ]); $uuid = $created['data']['data']['uuid']; $body = $this->authJson('PATCH', '/api/v1/billing/tenant-insurances/' . $uuid, $owner, [ 'category_coverages' => [['key' => 'inpatient', 'coverage_percent' => null]], ]); $this->assertSame(200, $this->responseCode()); $row = $body['data']['data']; $this->assertEquals(30.0, $row['category_coverages']['inpatient']); $this->assertSame('admin_default', $row['category_coverage_source']['inpatient']); } }