تحليل عميق لموديول الحسابات (هل شغّال، الناقص، مقارنة بالأنظمة الكبرى، نضيف إيه)، وفحص المبيعات والمشتريات والمخازن وجاهزيتهم للتكامل مع التصنيع — بأدلة من الكود وخطة عمل.
الحسابات نظام محاسبي حقيقي وكامل (مش skeleton): دليل حسابات شجري، قيود مزدوجة بـ bcmath، فترات مالية بقفل، عملات متعددة + إعادة تقييم، بنوك وتسويات، أصول ثابتة وإهلاك، موازنات ومراكز تكلفة، زكاة، وZATCA (في موديول EInvoicing). القوائم المالية موجودة (ميزان مراجعة، دخل، مركز مالي، تدفقات). والـ posting موحّد عبر action واحد — تصميم ممتاز.
validateBalance() موجودة بس **كود ميت مش متنادى**. قيد غير متوازن من أي موديول بيتحفظ ويُرحّل، والخلل بيتكشف لاحقاً بـ scanner مش بيتمنع. ده + باجز الإقفال السنوي المزدوج والترحيل المزدوج = مخاطر مالية حقيقية.StockService اللي التصنيع بيستخدمه ممتاز، بس التكلفة (WAC layers) والـ UoM والـ lot/expiry محتاجين شغل قبل تشغيل التصنيع جدّياً.CreateJournalEntry داخل transaction مع idempotency_key.AccountingServiceInterface/DTO الموجود — فالحدود المعرّفة مش بتفيد.ExpenseRevenueReportController 640 سطر (منطق تقارير في كنترولر).validateBalance كود ميت)
القيد بيحسب total_debit/credit ويخزّنهم من غير ما يتأكد إنهم متساويين. قيد غير متوازن بيتحفظ Draft من غير خطأ، والوحيد اللي بيمنع = خطوة الاعتماد (لو مش متجاوَزة). مفيش DB CHECK constraint ولا حارس وقت الكتابة → التوازن معتمد على فحص واحد بيقرأ أعمدة self-reported.
الحارس بيتأكد بس من isClosed()؛ بعد ReopenFiscalYear الحالة تبقى Reopened فالـ readiness يعدّي تاني. إقفال تاني = نقل صافي الدخل للأرباح المحتجزة مرة كمان → حقوق الملكية مبالغ فيها بسنة كاملة. وكمان: السنة بتتعلّم "مقفولة" حتى لو قيود الإقفال فشلت تترحّل بصمت.
الحارس if(!isDraft()) بدون قفل، والمستند بيتحمّل بدون lockForUpdate. اعتمادان متزامنان (دبل كليك/retry) الاتنين يعدّوا ويرحّلوا → قيدان لمستند واحد. آلية الـ idempotency موجودة في CreateJournalEntry بس مفيش action بيبعت المفتاح.
| # | المشكلة | المكان | الخطورة |
|---|---|---|---|
| — | سطر كشف بنكي يقدر يتطابق مرتين/أكثر من قيمته (مفيش unique ولا قفل) → رصيد مسوّى مبالغ فيه | BankReconciliationService.php:187 | CRIT |
| — | إشارة ربح/خسارة إعادة التقييم غلط للالتزامات (AP/قروض) — مكسب يتسجّل بدل خسارة | RevalueForeignBalances.php:59 | HIGH |
| — | الإهلاك المتناقص ~12× أبطأ (خلط شهور/سنين في المعادلة) | FixedAssetService.php:48 | HIGH |
| — | dispose() بيحط الخسارة في حساب مصروف الإهلاك ويسيب القيد غير مرحّل → الأصل يفضل في الميزانية | FixedAssetService.php:230 | HIGH |
| — | شيك مرتجع/ملغي بعد التحصيل مفيش قيد عكسي → بنك/كاش مبالغ فيه | ReturnCheck.php · CancelCheck.php | HIGH |
| — | رصيد العهدة (petty cash) lost-update بدون قفل → سحب زائد | PettyCashBalanceService.php:60 | HIGH |
| — | الإقفال/المقاصة غير transactional وبدون قفل (race) | CloseFiscalYear.php · ArApService.php:240 | HIGH |
SequenceService توليد الأرقام atomic وآمن).| القدرة | الحالة | ملاحظة |
|---|---|---|
| GL أساسي (دليل/قيود/فترات/عملات/متكررة) | موجود | ناضج |
| القوائم: ميزان/دخل/مركز مالي | موجود | — |
| قائمة التدفقات النقدية | جزئي | proxy مبسّط — مش indirect method حقيقي (مفيش working-capital/إهلاك add-back). أكبر فجوة صحة |
| أعمدة المقارنة (سنة سابقة) | ناقص | كل القوائم فترة واحدة بس |
| تسوية AR/AP على مستوى الفاتورة (allocation) | جزئي | على مستوى الحساب + netting بس |
| فرق عملة محقّق (realized FX) عند السداد | ناقص | بس unrealized revaluation |
| إقرار ضريبة القيمة المضافة بصيغة ZATCA | ناقص | في ملخص بالنسبة بس — مفيش نموذج الـ 14 خانة |
| توقيع ZATCA XAdES/XMLDSIG كامل | جزئي | التوقيع مخزّن كـ XML comment — ممكن يترفض في Phase-2 |
| الزكاة (طريقة صافي الثروة) | موجود | محتاج طبقة تعديلات SOCPA |
| أبعاد/تحليلية (project/segment) على سطر القيد | جزئي | مركز تكلفة بس |
| دمج كيانات/Intercompany · إيراد مؤجل · مسار تدقيق hash-chain · workflow اعتماد | ناقص | قدرات enterprise |
كل الـ actions المعدِّلة داخل transaction مع فحص enum؛ GL موحّد ومتوازن؛ المرتجعات بتعكس الإيراد/الضريبة/COGS وترجّع المخزون؛ تسوية مدفوعات FIFO بدايلوج كويس. PostLandedCostVoucher هو النمط المرجعي (قفل + idempotency).
| المشكلة | المكان | الخطورة |
|---|---|---|
| استلام بضاعة (GRN) ضد أمر شراء Draft/غير معتمد — يكتب مخزون و received_quantity لأمر لسه ماتعمدش | PurchaseGrnController.php:335 | CRIT |
| مسارات إنشاء/تحويل المبيعات مش transactional → headers يتيمة تلوّث طلب الـ MRP | SalesOrderController.php:120 | HIGH |
مسارات الترحيل بدون lockForUpdate + بدون whereNull(journal_entry_id) → ترحيل/خصم مخزون مزدوج | PostSalesInvoice.php:32 | HIGH |
| فاتورة يدوية بتتجاوز فحص حالة الأمر وسقف الكمية؛ مفيش فرض حد ائتماني | SalesInvoiceController.php:113 | HIGH |
received_quantity read-modify-write غير atomic؛ مفيش مسار عكس لـ GRN معتمد | PurchaseGrnController.php:524 | HIGH |
reserved_quantity متتبّع مع unique index.في الوضع الافتراضي (weighted_avg) الصرف بيقلّل total_value بس بيسيب remaining_quantity في الطبقات زي ما هي. فتقرير الأعمار (يجمع الطبقات) وتقرير قيمة المخزون (يقرأ StockBalance) مبيتصالحوش بعد أي صرف، والطبقات تكبر بلا حدود.
| المشكلة | المكان | الخطورة |
|---|---|---|
| تكلفة FIFO بتضيع عند التحويل بين المخازن (يستلم بمتوسط مش بطبقات) | ShipTransfer.php:61 | HIGH |
| FIFO بيقلّل التكلفة عند المخزون السالب (الزيادة تتصرف بتكلفة صفر) → COGS أقل | StockService.php:257 | HIGH |
قفل غير متسق: core increaseStock/decreaseStock read-modify-write بدون قفل → lost update | StockService.php:38,141 | HIGH |
| مفيش lot/expiry على StockBalance وcost layers — genealogy التصنيع مالهاش مقابل في المخزون؛ مفيش FEFO | StockBalance · InventoryCostLayer | HIGH |
| مفيش تحويل وحدات (UoM) عند حدود المخزون — صرف BOM بوحدة مختلفة عن الشراء = جمع غلط | StockService.php:47 | HIGH |
| التدفّق | الحالة | التفاصيل |
|---|---|---|
| المبيعات → MRP (الطلب) | جاهز ✅ | MRP بيقرأ SalesOrder بحقول صحيحة وdelivered_quantity متتبّع فعلاً. أهم تدفّق وهو سليم. |
| المشتريات → MRP (التوريد) | فجوة | الـ PO المُولّد من MRP بيتعمل Draft بس canConvert() بيطلب Approved → الحلقة بتقف عند موافقة يدوية. والمرتجع مبيقللش received_quantity → إشارتا التوريد بتختلفا. |
| المخازن → التصنيع | العقد ممتاز | reserve/release/ATP صحيح — بس التكلفة (WAC/FIFO) والـ UoM والـ lot محتاجين إصلاح قبل التشغيل الجدّي. |
| التصنيع → الحسابات (GL) | شغّال | عبر events→listeners بـ idempotency — أنظف نمط في الـ ERP. |
taxAmount=0) — المستخدم مبيشوفش الضريبة قبل الحفظ!qty≥0.01 بس. خطر سلامة بيانات.features/lis/ (دومين تاني)، مش في الحسابات. وميزان المراجعة tab داخل الـ ledger بس.<line-items-grid> مشترك + OnPush.| الموجة | الشغل | ليه |
|---|---|---|
| ١ — سلامة GL | افرض القيد المزدوج وقت الكتابة (+ DB CHECK)، idempotency_key من كل المعتمِدين + قفل، حماية الإقفال السنوي من التكرار | بتفسد توازن الدفاتر والأرقام دلوقتي |
| ٢ — باجز مالية | إشارة FX للالتزامات، إهلاك متناقص، dispose()، قيد عكس الشيكات، تطابق بنكي مزدوج، قفل العهدة | أرقام مالية غلط |
| ٣ — جاهزية التصنيع | قفل حلقة MRP→PR→PO، GRN ضد PO معتمد، إصلاح WAC layers + FIFO transfer/negative، UoM + lot/expiry على المخزون، قفل post paths | قبل تشغيل التصنيع جدّياً |
| ٤ — امتثال KSA | إقرار VAT بصيغة ZATCA، توقيع XAdES كامل، ضريبة عكسية، شهادات WHT، تعديلات زكاة | تنظيمي |
| ٥ — اكتمال + UI | تدفقات indirect، أعمدة مقارنة، تسوية فاتورة AR/AP، شاشات قوائم مالية في الحسابات، الضريبة الحيّة، منع الصرف الزائد، OnPush + line-items-grid | اكتمال وظيفي وتجربة |
| ٦ — enterprise | أبعاد عامة، إيراد مؤجل، دمج كيانات، مسار تدقيق hash-chain، workflow اعتماد | توسّع مستقبلي |