feat: integrate insurance coverage management for clinic services

- Updated NewSessionPage to calculate patient share based on insurance coverage rules.
- Refactored billing calculations to utilize new patientShareOf function for service items.
- Enhanced API documentation to reflect changes in service coverage structure.
- Implemented ServiceInsuranceModal for managing insurance coverage per service.
- Added UI components for displaying and editing insurance coverage details.
- Removed obsolete toggle switch styles and adjusted CSS for new components.
- Ensured backend endpoints support both service_item_id and service_item_uuid for flexibility.
This commit is contained in:
hamed
2026-06-24 04:23:50 +03:30
parent 253414ef3e
commit 27840da78d
11 changed files with 878 additions and 258 deletions
+8 -4
View File
@@ -426,6 +426,7 @@ override پوشش یک خدمت خاص تحت قرارداد یک بیمه. فی
"uuid": "…",
"tenant_insurance_id": 4,
"service_item_id": 12,
"service_item_uuid": "…",
"covered": true,
"coverage_percent": 80,
"franchise_rials": null,
@@ -442,13 +443,16 @@ override پوشش یک خدمت خاص تحت قرارداد یک بیمه. فی
**Body:**
| فیلد | نوع | توضیح |
|------|-----|-------|
| `service_item_id` | int | الزامی |
| `service_item_uuid` | string | شناسه‌ی خدمت (ترجیحی؛ پنل ادمین فقط uuid دارد) |
| `service_item_id` | int | جایگزین `service_item_uuid` (id داخلی) — یکی از این دو الزامی |
| `covered` | bool | پیش‌فرض true |
| `coverage_percent` | float \| null | null = ارث از قرارداد |
| `franchise_rials` | int \| null | null = ارث از قرارداد |
| `ceiling_rials` | int \| null | null = ارث از قرارداد |
پاسخ `200`: `{ success, data: { message } }`.
خطاها: `404 ERR_NOT_FOUND_001` قرارداد یافت نشد · `422 ERR_VALIDATION_001` service_item_id الزامی.
سرویس باید متعلق به همان مطب/کلینیکِ قرارداد باشد (`ServiceItem→section→entity_type/entity_id`).
> منطق resolve: `TenantInsuranceService::coverageRuleForService()` ابتدا override خدمت را بررسی می‌کند؛ اگر `covered=false` → `CoverageRule::notCovered()`؛ در غیر این صورت فیلدهای null از قرارداد پر می‌شوند. این `CoverageRule` در فاز ۴ ورودی `BillingCalculator` است.
پاسخ `200`: `{ success, data: { message } }`.
خطاها: `404 ERR_NOT_FOUND_001` قرارداد یافت نشد · `422 ERR_VALIDATION_001` سرویس یافت نشد · `403 ERR_FORBIDDEN_001` سرویس متعلق به شما نیست.
> منطق resolve: `TenantInsuranceService::coverageRuleForService()` ابتدا override خدمت را بررسی می‌کند؛ اگر `covered=false` → `CoverageRule::notCovered()`؛ در غیر این صورت فیلدهای null از قرارداد پر می‌شوند. این `CoverageRule` ورودی `BillingCalculator` است و سهم بیمه‌ی هر `InvoiceItem` را تعیین می‌کند؛ همان سهم‌ها در `ClaimService::createFromInvoice()` به `ClaimItem` (مطالبات بیمه) تبدیل می‌شوند. پنل ادمین این endpoint را از مودال «پوشش بیمه» در صفحه سرویس‌های کلینیک فراخوانی می‌کند.