فواتير العملاء الداخليين · المديونيات · التحصيل

تنظيف شاشة الفواتير من الـ B2B · شاشة "العملاء اللي عليهم فلوس" · تحصيل بضغطة واحدة يفك طباعة النتايج — دراسة كاملة قبل التنفيذ

1 اللي إنت طلبته (تأكيد الفهم)

خبر كويس: جزء كبير من اللي محتاجه موجود فعلاً في الباك إند — كل فاتورة عندها balance_due (المتبقي) وamount_paid (المدفوع)، وفيه بوابة جاهزة بتمنع إصدار النتيجة طول ما فيه مبلغ متبقي. الناقص أساسًا هو طريقة عرض وتجميع وتحصيل احترافية + تنظيف الـ B2B من الشاشة.

2 الوضع الحالي بالظبط (بالأدلة من الكود)

أ) شاشة الفواتير بتعرض كل الأنواع (ومنها الـ B2B)

الـ LabInvoiceController::index() بيرجّع كل الفواتير بدون أي فلترة على النوع. يعني الفواتير دي كلها بتتخلط في شاشة واحدة:

النوع (invoice_type)المعنىالمفروض يظهر في /lab/invoices؟
standard / patient_invoiceفاتورة مريض/فرد داخلينعم
insurance_invoiceفاتورة تأميننعم
external_lab_receivableمعمل خارجي كعميل (علينا نحصّل منه)لأ — B2B
external_lab_payableمعمل خارجي كمورّد (إحنا اللي بندفع له)لأ — B2B
المشكلة الأولى: دلوقتي الـ external_lab_* بيتخلطوا مع فواتير المرضى في نفس القايمة. ده اللي مخلّي الشاشة "مش بس العملاء الداخليين".

ب) بيانات المديونية موجودة بالفعل على كل فاتورة

موديل LabInvoice فيه الحقول دي (كلها decimal(12,3)):

total = الإجمالي amount_paid = المدفوع= balance_due = المتبقي (المديونية)

والحالة (status) بتتحدّث أوتوماتيك مع كل دفعة عن طريق recalculatePaymentStatus():

draft (مسودة) posted (مرحّلة) partially_paid (مدفوعة جزئيًا) paid (مدفوعة)

ج) صفحة المدفوعات موجودة لكن منفصلة وغير عملية للتحصيل السريع

د) بوابة الدفع على إصدار النتيجة — موجودة فعلاً

دي أهم نقطة. في LabResultController فيه دالة releaseBlockedByBalance() بتشتغل عند release() وbulkRelease():

if (user can 'lis.results.release_unpaid') → allow // صلاحية تجاوز invoice = latest invoice for request WHERE type != external_lab_receivable if (!invoice) → allow // مفيش فاتورة = مفيش بوابة return invoice.balance_due > 0.001 // فيه متبقي ⇒ امنع الإصدار
فجوة مهمة: البوابة على الإصدار (release) مش على الطباعة (print). بمعنى إن بوابة المعمل العامة (/patient-portal) بتطبع النتيجة المُصدَرة بدون أي فحص دفع. فلو حد صدّر بصلاحية تجاوز، المريض يقدر يطبع من البوابة. محتاجين قرار: نكتفي ببوابة الإصدار ولا نضيف فحص دفع على الطباعة كمان؟ (سؤال رقم 3 تحت).

هـ) مفيش شاشة "مديونيات العملاء" خاصة بالمعمل

3 خلاصة المشاكل اللي هنحلها

#المشكلةالأثر
1فواتير الـ B2B بتظهر مع فواتير المرضى في /lab/invoicesتشويش + أرقام غلط + اختلاط نظامين مختلفين
2مفيش عرض واضح لـ"مين عليه فلوس وكام"صعب تتابع المديونيات أو تطالب العملاء
3التحصيل بيحتاج تنقّل بين شاشتين ومعرفة رقم الفاتورةبطء على الكاشير + أخطاء
4ربط الدفع بطباعة النتيجة مش واضح للمستخدمالكاشير مش عارف "ليه النتيجة مش بتتطبع"

4 التصميم المقترح — 3 ركائز

الركيزة أ — شاشة فواتير "داخلية فقط" + تبويب منفصل للـ B2B

توصية: نخلي الـ B2B تبويب جوّه نفس الشاشة (مش لينك تاني) عشان توحيد التجربة، بس بيفتح على آلية المطالبات الشهرية.

الركيزة ب — تبويب/شاشة «المديونيات» (Receivables — اللي عليهم فلوس)

عرض مُجمّع بالعميل/المريض (مش بالفاتورة) — كل صف عميل عليه فلوس:

المريض | رقم MRN | عدد طلبات مفتوحة | إجمالي مستحق | مدفوع | المتبقي | أقدم مديونية | إجراء ───────────────────────────────────────────────────────────────────────────────── ayman ayman | 20561 | 2 | 120.00 | 40.00 | 80.00 | منذ 5 أيام | [تحصيل] nehal ibrahim | 20562 | 1 | 34.50 | 0.00 | 34.50 | اليوم | [تحصيل] ───────────────────────────────────────────────────────────────────────────────── الإجمالي المتبقي على العملاء: 114.50

الركيزة ج — تحصيل بضغطة واحدة يفك طباعة النتيجة

ديالوج تحصيل سريع من شاشة المديونيات أو من صف الفاتورة مباشرة:

اضغط [تحصيل] ديالوج: المبلغ (افتراضي = المتبقي) + طريقة الدفع + الخزنة حفظ balance_due = 0 ⇒ الفاتورة paid النتيجة بقت قابلة للإصدار/الطباعة

تجربة الكاشير الكاملة (السيناريو المطلوب)

المريض بيطلب نتيجته الكاشير يفتح «المديونيات» يلاقي اسمه وعليه 80 [تحصيل] → كاش اتدفع اطبع النتيجة

5 التغييرات التقنية (مختصرة — معظمها FE)

الباك إند (تعديلات صغيرة)

الفرونت إند

مبدأ: Backend-first ومفيش منطق مالي جديد — بنعيد استخدام balance_due + LabPayment + بوابة الإصدار الموجودة. التركيز على العرض والتجميع والتحصيل السريع.

6 قرارات محتاج رأيك فيها قبل التنفيذ

سؤال 1 — الـ B2B في شاشة الفواتير
نخفيه تمامًا من /lab/invoices ونخليه تبويب منفصل بيودّي على المطالبات الشهرية؟ (توصيتي: نعم، تبويب منفصل) — ولا تفضّل نشيله خالص من هنا ويبقى في صفحة المعامل الخارجية بس؟
سؤال 2 — شكل «المديونيات»
تبويب جوّه شاشة الفواتير، ولا شاشة مستقلة في القايمة الجانبية باسم «المديونيات / التحصيل»؟ (توصيتي: شاشة مستقلة عشان الكاشير يفتحها على طول)
سؤال 3 — بوابة الدفع: إصدار بس ولا طباعة كمان؟
دلوقتي الدفع بيتحكم في الإصدار. هل نضيف فحص دفع كمان على الطباعة في بوابة المريض (يمنع طباعة نتيجة لسه عليها فلوس حتى لو اتصدرت)؟ (توصيتي: نكتفي ببوابة الإصدار الحالية — أبسط وكافية، لأن النتيجة أصلاً مش بتتصدر قبل الدفع)
سؤال 4 — التأمين (insurance_invoice)
فواتير التأمين فيها «حصة المريض» (patient_share). نعتبرها «داخلية» وتظهر في المديونيات بحصة المريض فقط؟ (توصيتي: نعم — حصة المريض دين داخلي، وحصة التأمين مسارها المطالبات)
سؤال 5 — صلاحية التجاوز
مين يقدر يطبع/يصدر بدون دفع (صلاحية lis.results.release_unpaid)؟ نسيبها للأدمن بس ولا نعملها إعداد لكل دور؟ (توصيتي: الأدمن + مدير المعمل فقط)

7 خطة التنفيذ بالمراحل (بعد موافقتك)

المرحلة 1 — تنظيف شاشة الفواتير (نص يوم)
فلتر scope في الباك + تبويبات «داخلية/B2B» في الفرونت + إبراز عمود المتبقي.
المرحلة 2 — شاشة المديونيات (يوم)
endpoint التجميع /lis/invoices/receivables + كومبوننت العرض + الفلاتر + الكروت.
المرحلة 3 — التحصيل السريع + ربط الطباعة (نص يوم)
ديالوج Quick Collect + رسالة «جاهزة للطباعة» + زر اطبع + auto-post للمسودة.
المرحلة 4 — تلميع + اختبار (نص يوم)
اختبار السيناريو كامل: عميل عليه فلوس → تحصيل → إصدار → طباعة. + بناء ونشر على moonui.

8 الخلاصة في سطرين

المنطق المالي وبوابة الدفع موجودين. اللي هنبنيه هو طبقة عرض وتحصيل احترافية: شاشة فواتير داخلية نضيفة، شاشة «اللي عليهم فلوس»، وتحصيل بضغطة واحدة بيخلّي النتيجة جاهزة للطباعة فورًا. مفيش مخاطرة على الفلوس أو المحاسبة لأننا بنعيد استخدام اللي موجود.
دراسة فنية — Moon ERP / LIS · يونيو 2026 · للمراجعة والموافقة قبل التنفيذ