تدقيق متعمّق عبر 4 محاور بالتوازي: دورة الإنتاج والترحيل المحاسبي · التكاليف والانحرافات · التخطيط (MRP/CRP/MPS) · الواجهة
Moon ERP · Modules/Production + features/production · شغّال على /app/factory · قراءة فقط
الموديول مبني باحتراف وانضباط — كل القيود المحاسبية متوازنة (DR==CR) وبتمر على فاليديشن، والـstock+GL في معاملة واحدة (atomic)، والـi18n كامل 100% (850 مفتاح في العربي والإنجليزي)، وانفصال machine/labor صح ومحافظ على الإجماليات. لكن فيه مشكلتين حرجتين + مجموعة دقة مالية/أداء تحتاج إصلاح قبل التشغيل على بيانات حقيقية بحجم كبير.
فحص الحالة (canRelease/canIssue/canReceive/canClose) بيتعمل قبل الـlockForUpdate (أو من غير إعادة فحص بعد الـrefresh)، ومفيش idempotency guard على القيود (الجدول فيه index بس، مش unique على المستند).
الإصلاح: انقل فحص الحالة جوّه المعاملة بعد الـlock + refresh وأعد التأكيد؛ أضف lock مفقود لـRelease وClose؛ واربط القيد بمستنده (unique على (company_id, source_doc_type, source_doc_id)).
RunMrp.php:376-549 (planLevelByLevel) — بيدّعي المشي «الآباء قبل الأبناء» لكنه FIFO عادي مش low-level-code. أي طلب dependent بيتدمج في مكوّن بعد أول مرة اتعالج فيه → بيتجاهله الـprocessedOnce guard → المكوّنات المشتركة/العميقة بتتخطّط ناقصة. الاختبارات بتغطّي سلسلة 2-مستوى متوازنة بس (مفيش diamond/3-مستوى).
الإصلاح: حساب low-level-code لكل منتج أول (تمريرة واحدة)، وبعدين معالجة بالترتيب التصاعدي للـLLC — مايتعالجش منتج قبل ما كل آبائه الأقل مستوى يفجّروا مساهماتهم. + إضافة اختبارات للمكوّنات المشتركة والعمق.
| الخطورة | المشكلة | المكان / الإصلاح |
|---|---|---|
| CRITICAL | نافذة ترحيل مزدوج (C1) | guard قبل الـlock + مفيش idempotency — راجع فوق |
| HIGH | Close مبيقفلش صف الأوردر إطلاقاً | CloseProductionOrder.php:45-90 — أضف lockForUpdate + refresh + إعادة فحص canClose |
| HIGH | إلغاء صرف المواد بيعكس على حسابات «آخر صرف» مش الصرف الملغي | CancelMaterialIssue.php:160-219 — احفظ JE id على المستند واعكسه تحديداً (انحراف per-account) |
| HIGH | أرضيات تكلفة عكس التأكيد بتكسر تطابق WIP↔Applied | ConfirmOperation.php:355-364 — اعكس نفس المبلغ المسموح أو متعملش floor (drift بين الدفتر والفرعي) |
| MEDIUM | اكتشاف «الريل» بـ=== 0.0 هشّ | ProductionOrderController.php:323 — اكتشف بوجود مستندات issue/GR (زي Close) |
| MEDIUM | بواقي تحت 0.01 بتتسايب في WIP وبتتراكم | CloseProductionOrder.php:53-72 — اكنس أي بقية غير صفرية أو وثّق sweep دوري |
| MEDIUM | فشل الترحيل التلقائي بيسيب المخزون اتحرّك والـGL Draft بصمت | CreateJournalEntry.php:134-146 — راقب قيود الإنتاج Draft أو افشل بصوت عالٍ |
| LOW | تكلفة الصرف بـfirstWhere(product_id) بتخلط السطور المكرّرة | IssueMaterials.php:117 — طابق بالـindex/id (الإجمالي صح، التوزيع لأ) |
| الخطورة | المشكلة | المكان / الإصلاح |
|---|---|---|
| HIGH | أساس المعيار في الانحرافات (3 أرجل) ممكن يختلف قرش-قرشين عن قيد GR (رجل واحدة) | ComputeOrderVariances.php:178/236/289 ضد PostGoodsReceiptJournal.php:56 — وحّد أساس التقريب بين الاتنين |
| MEDIUM | مجمّع تكلفة المواد مش بيتعمله re-round بعد الجمع (تسريب أقل من قرش) | IssueMaterials.php:165 — round(sum + inc, 3) زي confirmation/cancel |
| MEDIUM | FOVV في وضع applied tautology (بيتسجّل كانحراف لكنه لا يطابق) | ComputeOrderVariances.php:368 — اقمعه أو علّمه structured flag |
| MEDIUM | حساب Applied OH مبيتصفّاش في الوضع الافتراضي → الحساب بيكبر بلا حد | SettleAppliedOverhead.php:166 — وثّق/صفّي حساب الامتصاص دورياً (نظافة GL) |
| LOW | fallback صفر-ساعات بيحط كل الانحراف في رجل المعدّل · اختيار routing مكرّر في ملفين · Labor Applied تحت الخصوم | تفاصيل في تقرير الوكيل — تطابق reconciliation محفوظ |
| الخطورة | المشكلة | المكان / الإصلاح |
|---|---|---|
| CRITICAL | صافي الاحتياجات متعدد المستويات (C2) — FIFO مش LLC | RunMrp.php:376-549 — راجع فوق |
| HIGH | تواريخ سريان الـBOM (effective_from/to) متجاهلة تماماً في كل الـ3 resolvers | RunMrp.php:924 · BomExplosionService.php:136 · BuildComponentOrders.php:170 |
| HIGH | مفيش index على inventory_stock_balances(company_id, product_id) → full scan لكل منتج | أضف index + ادمج الـSUMين + اسحب الكل دفعة واحدة (ده «MRP at scale» المؤجّل) |
| HIGH | عاصفة N+1 (5 استعلام/منتج + 2/bucket، مفيش BOM cache) | RunMrp.php:608/942 — preload مجمّع + cache (زي CRP) |
| MEDIUM | المعاملة كلها synchronous · POQ/EOQ شبه no-op · on-hand company-wide مش warehouse | حوّل لـqueued job بعد إصلاح الاستعلامات · وثّق حدود lot-sizing · وحّد نطاق التوفّر |
| LOW | CRP idle fan-out · nextRunNumber count()+1 race · مفيش وردية ليلية | تفاصيل في تقرير الوكيل (محدودة) |
| الخطورة | المشكلة | المكان / الإصلاح |
|---|---|---|
| HIGH | material_ownership بيتشال عند الحفظ → أوامر التصنيع للغير (toll) مينفعش تتعمل أصلاً | production-orders.component.ts:511 — ضيف الحقل للـpayload |
| HIGH | مفيش *appCan على أزرار الكتابة إطلاقاً (0 مرة) → مفيش صلاحية «عرض فقط»؛ أي حد يفتح الشاشة يقدر يصرف/يستلم/يعمل فاتورة toll | طبّق *appCan على Release/Issue/Complete/Cancel/Run/Approve (زي LIS) |
| HIGH | نوع رجوع getCosting() غلط (nested مش flat) → تاب التكاليف فضي قبل كده | production-order.service.ts:185 — صحّح النوع وادمج الـflatten |
| HIGH | تحويل استثناء MRP بيطابق بالـproduct_id بس → ممكن يحوّل الأوردر الغلط | mrp-cockpit.component.ts:642 — disambiguate بمعرّف الطلب |
| MEDIUM | عدم تناسق دقة الأرقام (2/3/4 منازل) + أرقام خام بدون number pipe + تواريخ batches off-by-one | وحّد على 3 منازل + locale حسب اللغة |
| MEDIUM | production-orders.component.ts = 1502 سطر (~2× الحد) | استخرج 3 dialogs (Issue/Receive/Toll) لمكوّنات فرعية |
| LOW | ابتلاع أخطاء صامت في تحميل القوائم · production-tools مفيهوش OnDestroy · كود ميت بسيط | ضيف toasts + takeUntilDestroyed |
| الأولوية | البند | الأثر |
|---|---|---|
| 1 | قفل دورة الإنتاج + idempotency للقيود (C1, H1-lifecycle) — نقل فحص الحالة جوّه الـlock + ربط القيد بالمستند | يمنع ترحيل/مخزون مزدوج (خطر مالي مباشر) |
| 2 | إعادة كتابة netting الـMRP كـlow-level-code (C2) + اختبارات shared/deep | يمنع تحت-تخطيط المكوّنات |
| 3 | أداء MRP: index على stock_balances + preload مجمّع + BOM cache (الدين المؤجّل) | يخلّيه يشتغل at scale |
| 4 | سريان الـBOM (effective dates) في الـ3 resolvers | صحة الاحتياجات |
| 5 | FE: material_ownership في الحفظ + *appCan على أزرار الكتابة + نوع getCosting | toll يشتغل + صلاحيات عرض-فقط |
| 6 | توحيد أساس التقريب (variances↔GR) + re-round مجمّع المواد + نظافة Applied OH | دقة مالية للقرش |
| 7 | تنظيف: تقسيم production-orders (1502 سطر)، توحيد دقة الأرقام، toasts للأخطاء | جودة وصيانة |