39529-vm/sales.php
2026-04-09 10:12:19 +00:00

170 lines
8.0 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/app.php';
app_bootstrap();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!verify_csrf($_POST['csrf_token'] ?? null)) {
flash('danger', 'انتهت صلاحية الجلسة. أعد المحاولة.');
header('Location: sales.php');
exit;
}
$customerId = (int) ($_POST['customer_id'] ?? 0);
$productId = (int) ($_POST['product_id'] ?? 0);
$qty = (float) ($_POST['qty'] ?? 0);
$notes = trim((string) ($_POST['notes'] ?? ''));
$result = create_sales_order($customerId, $productId, $qty, $notes);
flash($result['success'] ? 'success' : 'danger', $result['message']);
if (!empty($result['success'])) {
header('Location: order.php?id=' . (int) $result['order_id']);
exit;
}
header('Location: sales.php');
exit;
}
$catalog = fetch_sales_form_catalog();
$recentOrders = fetch_recent_orders(10);
$customerCount = count($catalog);
$productOptions = 0;
foreach ($catalog as $entry) {
$productOptions += count($entry['items']);
}
render_header('أوامر البيع', 'sales');
?>
<section class="mb-4">
<div class="d-flex justify-content-between align-items-start gap-3 flex-wrap mb-4">
<div>
<span class="section-kicker">Sales workflow</span>
<h1 class="page-title mb-2">إنشاء أمر بيع مع تسعير خاص وتحديث مخزون</h1>
<p class="page-lead mb-0">اختر العميل أولاً، وستظهر فقط الأصناف المسموح بها له مع السعر الخاص المخزن في النظام. عند التأكيد يتم حفظ الطلب وخصم المخزون مباشرة.</p>
</div>
<div class="d-flex gap-2 flex-wrap">
<span class="badge text-bg-light border text-dark">عملاء مفعّلون: <?= h((string) $customerCount) ?></span>
<span class="badge text-bg-light border text-dark">خيارات بيع: <?= h((string) $productOptions) ?></span>
</div>
</div>
</section>
<section class="mb-4 mb-lg-5">
<div class="row g-4 align-items-stretch">
<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">Create</span>
<h2 class="section-title mb-0">أمر بيع جديد</h2>
</div>
<span class="text-muted small">الحماية مفعلة: CSRF + prepared statements + output escaping</span>
</div>
<form method="post" id="sales-order-form" class="row g-3">
<input type="hidden" name="csrf_token" value="<?= h(csrf_token()) ?>">
<div class="col-md-6">
<label class="form-label" for="customer_id">العميل</label>
<select class="form-select" id="customer_id" name="customer_id" required>
<option value="">اختر العميل</option>
<?php foreach ($catalog as $customerId => $entry): ?>
<option value="<?= h((string) $customerId) ?>"><?= h($entry['customer_name']) ?> — <?= h($entry['branch_name']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-6">
<label class="form-label" for="product_id">الصنف المسموح</label>
<select class="form-select" id="product_id" name="product_id" required disabled>
<option value="">اختر العميل أولاً</option>
</select>
</div>
<div class="col-md-4">
<label class="form-label" for="qty">الكمية</label>
<input class="form-control" type="number" min="1" step="1" id="qty" name="qty" value="1" required>
</div>
<div class="col-md-8">
<label class="form-label" for="notes">ملاحظات</label>
<input class="form-control" type="text" id="notes" name="notes" maxlength="255" placeholder="ملاحظات داخلية على الطلب أو التسليم">
</div>
<div class="col-12 d-flex justify-content-between align-items-center flex-wrap gap-2 mt-2">
<div class="text-muted small">سيتم إنشاء أمر بيع مؤكد وحساب الربح المتوقع من تكلفة المنتج الحالية.</div>
<button class="btn btn-dark" type="submit" id="submit-order-btn">تأكيد أمر البيع</button>
</div>
</form>
</div>
</div>
<div class="col-lg-5">
<div class="card panel-card h-100 summary-card">
<div class="d-flex justify-content-between align-items-center mb-3">
<div>
<span class="section-kicker">Live summary</span>
<h2 class="section-title mb-0">ملخص فوري</h2>
</div>
<span class="status-badge neutral">Auto pricing</span>
</div>
<div class="summary-grid">
<div class="summary-row"><span>العميل</span><strong id="summary-customer">—</strong></div>
<div class="summary-row"><span>الفرع</span><strong id="summary-branch">—</strong></div>
<div class="summary-row"><span>السعر الخاص</span><strong id="summary-price">—</strong></div>
<div class="summary-row"><span>المتاح بالمخزون</span><strong id="summary-stock">—</strong></div>
<div class="summary-row"><span>الربح للوحدة</span><strong id="summary-margin">—</strong></div>
<div class="summary-row total"><span>قيمة السطر</span><strong id="summary-total">—</strong></div>
</div>
<div class="alert alert-light border mt-4 mb-0 small" id="sales-order-hint">
اختر عميلاً لعرض الأصناف المسموح بها له. إذا كانت الكمية المطلوبة أكبر من المتاح سيظهر تنبيه ويتم تعطيل الإرسال.
</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">Recent orders</span>
<h2 class="section-title mb-0">قائمة أوامر البيع</h2>
</div>
</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>
</tr>
</thead>
<tbody>
<?php if (!$recentOrders): ?>
<tr>
<td colspan="6">
<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>
<div><?= h($order['customer_name']) ?></div>
<div class="text-muted small"><?= h($order['branch_name']) ?></div>
</td>
<td><?= h(date('Y-m-d H:i', strtotime($order['created_at']))) ?></td>
<td><?= h(format_money((float) $order['subtotal'])) ?></td>
<td><?= h(format_money((float) $order['expected_profit'])) ?></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>
<script id="catalog-data" type="application/json"><?= h(json_encode($catalog, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)) ?></script>
<?php render_footer(); ?>