137 lines
6.7 KiB
PHP
137 lines
6.7 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: customers.php');
|
|
exit;
|
|
}
|
|
|
|
$result = create_customer_with_prices(
|
|
(string) ($_POST['name'] ?? ''),
|
|
(string) ($_POST['branch_name'] ?? ''),
|
|
(string) ($_POST['phone'] ?? ''),
|
|
is_array($_POST['selected_products'] ?? null) ? $_POST['selected_products'] : [],
|
|
is_array($_POST['special_price'] ?? null) ? $_POST['special_price'] : []
|
|
);
|
|
|
|
flash($result['success'] ? 'success' : 'danger', $result['message']);
|
|
header('Location: customers.php');
|
|
exit;
|
|
}
|
|
|
|
$customers = fetch_customers_with_catalog();
|
|
$finishedProducts = fetch_finished_products_for_pricing();
|
|
render_header('العملاء', 'customers');
|
|
?>
|
|
<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">Customers</span>
|
|
<h1 class="page-title mb-2">العملاء والفروع والأسعار الخاصة</h1>
|
|
<p class="page-lead mb-0">أضفت هنا أول خطوة CRUD حقيقية: يمكنك الآن إنشاء عميل جديد، تحديد فرعه، وإسناد الأصناف المسموح بها مع السعر الخاص مباشرة، ليظهر فوراً داخل شاشة أوامر البيع.</p>
|
|
</div>
|
|
<a class="btn btn-dark" href="sales.php">إنشاء أمر بيع</a>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="mb-4 mb-lg-5">
|
|
<div class="row g-4 align-items-start">
|
|
<div class="col-lg-5">
|
|
<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 customer</span>
|
|
<h2 class="section-title mb-0">إضافة عميل جديد</h2>
|
|
</div>
|
|
<span class="status-badge success">يرتبط بالمبيعات تلقائياً</span>
|
|
</div>
|
|
<form method="post" class="row g-3">
|
|
<input type="hidden" name="csrf_token" value="<?= h(csrf_token()) ?>">
|
|
<div class="col-12">
|
|
<label class="form-label" for="name">اسم العميل</label>
|
|
<input class="form-control" type="text" id="name" name="name" maxlength="160" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="branch_name">الفرع</label>
|
|
<input class="form-control" type="text" id="branch_name" name="branch_name" maxlength="160" required>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="phone">الهاتف</label>
|
|
<input class="form-control" type="text" id="phone" name="phone" maxlength="40" placeholder="+9665XXXXXXXX">
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label d-block mb-3">الأصناف المسموح بها والسعر الخاص</label>
|
|
<div class="pricing-picker">
|
|
<?php foreach ($finishedProducts as $product): ?>
|
|
<label class="pricing-option">
|
|
<div class="form-check m-0">
|
|
<input class="form-check-input" type="checkbox" name="selected_products[]" value="<?= h((string) $product['id']) ?>">
|
|
</div>
|
|
<div class="pricing-option-body">
|
|
<div class="fw-semibold"><?= h($product['name']) ?></div>
|
|
<div class="text-muted small"><?= h($product['sku']) ?> · <?= h($product['unit']) ?> · متاح <?= h(format_qty((float) $product['stock_qty'])) ?></div>
|
|
</div>
|
|
<div class="pricing-option-price">
|
|
<input class="form-control" type="number" step="0.01" min="0" name="special_price[<?= h((string) $product['id']) ?>]" placeholder="سعر خاص">
|
|
<div class="text-muted small mt-1">الافتراضي: <?= h(format_money((float) $product['sale_price'])) ?></div>
|
|
</div>
|
|
</label>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</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">حفظ العميل</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<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">Customer matrix</span>
|
|
<h2 class="section-title mb-0">مصفوفة العملاء الحالية</h2>
|
|
</div>
|
|
<span class="badge text-bg-light border text-dark">الإجمالي: <?= h((string) count($customers)) ?></span>
|
|
</div>
|
|
<div class="row g-3">
|
|
<?php foreach ($customers as $customer): ?>
|
|
<div class="col-12">
|
|
<div class="customer-list-card">
|
|
<div class="d-flex justify-content-between align-items-start gap-3 flex-wrap mb-3">
|
|
<div>
|
|
<h3 class="section-title small-title mb-1"><?= h($customer['name']) ?></h3>
|
|
<div class="text-muted small"><?= h($customer['branch_name']) ?> · <span dir="ltr"><?= h($customer['phone'] ?: '—') ?></span></div>
|
|
</div>
|
|
<span class="status-badge success">نشط</span>
|
|
</div>
|
|
<div class="mini-stat mb-3">
|
|
<span>الأصناف المسموح بها</span>
|
|
<strong><?= h((string) count($customer['catalog'])) ?></strong>
|
|
</div>
|
|
<div class="price-list compact-list">
|
|
<?php foreach ($customer['catalog'] as $item): ?>
|
|
<div class="price-item">
|
|
<div>
|
|
<div class="fw-semibold"><?= h($item['name']) ?></div>
|
|
<div class="text-muted small"><?= h($item['sku']) ?> · <?= h($item['unit']) ?></div>
|
|
</div>
|
|
<div class="fw-semibold"><?= h(format_money((float) $item['special_price'])) ?></div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<?php render_footer(); ?>
|