39728-vm/eid_print.php
2026-04-23 17:10:16 +00:00

249 lines
10 KiB
PHP

<?php
require_once __DIR__ . '/includes/app.php';
$user = require_permission('eid_orders', 'show');
ensure_sales_table();
$activeNav = 'eid_orders';
$pageTitle = tr('طباعة تجهيزات العيد', 'Print Eid Prep Summary');
$metaDescription = tr('ملخص قابل للطباعة لتجهيزات طلبات العيد حسب التاريخ والفرع والحالة.', 'Printable Eid preparation summary by date, branch, and status.');
$metaRobots = 'noindex, nofollow';
$mode = isset($_GET['mode']) && in_array($_GET['mode'], ['pos', 'normal'], true) ? $_GET['mode'] : null;
$branch = isset($_GET['branch']) && array_key_exists($_GET['branch'], branches()) ? $_GET['branch'] : null;
$search = trim((string) ($_GET['q'] ?? ''));
$paymentStatus = trim((string) ($_GET['payment_status'] ?? ''));
$deliveryStatus = trim((string) ($_GET['delivery_status'] ?? ''));
$dateFrom = trim((string) ($_GET['date_from'] ?? ''));
$dateTo = trim((string) ($_GET['date_to'] ?? ''));
$allowedBranches = $user && $user['role'] !== 'owner' ? get_user_branches($user) : [];
$deliveryOptions = eid_delivery_status_options();
$dbError = null;
$orders = [];
$itemRows = [];
$summary = [
'total_orders' => 0,
'unique_items' => 0,
'total_quantity' => 0,
'total_amount' => 0,
];
try {
$params = [':order_type' => 'eid'];
$where = ' WHERE order_type = :order_type ';
if ($mode) {
$where .= ' AND sale_mode = :sale_mode ';
$params[':sale_mode'] = $mode;
}
if ($branch) {
$where .= ' AND branch_code = :branch_code ';
$params[':branch_code'] = $branch;
}
if ($user && $user['role'] !== 'owner') {
if ($allowedBranches === []) {
$where .= ' AND 1=0 ';
} else {
$namedParams = [];
foreach ($allowedBranches as $i => $allowedBranch) {
$key = ':v_branch_' . $i;
$namedParams[] = $key;
$params[$key] = $allowedBranch;
}
$where .= ' AND branch_code IN (' . implode(', ', $namedParams) . ') ';
}
}
if ($search !== '') {
$where .= ' AND (receipt_no LIKE :search OR customer_name LIKE :search OR cashier_name LIKE :search OR notes LIKE :search) ';
$params[':search'] = '%' . $search . '%';
}
if (in_array($paymentStatus, ['paid', 'partial', 'unpaid'], true)) {
$where .= ' AND payment_status = :payment_status ';
$params[':payment_status'] = $paymentStatus;
}
if (isset($deliveryOptions[$deliveryStatus])) {
$where .= ' AND delivery_status = :delivery_status ';
$params[':delivery_status'] = $deliveryStatus;
}
if ($dateFrom !== '' && preg_match('/^\d{4}-\d{2}-\d{2}$/', $dateFrom)) {
$where .= ' AND DATE(COALESCE(delivery_date, sale_date)) >= :date_from ';
$params[':date_from'] = $dateFrom;
} else {
$dateFrom = '';
}
if ($dateTo !== '' && preg_match('/^\d{4}-\d{2}-\d{2}$/', $dateTo)) {
$where .= ' AND DATE(COALESCE(delivery_date, sale_date)) <= :date_to ';
$params[':date_to'] = $dateTo;
} else {
$dateTo = '';
}
$sql = 'SELECT * FROM sales_orders' . $where . ' ORDER BY COALESCE(delivery_date, DATE(sale_date)) ASC, sale_date ASC';
$stmt = db()->prepare($sql);
foreach ($params as $key => $value) {
$stmt->bindValue($key, $value);
}
$stmt->execute();
$orders = $stmt->fetchAll();
$itemIndex = [];
foreach ($orders as &$order) {
$decodedItems = json_decode((string) ($order['items_json'] ?? '[]'), true);
$items = is_array($decodedItems) ? $decodedItems : [];
$order['items'] = $items;
foreach ($items as $item) {
$sku = trim((string) ($item['sku'] ?? ''));
$name = trim((string) ($item['name_ar'] ?? ''));
if ($name === '') {
$name = trim((string) ($item['name_en'] ?? ''));
}
if ($name === '') {
$name = $sku !== '' ? $sku : tr('صنف بدون اسم', 'Unnamed item');
}
$key = $sku !== '' ? $sku : md5($name);
$qty = max(0, (float) ($item['qty'] ?? 0));
if (!isset($itemIndex[$key])) {
$itemIndex[$key] = [
'sku' => $sku,
'name' => $name,
'qty' => 0.0,
'order_count' => 0,
];
}
$itemIndex[$key]['qty'] += $qty;
$itemIndex[$key]['order_count']++;
}
}
unset($order);
usort($orders, static function (array $a, array $b): int {
$aDate = (string) ($a['delivery_date'] ?: substr((string) ($a['sale_date'] ?? ''), 0, 10));
$bDate = (string) ($b['delivery_date'] ?: substr((string) ($b['sale_date'] ?? ''), 0, 10));
return [$aDate, (string) ($a['receipt_no'] ?? '')] <=> [$bDate, (string) ($b['receipt_no'] ?? '')];
});
$itemRows = array_values($itemIndex);
usort($itemRows, static function (array $a, array $b): int {
if ($a['qty'] === $b['qty']) {
return strcasecmp((string) $a['name'], (string) $b['name']);
}
return $b['qty'] <=> $a['qty'];
});
$summary['total_orders'] = count($orders);
$summary['unique_items'] = count($itemRows);
$summary['total_quantity'] = array_sum(array_map(static fn(array $row): float => (float) $row['qty'], $itemRows));
$summary['total_amount'] = array_sum(array_map(static fn(array $row): float => (float) ($row['total_amount'] ?? 0), $orders));
} catch (Throwable $e) {
$dbError = $e->getMessage();
}
$filterParams = array_filter([
'q' => $search,
'branch' => $branch,
'mode' => $mode,
'payment_status' => $paymentStatus,
'delivery_status' => $deliveryStatus,
'date_from' => $dateFrom,
'date_to' => $dateTo,
], static fn($value) => $value !== null && $value !== '');
$generatedAt = date('Y-m-d H:i');
require __DIR__ . '/includes/header.php';
?>
<style>
.eid-print-shell { max-width: 1180px; margin: 0 auto; }
.eid-print-card {
background: #fff;
border: 1px solid #e8ecf4;
border-radius: 16px;
box-shadow: 0 12px 40px rgba(15, 23, 42, 0.06);
}
.eid-print-card .table th { white-space: nowrap; }
@media print {
@page {
size: portrait;
margin: 1cm;
}
body { background: #fff !important; color: #000 !important; font-size: 12pt !important; }
.main-sidebar, .main-header, .footer-section, footer, .d-print-none, .alert-dismissible .btn-close { display: none !important; }
.main-content { margin: 0 !important; padding: 0 !important; }
.eid-print-shell { max-width: 100% !important; margin: 0 !important; padding: 0 !important; }
.eid-print-card { box-shadow: none !important; border: none !important; padding: 0 !important; margin: 0 !important; border-radius: 0 !important; }
.table { width: 100% !important; border-collapse: collapse !important; }
.table th, .table td {
border: 1px solid #000 !important;
padding: 6px !important;
color: #000 !important;
}
.table th { background: transparent !important; }
}
</style>
<div class="eid-print-shell py-4">
<section class="eid-print-card p-4 p-lg-5 mb-4">
<div class="d-flex justify-content-between align-items-start gap-3 flex-wrap mb-4 d-print-none">
<div>
<h1 class="h3 mb-1"><i class="bi bi-printer me-2"></i><?= h(tr("ملخص تجهيزات طلبات العيد", "Eid Order Prep Summary")) ?></h1>
<p class="text-muted mb-0"><?= h(tr("تقرير قابل للطباعة يوضح الأصناف المطلوبة وعدد الطلبات التي تحتوي كل صنف.", "Printable report showing required items and how many orders contain each item.")) ?></p>
</div>
<div class="d-flex gap-2 flex-wrap">
<a class="btn btn-outline-secondary" href="<?= h(url_for("eid_orders.php", $filterParams)) ?>"><i class="bi bi-arrow-<?= current_lang() === "ar" ? "right" : "left" ?> me-1"></i><?= h(tr("رجوع لطلبات العيد", "Back to Eid Orders")) ?></a>
<button type="button" class="btn btn-dark" onclick="window.print()"><i class="bi bi-printer me-1"></i><?= h(tr("طباعة", "Print")) ?></button>
</div>
</div>
<div class="text-center mb-4">
<h2 class="h4 mb-1"><?= h(tr("ملخص تجهيزات طلبات العيد", "Eid Order Prep Summary")) ?></h2>
<div class="text-muted"><?= h(tr("تاريخ الطباعة", "Printed at")) ?>: <?= h($generatedAt) ?></div>
<?php if ($dateFrom !== "" || $dateTo !== ""): ?>
<div class="text-muted mt-1"><?= h(tr("الفترة", "Period")) ?>: <?= h($dateFrom !== "" ? $dateFrom : "…") ?> &rarr; <?= h($dateTo !== "" ? $dateTo : "…") ?></div>
<?php endif; ?>
</div>
<?php if ($dbError): ?>
<div class="alert alert-danger"><?= h($dbError) ?></div>
<?php else: ?>
<?php if ($itemRows === []): ?>
<div class="alert alert-secondary text-center"><?= h(tr("لا توجد بيانات للطباعة.", "No data to print.")) ?></div>
<?php else: ?>
<div class="table-responsive">
<table class="table table-bordered align-middle text-center">
<thead >
<tr>
<th style="width: 60px;">#</th>
<th style="text-align: right !important;"><?= h(tr("الصنف", "Item")) ?></th>
<th style="width: 150px;"><?= h(tr("عدد الطلبات", "Orders count")) ?></th>
<th style="width: 150px;"><?= h(tr("الكمية المطلوبة", "Quantity wanted")) ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($itemRows as $index => $row): ?>
<tr>
<td><?= $index + 1 ?></td>
<td class="fw-bold" style="text-align: right !important;"><?= h($row["name"]) ?></td>
<td><?= (int) $row["order_count"] ?></td>
<td class="fw-bold"><?= h(rtrim(rtrim(number_format((float) $row["qty"], 3, ".", ""), "0"), ".")) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
<?php endif; ?>
</section>
</div>
<?php require __DIR__ . "/includes/footer.php"; ?>