258 lines
11 KiB
PHP
258 lines
11 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/app.php';
|
|
app_bootstrap();
|
|
|
|
$metrics = fetch_dashboard_metrics();
|
|
$trend = fetch_sales_trend();
|
|
$recentOrders = fetch_recent_orders(6);
|
|
$products = fetch_products();
|
|
$maxRevenue = 1.0;
|
|
foreach ($trend as $point) {
|
|
$maxRevenue = max($maxRevenue, (float) $point['revenue']);
|
|
}
|
|
|
|
render_header('لوحة التحكم', 'dashboard');
|
|
?>
|
|
<section class="mb-4 mb-lg-5">
|
|
<div class="row g-4 align-items-stretch">
|
|
<div class="col-lg-8">
|
|
<div class="card panel-card hero-panel h-100">
|
|
<div class="d-flex justify-content-between align-items-start gap-3 flex-wrap mb-4">
|
|
<div>
|
|
<span class="section-kicker">لوحة تشغيل يومية</span>
|
|
<h1 class="page-title mb-2">ERP أولي يربط المبيعات بالمخزون فوراً</h1>
|
|
<p class="page-lead mb-0">هذه النسخة الأولى تمنحك شاشة تنفيذ حقيقية: العملاء، الأصناف، أسعار خاصة لكل عميل، إنشاء أمر بيع، وتحديث المخزون والربحية مباشرة.</p>
|
|
</div>
|
|
<div class="d-flex gap-2 flex-wrap">
|
|
<a class="btn btn-dark" href="sales.php">أمر بيع جديد</a>
|
|
<a class="btn btn-outline-secondary" href="customers.php">مصفوفة العملاء</a>
|
|
</div>
|
|
</div>
|
|
<div class="row g-3 metric-grid">
|
|
<div class="col-sm-6 col-xl-4">
|
|
<div class="metric-card">
|
|
<div class="metric-label">إجمالي العملاء</div>
|
|
<div class="metric-value"><?= h((string) $metrics['customers']) ?></div>
|
|
<div class="metric-note">عملاء نشطون مع فروع وتسعير خاص</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-xl-4">
|
|
<div class="metric-card">
|
|
<div class="metric-label">إجمالي الأصناف</div>
|
|
<div class="metric-value"><?= h((string) $metrics['products']) ?></div>
|
|
<div class="metric-note">مواد خام + منتجات نهائية</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-xl-4">
|
|
<div class="metric-card">
|
|
<div class="metric-label">أصناف منخفضة</div>
|
|
<div class="metric-value"><?= h((string) $metrics['low_stock_products']) ?></div>
|
|
<div class="metric-note">تحتاج ضبطًا أو توريدًا قريبًا</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-xl-4">
|
|
<div class="metric-card">
|
|
<div class="metric-label">أوامر بيع اليوم</div>
|
|
<div class="metric-value"><?= h((string) $metrics['orders_today']) ?></div>
|
|
<div class="metric-note">مؤكدة ومخصومة من المخزون</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-xl-4">
|
|
<div class="metric-card">
|
|
<div class="metric-label">مخزون منتجات نهائية</div>
|
|
<div class="metric-value"><?= h(format_qty((float) $metrics['finished_stock'])) ?></div>
|
|
<div class="metric-note">جاهز للتسليم</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-xl-4">
|
|
<div class="metric-card">
|
|
<div class="metric-label">مخزون خامات</div>
|
|
<div class="metric-value"><?= h(format_qty((float) $metrics['raw_stock'])) ?></div>
|
|
<div class="metric-note">تغذية مستقبلية للتصنيع</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-6 col-xl-4">
|
|
<div class="metric-card">
|
|
<div class="metric-label">مبيعات اليوم</div>
|
|
<div class="metric-value"><?= h(format_money((float) $metrics['sales_today'])) ?></div>
|
|
<div class="metric-note">ربح متوقع: <?= h(format_money((float) $metrics['profit_today'])) ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-4">
|
|
<div class="card panel-card h-100">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<div>
|
|
<span class="section-kicker">حالة التفعيل</span>
|
|
<h2 class="section-title mb-0">الوحدات المتاحة الآن</h2>
|
|
</div>
|
|
</div>
|
|
<div class="stack-list">
|
|
<div class="stack-item">
|
|
<div>
|
|
<strong>Sales</strong>
|
|
<div class="text-muted small">تسعير خاص + خصم مخزون</div>
|
|
</div>
|
|
<span class="status-badge success">جاهز</span>
|
|
</div>
|
|
<div class="stack-item">
|
|
<div>
|
|
<strong>Inventory</strong>
|
|
<div class="text-muted small">تحديث مباشر بعد البيع</div>
|
|
</div>
|
|
<span class="status-badge success">جاهز</span>
|
|
</div>
|
|
<div class="stack-item">
|
|
<div>
|
|
<strong>Customers</strong>
|
|
<div class="text-muted small">فروع + منتجات مسموحة</div>
|
|
</div>
|
|
<span class="status-badge success">جاهز</span>
|
|
</div>
|
|
<div class="stack-item">
|
|
<div>
|
|
<strong>Purchasing</strong>
|
|
<div class="text-muted small">أوامر شراء واستلام</div>
|
|
</div>
|
|
<span class="status-badge pending">التالي</span>
|
|
</div>
|
|
<div class="stack-item">
|
|
<div>
|
|
<strong>Manufacturing</strong>
|
|
<div class="text-muted small">تحويل خامات لمنتجات</div>
|
|
</div>
|
|
<span class="status-badge pending">التالي</span>
|
|
</div>
|
|
<div class="stack-item">
|
|
<div>
|
|
<strong>Accounting</strong>
|
|
<div class="text-muted small">كشف حساب وربح وخسارة</div>
|
|
</div>
|
|
<span class="status-badge pending">التالي</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="mb-4 mb-lg-5">
|
|
<div class="row g-4">
|
|
<div class="col-lg-7">
|
|
<div class="card panel-card h-100">
|
|
<div class="d-flex justify-content-between align-items-center mb-4 flex-wrap gap-2">
|
|
<div>
|
|
<span class="section-kicker">مبيعات آخر 7 أيام</span>
|
|
<h2 class="section-title mb-0">اتجاه التنفيذ</h2>
|
|
</div>
|
|
<span class="text-muted small">رسم مبسط للإيراد اليومي</span>
|
|
</div>
|
|
<div class="chart-list">
|
|
<?php foreach ($trend as $point): ?>
|
|
<?php $width = max(6, (int) round(($point['revenue'] / $maxRevenue) * 100)); ?>
|
|
<div class="chart-row">
|
|
<div class="chart-meta">
|
|
<strong><?= h($point['label']) ?></strong>
|
|
<span class="text-muted small"><?= h((string) $point['order_count']) ?> طلب</span>
|
|
</div>
|
|
<div class="chart-track">
|
|
<div class="chart-bar" style="width: <?= h((string) $width) ?>%"></div>
|
|
</div>
|
|
<div class="chart-value"><?= h(format_money((float) $point['revenue'])) ?></div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-5">
|
|
<div class="card panel-card h-100">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<span class="section-kicker">لقطة مخزون</span>
|
|
<h2 class="section-title mb-0">أصناف تحتاج متابعة</h2>
|
|
</div>
|
|
<a class="btn btn-sm btn-outline-secondary" href="products.php">كل المخزون</a>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table align-middle app-table mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>الصنف</th>
|
|
<th>الفئة</th>
|
|
<th>المتاح</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach (array_slice($products, 0, 5) as $product): ?>
|
|
<tr>
|
|
<td>
|
|
<div class="fw-semibold"><?= h($product['name']) ?></div>
|
|
<div class="text-muted small"><?= h($product['sku']) ?></div>
|
|
</td>
|
|
<td><span class="status-badge <?= $product['category'] === 'finished' ? 'neutral' : 'pending' ?>"><?= $product['category'] === 'finished' ? 'منتج نهائي' : 'خامة' ?></span></td>
|
|
<td><?= h(format_qty((float) $product['stock_qty'])) ?> <?= h($product['unit']) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<div class="card panel-card">
|
|
<div class="d-flex justify-content-between align-items-center mb-4 flex-wrap gap-2">
|
|
<div>
|
|
<span class="section-kicker">آخر أوامر البيع</span>
|
|
<h2 class="section-title mb-0">تنفيذ اليوم</h2>
|
|
</div>
|
|
<a class="btn btn-sm btn-outline-secondary" href="sales.php">إدارة أوامر البيع</a>
|
|
</div>
|
|
<div class="table-responsive">
|
|
<table class="table align-middle app-table mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>رقم الطلب</th>
|
|
<th>العميل</th>
|
|
<th>الفرع</th>
|
|
<th>القيمة</th>
|
|
<th>الربح المتوقع</th>
|
|
<th>الحالة</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (!$recentOrders): ?>
|
|
<tr>
|
|
<td colspan="7">
|
|
<div class="empty-state compact">
|
|
<div class="empty-title">لا توجد أوامر بعد</div>
|
|
<div class="empty-copy">ابدأ بأول أمر بيع لتفعيل الحركة على الداشبورد والمخزون.</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($recentOrders as $order): ?>
|
|
<tr>
|
|
<td class="fw-semibold"><?= h($order['order_number']) ?></td>
|
|
<td><?= h($order['customer_name']) ?></td>
|
|
<td><?= h($order['branch_name']) ?></td>
|
|
<td><?= h(format_money((float) $order['subtotal'])) ?></td>
|
|
<td><?= h(format_money((float) $order['expected_profit'])) ?></td>
|
|
<td><span class="status-badge success">مؤكد</span></td>
|
|
<td><a class="btn btn-sm btn-outline-secondary" href="order.php?id=<?= h((string) $order['id']) ?>">تفاصيل</a></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<?php render_footer(); ?>
|