39528-vm/index.php
2026-04-09 09:46:40 +00:00

248 lines
16 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/app.php';
if (!is_logged_in()) {
render_header('بوابة ERP', 'نظام ERP ويب على PHP + MySQL مع تسجيل دخول وصلاحيات ومخزون ومشتريات ومبيعات وتصنيع ومحاسبة.', 'dashboard');
?>
<section class="hero-panel mb-4 mb-lg-5">
<div class="row g-4 align-items-center">
<div class="col-lg-8">
<span class="eyebrow">ERP Access Portal</span>
<h1 class="hero-title">نظام ERP ويب جاهز كبداية تشغيلية متكاملة.</h1>
<p class="hero-copy">تم تجهيز نواة تشغيلية تشمل تسجيل الدخول، الصلاحيات، العملاء، الموردين، الأصناف، المشتريات، المبيعات، التصنيع، المحاسبة، وسجل حركات المخزون. ادخل بحساب مناسب لفتح لوحة التحكم.</p>
<div class="d-flex flex-wrap gap-2 mt-4">
<a href="login.php" class="btn btn-dark px-4">تسجيل الدخول</a>
<a href="healthz.php" class="btn btn-outline-secondary px-4">Health API</a>
</div>
</div>
<div class="col-lg-4">
<div class="hero-side-card h-100">
<div class="metric-label">حسابات تجريبية</div>
<?php foreach (default_account_credentials() as $cred): ?>
<div class="small mb-2"><strong><?= e($cred['username']) ?></strong> / <?= e($cred['password']) ?></div>
<?php endforeach; ?>
<p class="text-secondary small mb-0">هذه الحسابات لأغراض البداية فقط.</p>
</div>
</div>
</div>
</section>
<?php
render_footer();
exit;
}
require_permission('dashboard');
$counts = fetch_counts();
$inventory = inventory_totals();
$financial = accounting_summary();
$salesToday = today_record_count('sales_order');
$purchasesToday = today_record_count('purchase_order');
$manufacturingToday = today_record_count('manufacturing_order');
$latestSales = recent_records('sales_order', 5);
$latestPurchases = recent_records('purchase_order', 5);
$latestManufacturing = recent_records('manufacturing_order', 5);
$movements = recent_records('stock_movement', 6);
$accountingActivity = recent_accounting_activity(6);
$lowStock = low_stock_products(5);
$current = current_user();
$rawPercent = $inventory['all_qty'] > 0 ? round(($inventory['raw_qty'] / $inventory['all_qty']) * 100, 1) : 0;
$finishedPercent = $inventory['all_qty'] > 0 ? round(($inventory['finished_qty'] / $inventory['all_qty']) * 100, 1) : 0;
$totalManufactured = 0.0;
foreach (fetch_records('manufacturing_order') as $order) {
$totalManufactured += (float)($order['payload_data']['produced_qty'] ?? 0);
}
render_header('لوحة ERP المركزية', 'لوحة تشغيل يومية للعملاء والموردين والأصناف والمبيعات والمشتريات والتصنيع والمحاسبة وحركات المخزون.', 'dashboard');
?>
<section class="hero-panel mb-4 mb-lg-5">
<div class="row g-4 align-items-center">
<div class="col-lg-8">
<span class="eyebrow">Phase 5 ERP Foundation</span>
<h1 class="hero-title">تشغيل يومي موحّد مع تقارير فورية لكل أقسام الـ ERP.</h1>
<p class="hero-copy">مرحبًا <?= e($current['full_name'] ?? '') ?> — هذه النسخة تدعم تسجيل الدخول والصلاحيات، الموردين، أوامر الشراء، مسار المبيعات الكامل، أوامر التصنيع، المحاسبة التشغيلية، وسجل حركات المخزون، مع صفحة تقارير جديدة لتجميع الأداء حسب الفترة.</p>
<div class="quick-links mt-4">
<?php foreach (nav_items() as $item): ?>
<?php if (can_access($item['area'])): ?>
<a href="<?= e($item['href']) ?>" class="quick-link-card">
<strong><?= e($item['label']) ?></strong>
<span>فتح القسم</span>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
<div class="col-lg-4">
<div class="hero-side-card h-100">
<div class="metric-label">الدور الحالي</div>
<div class="metric-value"><?= e(role_label((string)($current['role'] ?? ''))) ?></div>
<p class="text-secondary mb-3">إجمالي السجلات التشغيلية: <?= e((string)(array_sum($counts))) ?></p>
<div class="small text-secondary">آخر تحديث: <?= e(date('Y-m-d H:i')) ?> UTC</div>
</div>
</div>
</div>
</section>
<section class="row g-3 mb-4">
<div class="col-12">
<div class="panel-card reports-callout">
<div class="section-header mb-0">
<div>
<h2 class="section-title">التقارير التنفيذية</h2>
<p class="section-copy mb-0">افتح صفحة التقارير لفلترة النتائج حسب التاريخ ومراجعة المبيعات والمشتريات والتصنيع والمحاسبة من شاشة واحدة.</p>
</div>
<?php if (can_access('reports')): ?>
<a href="reports.php" class="btn btn-dark">فتح التقارير</a>
<?php endif; ?>
</div>
</div>
</div>
</section>
<section class="row g-3 mb-4 mb-lg-5">
<div class="col-6 col-xl-3"><div class="stat-card"><div class="stat-label">العملاء</div><div class="stat-value"><?= e((string)$counts['customer']) ?></div><div class="stat-note">سجل العملاء</div></div></div>
<div class="col-6 col-xl-3"><div class="stat-card"><div class="stat-label">الموردون</div><div class="stat-value"><?= e((string)$counts['supplier']) ?></div><div class="stat-note">ربط المشتريات</div></div></div>
<div class="col-6 col-xl-3"><div class="stat-card"><div class="stat-label">الأصناف</div><div class="stat-value"><?= e((string)$counts['product']) ?></div><div class="stat-note">مواد خام ونهائية</div></div></div>
<div class="col-6 col-xl-3"><div class="stat-card"><div class="stat-label">أوامر التصنيع</div><div class="stat-value"><?= e((string)($counts['manufacturing_order'] ?? 0)) ?></div><div class="stat-note"><?= e((string)$manufacturingToday) ?> اليوم</div></div></div>
<div class="col-6 col-xl-3"><div class="stat-card"><div class="stat-label">مبيعات اليوم</div><div class="stat-value"><?= e((string)$salesToday) ?></div><div class="stat-note"><?= e(format_money(today_sales_value())) ?></div></div></div>
<div class="col-6 col-xl-3"><div class="stat-card"><div class="stat-label">مشتريات اليوم</div><div class="stat-value"><?= e((string)$purchasesToday) ?></div><div class="stat-note"><?= e(format_money(today_purchase_value())) ?></div></div></div>
<div class="col-6 col-xl-3"><div class="stat-card"><div class="stat-label">المقبوضات</div><div class="stat-value"><?= e(format_money((float)$financial['customer_receipts'])) ?></div><div class="stat-note">اليوم <?= e(format_money((float)$financial['today_receipts'])) ?></div></div></div>
<div class="col-6 col-xl-3"><div class="stat-card"><div class="stat-label">المصروفات</div><div class="stat-value"><?= e(format_money((float)$financial['expenses'])) ?></div><div class="stat-note">اليوم <?= e(format_money((float)$financial['today_expenses'])) ?></div></div></div>
</section>
<section class="row g-4 mb-4 mb-lg-5">
<div class="col-lg-7">
<div class="panel-card h-100">
<div class="section-header"><div><h2 class="section-title">الصورة التشغيلية والمالية</h2><p class="section-copy">مخزون، ذمم، ربح متوقع، وتدفق نقدي في ملخص واحد.</p></div></div>
<div class="row g-3">
<div class="col-md-6"><div class="stat-card stat-card-soft"><div class="stat-label">إجمالي المخزون</div><div class="stat-value"><?= e((string)$inventory['all_qty']) ?></div><div class="stat-note"><?= e((string)$inventory['sku_count']) ?> صنف نشط</div></div></div>
<div class="col-md-6"><div class="stat-card stat-card-soft"><div class="stat-label">إجمالي الإنتاج المرحّل</div><div class="stat-value"><?= e((string)$totalManufactured) ?></div><div class="stat-note">ناتج أوامر التصنيع المكتملة</div></div></div>
<div class="col-md-6"><div class="stat-card stat-card-soft"><div class="stat-label">ذمم العملاء</div><div class="stat-value"><?= e(format_money((float)$financial['receivables'])) ?></div><div class="stat-note">من فواتير المبيعات</div></div></div>
<div class="col-md-6"><div class="stat-card stat-card-soft"><div class="stat-label">ذمم الموردين</div><div class="stat-value"><?= e(format_money((float)$financial['payables'])) ?></div><div class="stat-note">من المشتريات المستلمة</div></div></div>
<div class="col-md-6"><div class="stat-card stat-card-soft"><div class="stat-label">الربح المتوقع</div><div class="stat-value"><?= e(format_money((float)$financial['expected_profit'])) ?></div><div class="stat-note">فواتير - مشتريات - مصروفات</div></div></div>
<div class="col-md-6"><div class="stat-card stat-card-soft"><div class="stat-label">صافي التدفق النقدي</div><div class="stat-value"><?= e(format_money((float)$financial['net_cashflow'])) ?></div><div class="stat-note">المقبوضات - المدفوعات - المصروفات</div></div></div>
</div>
<div class="mt-4">
<div class="summary-row mb-2"><span>الخامات (<?= e((string)$rawPercent) ?>%)</span><strong><?= e((string)$inventory['raw_qty']) ?></strong></div>
<div class="progress app-progress mb-3"><div class="progress-bar bg-secondary" style="width: <?= e((string)$rawPercent) ?>%"></div></div>
<div class="summary-row mb-2"><span>المنتجات النهائية (<?= e((string)$finishedPercent) ?>%)</span><strong><?= e((string)$inventory['finished_qty']) ?></strong></div>
<div class="progress app-progress"><div class="progress-bar bg-dark" style="width: <?= e((string)$finishedPercent) ?>%"></div></div>
</div>
</div>
</div>
<div class="col-lg-5">
<div class="panel-card h-100">
<div class="section-header compact"><div><h2 class="section-title">تنبيهات المخزون المنخفض</h2><p class="section-copy">الأصناف الأقرب لإعادة الطلب.</p></div></div>
<?php if ($lowStock): ?>
<div class="vstack gap-2">
<?php foreach ($lowStock as $product): $payload = $product['payload_data']; ?>
<div class="subtle-card">
<div class="d-flex justify-content-between"><strong><?= e($product['title']) ?></strong><span><?= e($payload['sku'] ?? $product['code']) ?></span></div>
<div class="small text-secondary mt-1">المتوفر: <?= e((string)($payload['stock_qty'] ?? 0)) ?> — حد الطلب: <?= e((string)($payload['reorder_level'] ?? 0)) ?></div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<div class="empty-inline">لا توجد أصناف منخفضة حاليًا.</div>
<?php endif; ?>
</div>
</div>
</section>
<section class="row g-4 mb-4 mb-lg-5">
<div class="col-lg-6">
<div class="panel-card h-100">
<div class="section-header"><div><h2 class="section-title">آخر أوامر البيع</h2><p class="section-copy">أحدث عمليات البيع المؤكدة.</p></div></div>
<?php if ($latestSales): ?>
<div class="table-responsive">
<table class="table align-middle app-table">
<thead><tr><th>الرقم</th><th>العميل</th><th>الصنف</th><th>الإجمالي</th></tr></thead>
<tbody>
<?php foreach ($latestSales as $order): $payload = $order['payload_data']; ?>
<tr><td><?= e($order['code']) ?></td><td><?= e($payload['customer_name'] ?? '') ?></td><td><?= e($payload['product_name'] ?? '') ?></td><td><?= e(format_money((float)($payload['grand_total'] ?? 0))) ?></td></tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="empty-inline">لا توجد أوامر بيع بعد.</div>
<?php endif; ?>
</div>
</div>
<div class="col-lg-6">
<div class="panel-card h-100">
<div class="section-header"><div><h2 class="section-title">آخر أوامر الشراء</h2><p class="section-copy">أحدث الأوامر الواردة من الموردين.</p></div></div>
<?php if ($latestPurchases): ?>
<div class="table-responsive">
<table class="table align-middle app-table">
<thead><tr><th>الرقم</th><th>المورد</th><th>الصنف</th><th>الإجمالي</th></tr></thead>
<tbody>
<?php foreach ($latestPurchases as $order): $payload = $order['payload_data']; ?>
<tr><td><?= e($order['code']) ?></td><td><?= e($payload['supplier_name'] ?? '') ?></td><td><?= e($payload['product_name'] ?? '') ?></td><td><?= e(format_money((float)($payload['grand_total'] ?? 0))) ?></td></tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="empty-inline">لا توجد أوامر شراء بعد.</div>
<?php endif; ?>
</div>
</div>
</section>
<section class="row g-4">
<div class="col-lg-4">
<div class="panel-card h-100">
<div class="section-header"><div><h2 class="section-title">آخر أوامر التصنيع</h2><p class="section-copy">ملخص العمليات الإنتاجية المرحّلة.</p></div></div>
<?php if ($latestManufacturing): ?>
<div class="vstack gap-2">
<?php foreach ($latestManufacturing as $order): $payload = $order['payload_data']; ?>
<div class="list-row">
<div><strong><?= e($order['code']) ?></strong><div class="small text-secondary"><?= e($payload['finished_product_name'] ?? '') ?></div></div>
<div class="text-start small"><?= e((string)($payload['produced_qty'] ?? 0)) ?> <?= e($payload['finished_unit'] ?? '') ?></div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<div class="empty-inline">لا توجد أوامر تصنيع بعد.</div>
<?php endif; ?>
</div>
</div>
<div class="col-lg-4">
<div class="panel-card h-100">
<div class="section-header"><div><h2 class="section-title">أحدث حركات المخزون</h2><p class="section-copy">تشمل المبيعات والمشتريات والتصنيع في سجل واحد.</p></div></div>
<?php if ($movements): ?>
<div class="vstack gap-2">
<?php foreach ($movements as $movement): $payload = $movement['payload_data']; $delta = (float)($payload['qty_change'] ?? 0); ?>
<div class="list-row">
<div><strong><?= e($payload['product_name'] ?? '') ?></strong><div class="small text-secondary"><?= e($payload['movement_type'] ?? '') ?> — <?= e($payload['reference_code'] ?? '') ?></div></div>
<div class="text-start"><span class="badge <?= e(movement_badge_class($delta)) ?> mb-1"><?= e(movement_direction_label($delta)) ?></span><div class="small"><?= e((string)$delta) ?> / بعد الحركة <?= e((string)($payload['qty_after'] ?? 0)) ?></div></div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<div class="empty-inline">لا توجد حركات مخزون بعد.</div>
<?php endif; ?>
</div>
</div>
<div class="col-lg-4">
<div class="panel-card h-100">
<div class="section-header"><div><h2 class="section-title">آخر نشاط محاسبي</h2><p class="section-copy">مقبوضات ومدفوعات ومصروفات مرحّلة.</p></div></div>
<?php if ($accountingActivity): ?>
<div class="vstack gap-2">
<?php foreach ($accountingActivity as $row): $payload = $row['payload_data']; ?>
<div class="list-row">
<div><strong><?= e($row['title']) ?></strong><div class="small text-secondary"><?= e($row['code']) ?></div></div>
<div class="text-start small"><?= e(format_money((float)($payload['amount'] ?? 0))) ?></div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<div class="empty-inline">لا توجد قيود محاسبية بعد.</div>
<?php endif; ?>
</div>
</div>
</section>
<?php render_footer(); ?>