feat: Enhance insurance billing system to support supplementary insurance
- Updated CoverageRule and related entities to include franchise_percent instead of franchise_rials. - Modified Appointment entity to carry supplementary insurance ID alongside base insurance. - Implemented SessionBillingService to ensure finalized invoices for insured patient sessions. - Created InvoiceFinalized event to trigger claims creation upon invoice finalization. - Added BackfillMissingClaimsCommand to generate claims for finalized invoices without existing claims. - Developed tests to validate the new functionality for supplementary insurance handling in appointments and claims.
This commit is contained in:
@@ -73,7 +73,13 @@ class AppointmentInsuranceService
|
||||
|
||||
if (array_key_exists('insurance_base_id', $data)) {
|
||||
$appointment->setInsuranceBaseId(
|
||||
$this->resolveBaseInsuranceId($data['insurance_base_id'], $entityType, $entityId)
|
||||
$this->resolveInsuranceId($data['insurance_base_id'], $entityType, $entityId, false)
|
||||
);
|
||||
}
|
||||
|
||||
if (array_key_exists('insurance_supplementary_id', $data)) {
|
||||
$appointment->setInsuranceSupplementaryId(
|
||||
$this->resolveInsuranceId($data['insurance_supplementary_id'], $entityType, $entityId, true)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -106,8 +112,15 @@ class AppointmentInsuranceService
|
||||
return $category;
|
||||
}
|
||||
|
||||
private function resolveBaseInsuranceId(mixed $raw, string $entityType, int $entityId): ?int
|
||||
/**
|
||||
* شناسهٔ بیمهٔ معتبر برای این نوبت، یا null وقتی انتخاب پاک شده است.
|
||||
* قرارداد باید فعال باشد و نوعش با جایگاهی که در آن انتخاب شده بخواند —
|
||||
* بیمهٔ تکمیلی نمیتواند جای بیمهٔ پایه بنشیند و برعکس.
|
||||
*/
|
||||
private function resolveInsuranceId(mixed $raw, string $entityType, int $entityId, bool $supplementary): ?int
|
||||
{
|
||||
$field = $supplementary ? 'insurance_supplementary_id' : 'insurance_base_id';
|
||||
|
||||
if ($raw === null || $raw === '' || (int) $raw <= 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -119,18 +132,20 @@ class AppointmentInsuranceService
|
||||
ErrorCodes::ERR_VALIDATION_001,
|
||||
'این بیمه برای این پزشک/کلینیک قرارداد فعال ندارد',
|
||||
422,
|
||||
'insurance_base_id',
|
||||
$field,
|
||||
);
|
||||
}
|
||||
|
||||
// نوعِ قرارداد بر نوع کاتالوگ اولویت دارد — همان قاعدهٔ TenantInsuranceService.
|
||||
$kind = $contract->getKind() ?? $this->insuranceRepo->find($insuranceId)?->getType()->value;
|
||||
if ($kind === InsuranceType::Supplementary->value) {
|
||||
$kind = $contract->getKind() ?? $this->insuranceRepo->find($insuranceId)?->getType()->value;
|
||||
$isSupp = $kind === InsuranceType::Supplementary->value;
|
||||
|
||||
if ($isSupp !== $supplementary) {
|
||||
throw new AppException(
|
||||
ErrorCodes::ERR_VALIDATION_001,
|
||||
'برای نوبت فقط بیمهٔ پایه قابل انتخاب است',
|
||||
$supplementary ? 'اینجا فقط بیمهٔ تکمیلی قابل انتخاب است' : 'اینجا فقط بیمهٔ پایه قابل انتخاب است',
|
||||
422,
|
||||
'insurance_base_id',
|
||||
$field,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user