206 lines
8.2 KiB
PHP
206 lines
8.2 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
require_once __DIR__ . '/app.php';
|
|
require_permission('customers');
|
|
|
|
$errors = [];
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
verify_csrf();
|
|
|
|
$name = trim((string)($_POST['name'] ?? ''));
|
|
$phone = trim((string)($_POST['phone'] ?? ''));
|
|
$email = trim((string)($_POST['email'] ?? ''));
|
|
$branchesRaw = trim((string)($_POST['branches'] ?? ''));
|
|
$allowedRaw = trim((string)($_POST['allowed_skus'] ?? ''));
|
|
$pricingRaw = trim((string)($_POST['price_overrides'] ?? ''));
|
|
$notes = trim((string)($_POST['notes'] ?? ''));
|
|
|
|
if ($name === '') {
|
|
$errors[] = 'اسم العميل مطلوب.';
|
|
}
|
|
|
|
$branches = array_values(array_filter(array_map('trim', explode(',', $branchesRaw))));
|
|
if (!$branches) {
|
|
$errors[] = 'أدخل فرعًا واحدًا على الأقل.';
|
|
}
|
|
|
|
$allowedSkus = array_values(array_filter(array_map('trim', explode(',', $allowedRaw))));
|
|
$priceOverrides = [];
|
|
if ($pricingRaw !== '') {
|
|
foreach (preg_split('/\r\n|\r|\n/', $pricingRaw) as $line) {
|
|
$line = trim($line);
|
|
if ($line === '') {
|
|
continue;
|
|
}
|
|
[$sku, $price] = array_pad(array_map('trim', explode(':', $line, 2)), 2, '');
|
|
if ($sku !== '' && is_numeric($price)) {
|
|
$priceOverrides[$sku] = (float)$price;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$errors) {
|
|
create_record('customer', $name, next_code('CUS', 'customer'), [
|
|
'phone' => $phone,
|
|
'email' => $email,
|
|
'branches' => $branches,
|
|
'allowed_skus' => $allowedSkus,
|
|
'price_overrides' => $priceOverrides,
|
|
'notes' => $notes,
|
|
]);
|
|
set_flash('success', 'تمت إضافة العميل بنجاح.');
|
|
redirect('customers.php');
|
|
}
|
|
}
|
|
|
|
$customers = fetch_records('customer');
|
|
$detail = isset($_GET['id']) ? fetch_record('customer', (int)$_GET['id']) : null;
|
|
render_header('إدارة العملاء', 'تعريف العملاء وفروعهم وأسعارهم الخاصة والأصناف المسموح بها.', 'customers');
|
|
?>
|
|
<div class="row g-4">
|
|
<div class="col-lg-5">
|
|
<div class="panel-card">
|
|
<div class="section-header compact">
|
|
<div>
|
|
<h1 class="section-title mb-1">إضافة عميل</h1>
|
|
<p class="section-copy">عرّف الفروع والأسعار الخاصة لتظهر تلقائيًا عند إنشاء أمر البيع.</p>
|
|
</div>
|
|
</div>
|
|
<?php if ($errors): ?>
|
|
<div class="alert alert-danger py-2">
|
|
<?php foreach ($errors as $error): ?>
|
|
<div><?= e($error) ?></div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
<form method="post" class="vstack gap-3">
|
|
<input type="hidden" name="csrf_token" value="<?= e(csrf_token()) ?>">
|
|
<div>
|
|
<label class="form-label">اسم العميل</label>
|
|
<input type="text" class="form-control" name="name" required>
|
|
</div>
|
|
<div class="row g-3">
|
|
<div class="col-md-6">
|
|
<label class="form-label">الهاتف</label>
|
|
<input type="text" class="form-control" name="phone">
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label">البريد الإلكتروني</label>
|
|
<input type="email" class="form-control" name="email">
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<label class="form-label">الفروع</label>
|
|
<input type="text" class="form-control" name="branches" placeholder="الرياض, جدة" required>
|
|
<div class="form-text">افصل الفروع بفاصلة.</div>
|
|
</div>
|
|
<div>
|
|
<label class="form-label">الأصناف المسموح بها</label>
|
|
<input type="text" class="form-control" name="allowed_skus" placeholder="P-100, P-200">
|
|
</div>
|
|
<div>
|
|
<label class="form-label">الأسعار الخاصة</label>
|
|
<textarea class="form-control" name="price_overrides" rows="4" placeholder="P-100:95 P-200:145"></textarea>
|
|
<div class="form-text">كل سطر بصيغة SKU:PRICE.</div>
|
|
</div>
|
|
<div>
|
|
<label class="form-label">ملاحظات</label>
|
|
<textarea class="form-control" name="notes" rows="3"></textarea>
|
|
</div>
|
|
<button class="btn btn-dark" type="submit">حفظ العميل</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-7">
|
|
<div class="panel-card mb-4">
|
|
<div class="section-header">
|
|
<div>
|
|
<h2 class="section-title">سجل العملاء</h2>
|
|
<p class="section-copy">اختر عميلًا لعرض الفروع والأسعار الخاصة والأصناف المتاحة له.</p>
|
|
</div>
|
|
</div>
|
|
<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 ($customers as $customer): $payload = $customer['payload_data']; ?>
|
|
<tr>
|
|
<td>
|
|
<div class="fw-semibold"><?= e($customer['title']) ?></div>
|
|
<div class="small text-secondary"><?= e($customer['code']) ?></div>
|
|
</td>
|
|
<td><?= e(implode('، ', $payload['branches'] ?? [])) ?></td>
|
|
<td><?= e(implode('، ', $payload['allowed_skus'] ?? [])) ?></td>
|
|
<td><a class="btn btn-sm btn-outline-secondary" href="customers.php?id=<?= (int)$customer['id'] ?>">عرض</a></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel-card">
|
|
<div class="section-header compact">
|
|
<div>
|
|
<h2 class="section-title">تفاصيل العميل</h2>
|
|
</div>
|
|
</div>
|
|
<?php if ($detail): $payload = $detail['payload_data']; ?>
|
|
<div class="detail-grid">
|
|
<div class="detail-block">
|
|
<span class="detail-label">اسم العميل</span>
|
|
<strong><?= e($detail['title']) ?></strong>
|
|
</div>
|
|
<div class="detail-block">
|
|
<span class="detail-label">رقم العميل</span>
|
|
<strong><?= e($detail['code']) ?></strong>
|
|
</div>
|
|
<div class="detail-block">
|
|
<span class="detail-label">بيانات التواصل</span>
|
|
<strong><?= e(($payload['phone'] ?? '—') . ' / ' . ($payload['email'] ?? '—')) ?></strong>
|
|
</div>
|
|
<div class="detail-block">
|
|
<span class="detail-label">الفروع</span>
|
|
<strong><?= e(implode('، ', $payload['branches'] ?? [])) ?></strong>
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<div class="row g-3">
|
|
<div class="col-md-6">
|
|
<div class="subtle-card h-100">
|
|
<div class="detail-label mb-2">الأصناف المسموح بها</div>
|
|
<div><?= e(implode('، ', $payload['allowed_skus'] ?? [])) ?: '—' ?></div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="subtle-card h-100">
|
|
<div class="detail-label mb-2">الأسعار الخاصة</div>
|
|
<?php if (!empty($payload['price_overrides'])): ?>
|
|
<?php foreach ($payload['price_overrides'] as $sku => $price): ?>
|
|
<div class="d-flex justify-content-between border-bottom py-1 small">
|
|
<span><?= e((string)$sku) ?></span>
|
|
<span><?= e(format_money((float)$price)) ?></span>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<div>لا توجد أسعار خاصة.</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mt-3 text-secondary small"><?= e($payload['notes'] ?? '') ?></div>
|
|
<?php else: ?>
|
|
<div class="empty-inline">اختر عميلًا من الجدول لعرض التفاصيل.</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php render_footer(); ?>
|