# LIS Home-Visit Fee — عقد + ليدجر (2026-07-08)

> الخطة المعتمدة (المالك، الخيارات الموصى بها). دراسة: `public_html/home-visit-fee-plan.html`. **Fable 5 مستشار التصميم، Codex يراجع كل WP.**

## القرارات المعتمدة (المالك)
① قابل للتعديل بعد الإنشاء (عبر تعديل الطلب) · ② الرسم **غير قابل للخصم** · ③ التأمين لا يغطّيه (v1، 100% على المريض) · ④ حساب إيراد المعمل العام (منفصل=v2) · ⑤ الطلبات العيادية **خارج النطاق** (ويزارد المعمل المستقل فقط).

## التصميم (Fable 5 — كله مؤكَّد على الكود)
- **تخزين:** عمودان على `lab_requests`: `home_visit_type_id` (FK nullable) + `home_visit_fee` decimal(12,3) default 0 — **لقطة سعر server-side** (لا يُعاد حسابها). **مش** pseudo request-investigation.
- **recalc** (`LabRequestService::recalculateTotals` ~:190-393): الرسم **بعد** الخصم وغير قابل للخصم → `net_amount = max(0, grossNet − manualDisc) + home_visit_fee`؛ `total_amount += home_visit_fee`. الخصم يظل على `grossNet` (تحاليل فقط).
- **فاتورة:** سطر synthetic واحد في `InsuranceInvoiceService::generateFromRequest` (investigation_id=null، description=اسم النوع، price=fee) — سابقة باقة B2B `:145-157`. الضريبة تلقائية عبر `LabInvoice::recalculateTotals` (صفر كود ضريبة). عمود `home_visit_type_id` على `lab_invoice_items`.
- **⚠️ استثناء من أساس الخصم** في `createStandardInvoice`/split (`resolveManualDiscount` gross و`$patientGross`) وإلا خصم% يخصم الرسم على الفاتورة ≠ الطلب.
- **⚠️ تخطّي العمولة:** `if ($item->home_visit_type_id) continue;` في `DoctorCommissionService` per-item (وإلا الطبيب ياخد عمولة على الرسم).
- **تأمين:** الرسم على فاتورة **المريض فقط** (بعد فرع per-test share، قبل `$patientGross` discount)، + يُضاف لـ`patient_share_total`.
- **كتالوج:** جدول `lab_home_visit_types` (استنساخ `LabSpecimenType` + `price`/`note`/`is_active`/`sort_order`)، صلاحية `lis.home-visit-types`، سعر ثابت واحد v1، السيرفر يحلّ السعر (لا يثق بالعميل).
- migration ≥ `2026_07_08_*`.

## 📊 ليدجر
| WP | المحتوى | يعتمد | مراجعة | الحالة |
|----|---------|-------|--------|--------|
| WP1 | كتالوج BE: `lab_home_visit_types` migration + Model + CRUD controller + routes + صلاحية `lis.home-visit-types` (استنساخ specimen-types). Pest CRUD+عزل. | — | Codex | ✅ |
| WP2 | رسم الطلب BE: عمودان على `lab_requests` + validation (exists+شركة+active) + snapshot server-side في CreateLabRequest/update + recalc math (§) + إعادة حساب مسار التعديل. Pest recalc. | WP1 | Codex+Fable | ✅ |
| WP3 | سطر الفاتورة BE: `home_visit_type_id` على lab_invoice_items + سطر الرسم (فرعي المريض/التأمين — المريض فقط) + استثناء أساس الخصم + تخطّي العمولة. Pest (parity + تأمين + ضريبة + عمولة). | WP2 | Codex+Fable | ✅ |
| WP4 | شاشة الكتالوج FE (استنساخ lis-specimen-types + سعر/ملاحظة) + route + nav. | WP1 | single | ✅ |
| WP5 | ويزارد الطلب FE: توجل(OFF) + قائمة الأنواع بأسعارها + سطر الملخّص + `netAmount += fee` + payload + استرجاع التعديل + سطر طباعة الإيصال. | WP1 | Codex | ⬜ |
| WP6 | Pest شامل + CHANGELOG + نشر /app + push. | الكل | single | ⬜ |

**DAG:** BE سلسلة {WP1→WP2→WP3} · FE WP4/WP5 بعد WP1. ⚠️ الطلب العيادي: `handleFromArray` ماينقلش حقول الزيارة (حدّ النطاق). ⚠️ phpunit=sqlite.
