⚖️ LEGAL-GRADE AUDIT · مراجعة قانونية
تقرير مراجعة شاملة لنظام المحاسبة في Moon ERP
تقييم تفصيلي للنظام (Backend + Frontend + Compliance + Live API) — مع توصيات إجراءات فورية قبل التشغيل التجاري. النظام طوّره بالكامل وكيل ذكاء اصطناعي (Claude) ولم يخضع لمراجعة محاسبية متخصصة قبل هذه الوثيقة.
📅 تاريخ التقرير: 2026-05-11
🌐 البيئة المختبرة: nature.elbaset.com
📂 الملفات المُراجَعة: 410 backend PHP + 51+ frontend TS
⚙️ المنهج: 4 وكلاء متوازين + اختبار حي عبر API
⚠️ تقييم المخاطر الكلي: عالي جداً — لا يُنصح بالتشغيل التجاري قبل معالجة العيوب الحرجة المذكورة في القسم 2.
1 الملخص التنفيذي
32CRITICAL
43HIGH
22MEDIUM
17LOW
إجمالي: 114 ملاحظة موزعة على 4 محاور مراجعة. أكثرها خطورة 32 ثغرة CRITICAL تؤثر مباشرة على صحة السجلات المالية ومنها 7 مؤكدة عبر الـ Live API.
⛔ موقف النظام: النظام يحتوي على عيوب جوهرية تُعرّض الشركة لمخاطر قانونية ومحاسبية فعلية. أبرزها:
- الشيكات لا تُسجَّل في دفتر الأستاذ العام (GL) — كل المدفوعات والمستلمات بالشيكات لا تُحدث الرصيد البنكي ولا الذمم
- سندات القبض/الصرف والمصروفات لا تُرحَّل تلقائياً — bug في تمرير حقل وحيد يجعل القيود تبقى Draft إلى الأبد
- الإهلاك يمكن تشغيله أكثر من مرة لنفس الفترة — مؤكد عبر API: 200 + 200 = 400 لإهلاك شهر واحد
- الـ Exchange Rate يُتجاهَل بصمت — قيد USD برصيد 100 × 3.75 يُسجَّل كـ 100 SAR بدلاً من 375 SAR
- مفيش ZATCA e-invoicing — إلزامي قانونياً في المملكة (Phase 2)
- مفيش Audit Trail — متطلب أساسي في SOCPA و ZATCA
- Reopen Fiscal Year يعدّل قيود مرحَّلة — يكسر مبدأ ثبات السجلات المُدققة
1.1 توزيع الملاحظات حسب المحور
| المحور | CRITICAL | HIGH | MEDIUM | LOW | الإجمالي |
| Backend (Laravel) | 16 | 22 | 14 | 10 | 62 |
| Frontend (Angular) | 6 | 10 | 12 | 9 | 37 |
| Compliance (GAAP/SOCPA/ZATCA) | 6 | 8 | 11 | 8 | 33 |
| Live API Testing | 4 | 3 | 2 | 3 | 12 |
1.2 جدول المحتويات
2 الإجراءات الفورية المطلوبة (Stop-Ship)
⛔ توقف عن استخدام هذه الموديولات في الإنتاج فوراً حتى الإصلاح:
🛑 إيقاف فوري (P0)
- سير عمل الشيكات (Checks) — Cash/Collect/Deliver/Deposit جميعها لا تُحدث الـ GL أو تنشئ قيوداً ذاتية الإلغاء
- إعداد
auto_post_entries — يتجاوز الـ Approval / Permissions، يجب إغلاقه على مستوى الـ DB
- Petty Cash standalone transactions — لا تُنشئ JE
- Fixed Asset → Sell — يدبت Depreciation Expense بقيمة البيع (محاسبياً خاطئ كلياً)
- Reopen Fiscal Year — يحذف ثبات السجلات المُدققة
- Foreign-currency Journal Entries — حتى يُضاف input للـ currency/rate في الواجهة وقراءته في الـ Backend
- Bank Reconciliation /complete — يقبل reconciliation غير متزنة
⚠️ مراجعة بيانات قائمة (P1)
- البحث عن JEs ذاتية الإلغاء (line.account_id == line.account_id) — كل شيك مرّ بالنظام
- البحث عن Approved vouchers بـ JE.status = Draft (مصروفات/إيرادات معتمدة لكن غير مرحَّلة)
- البحث عن Posted JEs بـ entry_number = NULL (قيود year-end)
- البحث عن Bank Reconciliations مكتملة بـ difference ≠ 0
- التحقق من قيود الإهلاك المكررة لنفس الأصل والفترة
- التحقق من قيود FX بـ exchange_rate = 1 لعملات غير الأساسية
3 عيوب البنية التحتية الحرجة (Backend)
المراجعة شملت 410 ملف PHP في Modules/Accounting/. هذه أبرز 16 ثغرة CRITICAL:
C1–C4 · سير عمل الشيكات مكسور بالكامل — Bank GL لا يُحدَّث
CRITICAL
app/Actions/CashCheck.php · CollectCheck.php · DeliverCheck.php · DepositCheck.php
- الخطأ
- عند صرف شيك (CashCheck) أو تحصيل شيك (CollectCheck): الـ JE يحتوي على سطرين كلاهما يستخدم نفس
bank_account.account_id (مرة debit ومرة credit) → التأثير الصافي = صفر. أما DeliverCheck و DepositCheck فلا ينشئان JE نهائياً.
- الأثر القانوني
- الشركة تدفع للموردين بشيكات والرصيد البنكي في النظام لا ينخفض — قائمة المركز المالي تُظهر أصولاً أعلى من الحقيقة وذمم دائنة أعلى من الحقيقة. هذا يُعتبر إغفال مادي (material misstatement) ويُخالف SOCPA.
- الإصلاح
- إعادة كتابة الـ Actions: عند الصرف debit AP credit Bank؛ عند التحصيل debit Bank credit AR. وإضافة JE عند الإصدار والإيداع.
C6 · سندات الصرف/القبض والمصروفات لا تُرحَّل (Vouchers stay Draft)
CRITICAL
app/Actions/ApproveExpense.php · ApprovePaymentVoucher.php · ApproveReceiptVoucher.php
- الخطأ
- عند الاعتماد، يُمرَّر للـ
CreateJournalEntry حقل 'type' => ... بدلاً من 'entry_type' — Laravel يحذف الحقل المجهول بصمت، والقيد يبقى Draft. ولأن auto_post_entries مغلق افتراضياً، القيد لا يصل للـ GL أبداً. والأسوأ: CancelExpense يحاول عكس قيد Posted ويفشل.
- الأثر
- كل المصروفات والإيرادات والسندات المعتمدة لا تظهر في دفتر الأستاذ — قائمة الدخل ناقصة بشكل كبير.
- الإصلاح
- تغيير المفتاح إلى
'entry_type' + إضافة $this->postEntry($entry) داخل Approve.
C5 · Petty Cash لا يُنشئ قيوداً للمعاملات المستقلة
CRITICAL
app/Actions/PettyCashTransaction*
- الأثر
- كل مدفوعات/مقبوضات النقدية المنفصلة (replenishment, ad-hoc) لا تصل للـ GL — رصيد النقدية في الدفاتر خاطئ.
C7 + C14 · auto_post_entries يتخطى الـ Approval/Permission
CRITICAL
app/Actions/CreateJournalEntry.php · ApproveJournalEntry.php
- الأثر
- إعداد واحد يفعّل auto-post → نفس المستخدم المنشئ يُرحّل القيد بدون مراجعة، يكسر Segregation of Duties ومتطلب SOCPA.
C8 · Fixed Asset → Sell يدبت حساب الإهلاك بقيمة البيع
CRITICAL
app/Services/FixedAssetService.php :: sell()
- الخطأ
- عند بيع أصل بـ 50,000 ر.س: الـ Debit يذهب لـ
depreciation_expense_account بدلاً من Cash/Bank.
- الأثر
- مصروف الإهلاك يتضخم بقيمة البيع، والنقدية لا تظهر — قائمة الدخل والمركز المالي خاطئتان.
C9 · إنشاء أصل ثابت لا يُولّد JE اقتناء
CRITICAL
- الأثر
- الأصول الثابتة المُسجَّلة لا تظهر في الميزانية العمومية أبداً.
C10 · ReopenFiscalYear يُعدّل قيود مرحَّلة (يكسر Audit Immutability)
CRITICAL
- الخطأ
- بدلاً من إنشاء قيود عكسية، يُحوِّل قيود الإقفال إلى Cancelled مباشرة في الـ DB.
- الأثر القانوني
- يُعتبر تلاعباً بالسجلات المحاسبية. التقارير التاريخية تتغيّر بعد التدقيق. مخالف لمعايير IAS 1 ومتطلبات الـ audit trail.
C11 · Year-End Closing JEs تُسجَّل بـ entry_number = NULL
CRITICAL
- الأثر
- قيود الإقفال بلا رقم تسلسلي — لا يمكن تتبعها أو الإشارة إليها في تقرير المدقق.
C13 · يمكن عكس نفس القيد مرتين
CRITICAL
- الإثبات
- مؤكد عبر Live API: قيد ID=6 تم عكسه إلى ID=8 و ID=9 — كلاهما يحمل
reversed_entry_id:6.
- الأثر
- إذا تم ترحيل العكسيتين، المعاملة الأصلية تُلغى مرتين — رصيد سالب وهمي.
C15 · CostAllocationService لا يعالج باقي القسمة
CRITICAL
- الإثبات
- توزيع 100 على 3 مراكز تكلفة → 33.333 × 3 = 99.999 ≠ 100 → JE غير متزن.
C16 · ApproveJournalEntry لا يتحقق من period.is_open
CRITICAL
- الأثر
- قيد بتاريخ في فترة مُقفلة يمكن اعتماده — يكسر Period Locking.
أبرز HIGH (22 ملاحظة)
| # | العنوان | الأثر |
| H1 | ExchangeRateService يتجاهل اتجاه العكس | قيود FX بأسعار صرف = 1 صامتاً |
| H2 | JournalEntryLine.exchange_rate افتراضي = 1 | أرصدة العملة الأساسية خاطئة لقيود FX |
| H3 | لا يوجد تتبع FX gain/loss | إعادة تقييم نهاية الفترة غير متاحة |
| H6 | journal_entry_lines.account_id بلا FK constraint | orphan IDs ممكنة عند حذف حساب |
| H11 | TaxService غير مُستخدَم في Expense/Revenue Controllers | الضرائب تُحسب يدوياً بدون توحيد |
| H14 | CompleteReconciliation لا يفرض difference == 0 | تسوية بنكية غير متزنة معتمدة |
| H16 | Fixed Asset salvage/life يتغيران بعد الرسملة دون JE تعديل | الإهلاك المتبقي خاطئ |
| H17 | الإهلاك بلا mid-month proration | الأصول المشتراة منتصف الشهر تُهلك شهراً كاملاً |
| H18 | Recurring Entry يستخدم القالب الحي (لا snapshot) | تعديل قالب لاحقاً يغيّر سلوك المرات السابقة المُجدوَلة |
| H21 | Netting يمكن أن يتجاوز الرصيد المطلوب | over-net في AR/AP |
📄 التقرير الكامل (62 ملاحظة، 28 KB)
4 عيوب الواجهة (Frontend / Angular)
FC1 · Journal Entry بلا حقول currency/exchange_rate في الواجهة
CRITICAL
- الأثر
- المستخدم لا يستطيع إنشاء قيد بعملة أجنبية من الواجهة، رغم وجود الحقول في الـ model — أي قيد FX يُسجَّل بسعر صرف = 1 (مفقود).
FC3 · Bug توقيت UTC vs Local — قيود تروح للسنة الخطأ
CRITICAL
recurring-entries.component.ts, bank-reconciliations.component.ts, fixed-assets.component.ts, opening-balances.component.ts
- الخطأ
- استخدام
toISOString().split('T')[0] يحوّل التاريخ إلى UTC. مستخدم في السعودية (UTC+3) يختار 2026-01-01 → يُحفظ كـ 2025-12-31.
- الأثر
- قيود بداية السنة تذهب للسنة المالية السابقة → التقارير المقارنة مشوّهة، الإقفال خاطئ.
- الإصلاح
- استخدام دالة
formatDate() محلية (مثل ما فعل journal-entries.component.ts).
FC6 · فجوات في validation الـ Journal Entry lines
CRITICAL
- الفجوات
-
- لا يمنع debit = 0 AND credit = 0 (سطر فارغ)
- لا يمنع debit > 0 AND credit > 0 على نفس السطر
- tolerance الـ "balanced" غير متّسق: 0.001 في JE vs 0.01 في opening-balances
FC4 · Transfer من حساب إلى نفسه مسموح به
CRITICAL
- الأثر
- لا يمنع
from_account_id == to_account_id في الـ Account Transfers.
FC5 · لا يوجد client-side guard للفترات المُقفلة
CRITICAL
- الأثر
- المستخدم يكتب القيد ثم يكتشف بعد الإرسال 422 — تجربة سيئة + مخاطرة بقيود تذهب لفترات خطأ.
أبرز HIGH (10 ملاحظات)
| # | العنوان | الأثر |
| FH3 | أزرار post/approve/reverse/dispose ظاهرة لأي مستخدم بصرف النظر عن الصلاحيات | تجربة سيئة + اعتماد على fallback الـ 403 |
| FH1 | نمط watchSave يخلط toasts بين العمليات المتزامنة | رسائل خطأ سابقة تظهر كرسائل نجاح جديدة |
| FH2 | تسريب subscriptions في كل المكونات (لا takeUntilDestroyed) | تسرّب ذاكرة على الجلسات الطويلة |
| FH7 | HTTP 422 errors تُختصر — err.error.errors لا يُقرأ | الفورم متعدد السطور لا يخبر المستخدم أي سطر فشل |
| FH8 | Reverse JE date hardcoded = اليوم | عكس قيد قديم يدخل في فترة مختلفة بصمت |
📄 التقرير الكامل (37 ملاحظة، 22 KB)
5 الامتثال للمعايير المحاسبية الدولية
CA8 · مفيش Audit Trail (متطلب SOCPA + ZATCA)
CRITICAL
- الواقع
- صفر استخدام لـ
spatie/laravel-activitylog أو أي مكتبة تسجيل تغييرات. فقط created_by/approved_by/posted_by على رؤوس القيود — أما السطور والحسابات وإعادة فتح الفترات فبدون أي سجل.
- الأثر القانوني
- عند نزاع قضائي، الشركة لا تستطيع إثبات من أجرى تعديلاً متى وماذا كان قبل التعديل. هذا متطلب أساسي في معايير SOCPA السعودية.
CA19 · Segregation of Duties غير مُفرَّض
CRITICAL
- الواقع
ApproveJournalEntry و PostJournalEntry تستقبل $userId ولا ترفض إذا كان $userId === $entry->created_by — أي شخص يقدر يُنشئ ويعتمد ويرحّل نفسه. وإعداد auto-post يقوم بهذا تلقائياً.
CA22 · Year-End Closing قابل للعكس بعد التوقيع المُدقَّق
CRITICAL
- الواقع
- ReopenFiscalYear يلغي قيود الإقفال ويعيد الحالة إلى Open. مفيش حالة "Finalized" نهائية — يعني المقارنات يمكن تعديلها بعد توقيع المدقق.
CA28 · Balance Sheet لا يتزن في فترات وسطية
HIGH
- الواقع
- صافي ربح الفترة الحالية غير مُضاف ضمن حقوق الملكية حتى الإقفال السنوي — أي balance sheet أثناء السنة لا يتزن.
CA24 · Trial Balance hard-check غائب
HIGH
- الواقع
- لا يوجد CHECK constraint على مستوى DB يضمن SUM(lines.debit) = SUM(lines.credit) لكل JE. الفحص يحصل في PHP فقط، وفي مرحلة Approve فقط — الـ drafts يمكن تكون غير متزنة.
عيوب أخرى مهمة
| # | المعيار/المتطلب | الحالة | الخطورة |
| CA5 | Matching Principle (الإهلاك = فترة الاستخدام) | بلا proration للأصول منتصف الشهر | HIGH |
| CA6 | Conservatism (تسجيل خسائر FX) | غير مدعوم | HIGH |
| CA11 | Account Hierarchy — Control accounts | Header accounts يمكن posting عليها مباشرة | HIGH |
| CA21 | Period Locking | مفروض على JE creation لكن مش على Approve | HIGH |
| CA29 | Cash Flow Statement | يصف نفسه "simplified" — مش متوافق مع IAS 7 | MEDIUM |
| CA30 | AR/AP Aging Reports | موجودة لكن بحاجة فحص دقيق | MEDIUM |
📄 التقرير الكامل (33 ملاحظة، 13 KB)
6 نتائج اختبار API الحي (مؤكدة بالأدلة)
أُجريت 15 سيناريو اختبار حي على البيئة الإنتاجية nature.elbaset.com. هذه النتائج مؤكدة بـ HTTP responses حقيقية وليست تخمين.
API-1 · سعر الصرف يُتجاهل بصمت في قيود العملة الأجنبية
CRITICAL · مؤكد
- الاختبار
- POST قيد بسعر صرف 3.75 لـ 100 USD
- المتوقع
- base_debit = 375 SAR
- الفعلي
- base_debit = 100, exchange_rate = 1.0 — القيمة بالعملة الأساسية خاطئة بنسبة 73%
API-2 · Bank Reconciliation تكتمل بفرق غير صفر
CRITICAL · مؤكد
- الاختبار
- إكمال reconciliation: closing=1000, reconciled=0, لا توجد سطور مطابقة
- المتوقع
- 422 يمنع الإكمال
- الفعلي
- HTTP 200,
difference: 0 (محسوبة خطأ)، Reconciliation معتمدة وهمياً
API-3 · الإهلاك ليس Idempotent — تكرار التشغيل يضاعف القيمة
CRITICAL · مؤكد
- الاختبار
- تشغيل depreciation لنفس
period_date مرتين
- الفعلي
- تم إنشاء JE-1 (200) + JE-2 (200) = 400 لإهلاك شهر واحد. أي cron retry يضاعف القيمة.
- الأثر
- الأصول يمكن أن تُهلك بأكثر من قيمتها الدفترية.
API-4 · يمكن عكس نفس القيد عدة مرات
CRITICAL · مؤكد
- الاختبار
- قيد ID=6 → reverse → JE-8 (
reversed_entry_id:6) → reverse مرة أخرى → JE-9 (reversed_entry_id:6)
- الأثر
- إذا تم post العكسيتين، الأثر = إلغاء مرتين = رصيد سالب وهمي.
API-5 · سطر يحمل debit و credit معاً مسموح
HIGH · مؤكد
- المثال
- سطر بـ debit=100 و credit=100 يمر — يخالف قواعد القيد المزدوج. وينفخ
period_debit/credit في Trial Balance.
API-6 · القيود غير المتزنة تُقبَل في CREATE
HIGH · مؤكد
- الاختبار
- POST قيد debit=100, credit=50 → HTTP 201 (المتوقع 422)
الفحص يحدث فقط عند Approve.
API-7 · General Ledger مرتب حسب ID وليس تاريخ القيد
HIGH · مؤكد
- المثال
- قيد فبراير ظهر بعد قيد مايو في dump → الـ running balance بلا معنى زمنياً.
الاختبارات التي نجحت ✅
- Period Locking يمنع إنشاء قيد بتاريخ في فترة مُقفلة
- Double-post محظور
- حذف Posted JE محظور
- إغلاق فترة بـ unposted entries محظور
- Reversal يعكس debits/credits بشكل صحيح ويربط بالأصل
- Trial Balance: Σdr = Σcr ✓
- Balance Sheet: Assets = Liabilities + Equity ✓ (عند إقفال السنة)
- SQL Injection / XSS payload escaped بأمان (Laravel ORM)
- Multi-tenant isolation يعمل (لا تسرّب بيانات بين شركات)
- Concurrent posts تنتج entry_numbers فريدة (atomic sequence)
- Server يعيد حساب tax_amount حتى لو العميل أرسل قيمة خاطئة
📄 التقرير الكامل (12 ملاحظة، 11 KB)
7 الامتثال للوائح السعودية (SOCPA · ZATCA)
SA1 · مفيش ZATCA E-Invoicing (Phase 2)
CRITICAL · إلزامي قانونياً
- الواقع
- صفر تطابق لكلمات: zatca, e-invoice, einvoice, fatoorah, UBL, XML invoice. لا يوجد QR code TLV، لا CSID، لا API clearance.
- الأثر القانوني
- كل فاتورة تُصدرها الشركة بعد ديسمبر 2023 يجب أن تكون إلكترونية ومُعتمدة من ZATCA. عدم الامتثال = غرامات + إيقاف فوترة.
SA2 · مفيش Withholding Tax Workflow
CRITICAL
- الواقع
TaxType::Withholding موجودة كـ enum case فقط — لا خدمة، لا تكامل مع Payment Vouchers، لا تقرير. ضرورية للموردين الأجانب (5%/15%/20%).
SA3 · مفيش حساب الزكاة
CRITICAL
- الواقع
- صفر إشارة في الكود لـ "zakat". إلزامي للشركات المملوكة للسعوديين.
SA4 · SAR محفوظة بـ decimal(15,3) بدلاً من (15,2)
HIGH
- الأثر
- هلالة (1/100 SAR) دقتها 2 رقم عشري. الـ 3 خانات تُسبّب sub-halala drift عند الجمع المتكرر، ولا تتطابق مع لقطات ZATCA.
SA5 · مفيش تواريخ هجرية
MEDIUM
- الواقع
- كل التواريخ ميلادية فقط. التقارير الحكومية والزكاة تتطلب هجري في كثير من الحالات.
SA6 · VAT 15% — مدعوم جزئياً
MEDIUM
- الواقع
- tax-rates module موجود وبرسم 15%. لكن:
- لا VAT recoverable vs VAT payable accounts منفصلة بوضوح
- لا تقرير "VAT Return" جاهز للتقديم
- لا تتبع inclusive vs exclusive بشكل منهجي
8 نقاط القوة في النظام
رغم العيوب الخطيرة، النظام يحتوي على أساسات تقنية جيدة يمكن البناء عليها:
- ✅ BCMath مستخدم في التحقق من توازن JE (دقة حسابية صحيحة بدلاً من float)
- ✅ Decimal columns في كل أعمدة الأموال (15,3 و 12,3) — لا float في DB
- ✅ DB Transactions تغلّف العمليات متعددة الخطوات في الـ Core Actions
- ✅ Action Pattern نظيف — كل عملية مكتوبة كـ class مستقل (Create/Cancel/Reverse/Approve/Post)
- ✅ Permission middleware على كل الـ controllers بصلاحيات دقيقة
- ✅ fiscal_period.is_closed check في PostJournalEntry (لكن مفقود في Approve — C16)
- ✅ Reversal Pattern ينشئ قيداً عكسياً جديداً بدلاً من تعديل الأصل (يحفظ الـ audit trail)
- ✅ Sequence on post — أرقام تسلسلية ذرية بدون فجوات من الإلغاءات
- ✅ Multi-currency storage — كل سطر له debit/credit + base_debit/base_credit (البنية موجودة، تحتاج تفعيل في الـ UI والـ Service)
- ✅ SoftDeletes في معظم الجداول الرئيسية
- ✅ Multi-tenant scoping على مستوى الـ controllers (company_id filter)
- ✅ NgRx slices موحدة في الواجهة
- ✅ Server-side pagination مطبّق بشكل سليم
- ✅ JE Balance UI — العرض المرئي لرصيد debits/credits أثناء الإدخال ممتاز
- ✅ Multi-tenant Isolation — مؤكد عبر API testing
- ✅ SQL Injection محمي عبر Eloquent ORM
9 خطة المعالجة المقترحة
المرحلة 0 — قبل أي تشغيل تجاري (يوم 1)
- إيقاف سير عمل الشيكات بالكامل من الـ UI
- إيقاف إعداد
auto_post_entries وحذفه من الـ DB
- إيقاف Petty Cash standalone و Fixed Asset Sell و Reopen Fiscal Year
- إيقاف Bank Reconciliation /complete حتى إضافة فحص الفرق
المرحلة 1 — إصلاحات حرجة (أسبوع 1)
| المهمة | الجهد المقدّر | الأولوية |
| إصلاح Check Actions الأربعة (C1-C4) — JEs صحيحة للصرف/التحصيل/الإيداع | 3 أيام | P0 |
| إصلاح bug 'type' → 'entry_type' في Approve Actions + إضافة auto-post الصريح (C6) | 1 يوم | P0 |
| إضافة JEs لـ Petty Cash standalone و Fixed Asset Sell و Acquisition (C5, C8, C9) | 2 يوم | P0 |
| إعادة كتابة ReopenFiscalYear بإنشاء قيود عكسية بدلاً من mutation (C10) | 1 يوم | P0 |
| إضافة guard ضد reverse مرتين (C13) | 2 ساعة | P0 |
| إصلاح CostAllocation rounding residual (C15) | 3 ساعات | P0 |
| إضافة period.is_open check في Approve (C16) | 1 ساعة | P0 |
| إصلاح Depreciation Idempotency + قراءة exchange_rate (API-1, API-3) | 1 يوم | P0 |
| إصلاح Bank Reconciliation difference check (API-2) | 3 ساعات | P0 |
| إصلاح date timezone في 4 شاشات Frontend (FC3) | 2 ساعة | P0 |
المرحلة 2 — الامتثال السعودي (أسبوع 2-4)
- تكامل ZATCA Phase 2 (UBL 2.1 XML + QR TLV + CSID + API clearance)
- إضافة Audit Log عبر spatie/activitylog — على JE، Account، Voucher، FiscalYear
- تطبيق Segregation of Duties: ApproveJE يرفض إذا approver == creator
- إضافة Withholding Tax workflow + تقرير
- إضافة Zakat calculation module
- تحويل SAR من decimal(15,3) إلى decimal(15,2)
- إضافة Year-End Finalization (irreversible)
المرحلة 3 — تحسينات (أسبوع 5-6)
- FX gain/loss tracking + Period-end revaluation
- Fixed Asset mid-month proration
- إصلاح Frontend HIGH findings (permissions on buttons, subscription leaks, 422 error display)
- إضافة Trial Balance hard-check (DB CHECK constraint)
- إضافة Cash Flow statement متوافق مع IAS 7
المرحلة 4 — تدقيق بيانات قائمة
قبل تشغيل النسخة المُصلَّحة، يجب تنفيذ مسح للبيانات الحالية للبحث عن:
- JEs ذاتية الإلغاء (sum debit on account A = sum credit on account A)
- Vouchers/Expenses Approved بـ JE.status = 'draft'
- JEs Posted بـ entry_number = NULL
- Bank Reconciliations Completed بـ difference ≠ 0
- Depreciation JEs مكررة لنفس asset_id + period_date
- JE Lines مع currency_id ≠ base_currency و exchange_rate = 1
10 المنهجية والمراجع
10.1 منهجية المراجعة
أُجريت المراجعة بواسطة 4 وكلاء ذكاء اصطناعي متوازين، كل وكيل مسؤول عن بُعد محدد:
10.2 المعايير المعتمدة
- IFRS / IAS — IAS 1 (Presentation), IAS 7 (Cash Flows), IAS 16 (PPE), IAS 21 (FX)
- SOCPA — Saudi Organization for Chartered & Professional Accountants
- ZATCA — Phase 2 E-Invoicing technical specifications
- Saudi Tax Law — VAT 15%, Withholding Tax, Zakat
10.3 قيود المراجعة
ما لم تشمله هذه المراجعة (بحاجة لمراجعة مستقلة):
- ملف Routes الكامل + Policies — للتأكد من تغطية permission middleware
- Background scheduler wiring — تحديد توقيت تشغيل Recurring Entries
- Multi-tenant Global Scopes على مستوى Base Model
- Resources (Http/Resources/*) — قد تسرّب حقول داخلية
- OpeningBalance Lock/Unlock workflow كاملاً
- Reports Services بالكامل (BalanceSheetService, IncomeStatementService, CashFlowService, AgingReportService)
- اختبار الأداء والـ load testing
- Penetration Testing للأمان
10.4 توقيع التقرير
| البند | التفاصيل |
| تاريخ التقرير | 2026-05-11 |
| إصدار النظام | v0.6.0 (Unreleased) |
| البيئة المختبرة | https://nature.elbaset.com (production-like) |
| منهجية | Static code analysis + Live API testing |
| مدة المراجعة | ~30 دقيقة (مراجعة متوازية) |
| إجمالي الملاحظات | 114 (32 CRITICAL · 43 HIGH · 22 MEDIUM · 17 LOW) |