Moon ERP · تشخيص اختبار حقيقي

اختبار التسليم الجزئي: ليه ماحصلش اللي توقّعته؟ Partial-delivery test — expected vs. actual (root-caused from live data)

عملت فاتورة بيع، اتعمل إذن تسليم مسودة، رحت صرفت جزء (4 من 5) — لكن النظام ما عملش إذن تاني بالباقي وما ظهرش أي تتبّع على الفاتورة. ده مش عطل — ده لأن «وضع التسليم» مش مفعَّل على شركتك. التفاصيل بالأدلة من قاعدة بياناتك تحت.

📅 2026-06-23 المصدر: بيانات moonui2_dev_be الفعلية (فاتورة #11 / إذن #24) الخلاصة: إعداد ناقص + ملاحظتان حقيقيتان

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

شركتك دلوقتي على «احتساب التكلفة عند الفاتورة» (الوضع الافتراضي) — والميزة الجديدة (التسليم الجزئي + الإذن المتبقّي + تتبّع المُسلَّم + COGS عند التسليم) opt-in، بتشتغل بس لما تفعّل «نقطة احتساب التكلفة = عند التسليم». عشان كده: الصرف الجزئي اتسجّل على مستوى المخزن صح (الإذن بقى «مصروف جزئيًا 4 من 5»)، لكن طرف المبيعات ما تحرّكش (مفيش إذن متبقّي، الفاتورة فضلت «قيد الانتظار»، مفيش قيد COGS عند التسليم). الحل: فعّل الإعداد وأعد التجربة.

1 اللي حصل فعلًا (من بياناتك)

استخرجت الحالة الفعلية من قاعدة بياناتك للفاتورة والإذن اللي عملتهم:

إعدادات شركتك (Company #4)

الإعدادالقيمة الحاليةالمعنى
sales.cogs_recognition_pointNULL → "invoice"🔴 وضع الفاتورة — الميزة الجديدة مُطفأة
sales.auto_create_stock_issue_on_invoice'true'بيعمل إذن صرف مسودة تلقائيًا
sales.auto_approve_stock_issue_on_invoice'false'الإذن بيتعمل مسودة (مايتعتمدش آليًا)
sales.auto_create_backorderNULL → true(بيشتغل بس في وضع التسليم)
inventory.allow_partial_issueNULL → trueالصرف الجزئي مسموح على مستوى المخزن

الفاتورة #11 والإذن #24

الفاتورة INV-2026-00011: status = paid fulfillment_status = Pending ← لسه «قيد الانتظار» (ما اتحدّثش) cogs_journal_entry_id = NULL السطر: product 27, qty=5, delivered=0, cancelled=0 ← المُسلَّم لسه صفر! إذن الصرف GDN-000021 (#24): (اتعمل 01:40، اتعتمد 01:41 — بالكود الجديد) status = partially_issued ← المخزن سجّل إنه جزئي صح ✓ cogs_journal_entry_id = NULL delivery_processed_at = NULL ← المستمع ما اشتغلش خالص السطر: product 27, quantity=5, issued_quantity=4, source_item_id=NULL
القراءة: الإذن سجّل الصرف الجزئي صح (4 من 5، وحالته «مصروف جزئيًا»، والمخزون نقص 4). لكن delivery_processed_at=NULL وdelivered=0 وfulfillment_status=Pending — يعني مستمع المبيعات (اللي بيعمل الإذن المتبقّي ويحدّث المُسلَّم ويسجّل COGS) ما اشتغلش إطلاقًا.

2 ليه؟ السبب الجذري

الميزة الجديدة كلها متحكّم فيها بوابة واحدة: sales.cogs_recognition_point.

الصرف الجزئي على مستوى المخزن (إدخال «الكمية المنصرفة» وحالة «مصروف جزئيًا») شغّال في الوضعين — عشان كده الإذن سجّل 4 من 5 صح. لكن أوركسترا المبيعات (المتبقّي/المُسلَّم/الحالة/التكلفة) مربوطة بوضع التسليم فقط، وإنت لسه في وضع الفاتورة.

3 اللي كان المفروض يحصل (في وضع التسليم)

لو كان cogs_recognition_point = delivery، نفس خطواتك (صرف 4 من 5) كانت هتعمل:

تحديث المُسلَّم على الفاتورة

سطر الفاتورة: delivered_quantity = 4، والحالة partially_delivered (مُسلَّم جزئيًا).

قيد تكلفة المبيعات بالكمية المنصرفة

Dr COGS / Cr Inventory لقيمة الـ4 المنصرفة فقط (مش الـ5)، وdelivery_processed_at يتسجّل.

إنشاء إذن متبقّي تلقائي

إذن صرف مسودة جديد للكمية الباقية (1) مربوط بنفس الفاتورة — يظهر في طابور التسليمات بانتظار الصرف.

الإكمال لاحقًا

لما تعتمد إذن المتبقّي (1) → delivered=5، الحالة fully_delivered، وإجمالي COGS = تكلفة الـ5. أو لو الباقي مش هيتسلّم → زر «إقفال على المُسلَّم».

4 الحل (عشان تجرّب السلوك اللي توقّعته)

  1. روح المبيعات ← الإعدادات ← دوّر على «نقطة احتساب التكلفة» (COGS recognition point) وغيّرها لـ «عند التسليم» (At delivery).
    تأكّدت إن تعريف الإعداد مزروع في قاعدة بياناتك (نوع string، خيارات invoice/delivery) فالمفروض يظهر كقائمة منسدلة في الشاشة.
  2. (اختياري) فعّل «إنشاء إذن متبقّي تلقائي» و«منع التسليم الزائد» — الاتنين افتراضهم مفعّل.
  3. اعمل فاتورة جديدة → افتح الإذن المسودة → في عمود «الكمية المنصرفة» غيّر 5 لـ4 → احفظ ثم اعتمد.
  4. هتلاقي: الفاتورة «مُسلَّم جزئيًا 4/5» + إذن متبقّي مسودة بـ1 + قيد COGS للـ4.
مهم في الخطوة 3: عشان الصرف يبقى جزئي لازم تغيّر «الكمية المنصرفة» قبل الاعتماد. لو اعتمدت الإذن من غير ما تغيّرها، هيصرف الكمية كاملة (وده اللي حصل جزئيًا في تجربتك — بس إنت فعلًا غيّرتها لـ4، فالمخزن سجّلها جزئي صح).

5 ملاحظات حقيقية اكتشفتها أثناء التشخيص (تستاهل إصلاح)

ملاحظة #1 · تجربة مربكة

في وضع الفاتورة، الصرف الجزئي «مسموح» لكن بلا أي نتيجة

المخزن سمحلك تصرف 4 من 5 وحطّ الإذن «مصروف جزئيًا» — لكن لأننا في وضع الفاتورة، مفيش إذن متبقّي ولا تتبّع. ده مربك: المستخدم يفتكر إنه عمل تسليم جزئي والنظام «نسي» الباقي. التوصية: في وضع الفاتورة، يا إمّا نمنع الصرف الجزئي (نلزم بالكمية كاملة)، يا إمّا نعرض تنبيه واضح إن «التسليم الجزئي محتاج وضع التسليم».

ملاحظة #2 · ربط دقيق

تعديل المسودة بيمسح source_item_id

الإذن التلقائي بيتعمل ومعاه source_item_id (الرابط بسطر الفاتورة). لكن لما تعدّل المسودة (عشان تحط الكمية المنصرفة)، المتحكّم بيمسح الأصناف ويعيد إنشاءها من الطلب — والطلب مش بيمرّر source_item_id → بيتحوّل لـ NULL (شوفناه في إذنك). في وضع التسليم ده بيخلّي تتبّع المُسلَّم يرجع لمطابقة بالمنتج (تمام للفاتورة بسطر واحد، لكن ممكن يلخبط لو نفس المنتج في سطرين). التوصية: نحافظ على source_item_id عند التعديل.

ملاحظة #3 · عرض

شاشة الإذن تعرض «المطلوب» بشكل بارز فتبان كأنها صرفت الكل

قلت إن الإذن «عرض الداتا كاملة كأن استلمها كلها» — بينما فعليًا issued_quantity=4 وquantity=5. يبقى العرض محتاج يوضّح المطلوب 5 / المنصرف 4 / المتبقّي 1 بشكل أظهر في شاشة الإذن.

الزبدة

اللي حصل (وضع الفاتورة)اللي المفروض (وضع التسليم)
الإذن (المخزن)مصروف جزئيًا 4/5 ✓مصروف جزئيًا 4/5 ✓
المُسلَّم على الفاتورة0 (ما اتحدّثش)4
حالة تسليم الفاتورةPendingpartially_delivered
قيد COGSمفيش (عند التسليم)للـ4 المنصرفة
إذن المتبقّي (1)ما اتعملشمسودة تلقائية
مفيش عطل في المحاسبة — المخزون نقص 4 صح، والنظام شغّال زي ما هو مصمَّم. ينقص بس تفعيل وضع التسليم عشان الأوركسترا الكاملة تشتغل، + إصلاح الملاحظتين #1 و#2 لتحسين التجربة والدقة.