38929-vm/customer_statement.php
2026-03-03 13:15:17 +00:00

195 lines
13 KiB
PHP

<?php
$title = 'customer_statement';
require_once __DIR__ . '/includes/header.php';
$customer_id = $_GET['id'] ?? null;
if (!$customer_id) { header('Location: customers.php'); exit; }
$stmt = db()->prepare("SELECT * FROM customers WHERE id = ?");
$stmt->execute([$customer_id]);
$customer = $stmt->fetch();
if (!$customer) { header('Location: customers.php'); exit; }
$from_date = $_GET['from_date'] ?? '';
$to_date = $_GET['to_date'] ?? '';
$active_tab = $_GET['tab'] ?? 'financial';
// Financial Logic
$orders_sql = "SELECT id, order_number, total_price, created_at FROM orders WHERE customer_id = ?";
$payments_sql = "SELECT p.id, p.amount, p.payment_method, p.created_at, o.order_number FROM payments p JOIN orders o ON p.order_id = o.id WHERE o.customer_id = ?";
if ($from_date) { $orders_sql .= " AND DATE(created_at) >= ?"; $payments_sql .= " AND DATE(p.created_at) >= ?"; }
if ($to_date) { $orders_sql .= " AND DATE(created_at) <= ?"; $payments_sql .= " AND DATE(p.created_at) <= ?"; }
$stmt_orders = db()->prepare($orders_sql);
$orders_params = [$customer_id];
if ($from_date) $orders_params[] = $from_date;
if ($to_date) $orders_params[] = $to_date;
$stmt_orders->execute($orders_params);
$orders = $stmt_orders->fetchAll();
$stmt_payments = db()->prepare($payments_sql);
$payments_params = [$customer_id];
if ($from_date) $payments_params[] = $from_date;
if ($to_date) $payments_params[] = $to_date;
$stmt_payments->execute($payments_params);
$payments = $stmt_payments->fetchAll();
$transactions = [];
foreach ($orders as $o) { $transactions[] = ['date' => $o['created_at'], 'type' => 'order', 'ref' => $o['order_number'], 'debit' => $o['total_price'], 'credit' => 0, 'description' => __('order') . ' #' . $o['order_number']]; }
foreach ($payments as $p) { $transactions[] = ['date' => $p['created_at'], 'type' => 'payment', 'ref' => $p['order_number'], 'debit' => 0, 'credit' => $p['amount'], 'description' => __('payment') . ' (' . __($p['payment_method']) . ') - ' . __('order') . ' #' . $p['order_number']]; }
usort($transactions, function($a, $b) { return strtotime($a['date']) - strtotime($b['date']); });
$total_debit = 0; $total_credit = 0; $balance = 0;
foreach ($transactions as &$t) { $total_debit += $t['debit']; $total_credit += $t['credit']; $balance += ($t['debit'] - $t['credit']); $t['running_balance'] = $balance; }
// Loyalty Logic
$loyalty_sql = "SELECT lt.*, o.order_number FROM loyalty_transactions lt LEFT JOIN orders o ON lt.order_id = o.id WHERE lt.customer_id = ?";
if ($from_date) $loyalty_sql .= " AND DATE(lt.created_at) >= ?";
if ($to_date) $loyalty_sql .= " AND DATE(lt.created_at) <= ?";
$loyalty_sql .= " ORDER BY lt.created_at ASC";
$stmt_loyalty = db()->prepare($loyalty_sql);
$loyalty_params = [$customer_id];
if ($from_date) $loyalty_params[] = $from_date;
if ($to_date) $loyalty_params[] = $to_date;
$stmt_loyalty->execute($loyalty_params);
$loyalty_transactions = $stmt_loyalty->fetchAll();
$loyalty_balance = 0;
foreach ($loyalty_transactions as &$lt) {
$loyalty_balance += $lt['points'];
$lt['running_balance'] = $loyalty_balance;
}
$display_company_name = ($lang === 'ar' ? ($company_info['name_ar'] ?: $company_info['name_en']) : $company_info['name_en']) ?: 'Laundry Brand';
$display_address = ($lang === 'ar' ? ($company_info['address_ar'] ?: $company_info['address_en']) : $company_info['address_en']);
?>
<div class="d-print-none mb-4">
<nav aria-label="breadcrumb">
<ol class="breadcrumb"><li class="breadcrumb-item"><a href="customers.php"><?= __('customers') ?></a></li><li class="breadcrumb-item active"><?= __('customer_statement') ?></li></ol>
</nav>
</div>
<div class="card p-4 border-0 shadow-sm mb-4 d-print-none rounded-4">
<form action="" method="GET" class="row g-3 align-items-end">
<input type="hidden" name="id" value="<?= $customer_id ?>">
<input type="hidden" name="tab" value="<?= $active_tab ?>">
<div class="col-md-4"><label class="form-label small fw-bold"><?= __('from_date') ?></label><input type="date" name="from_date" class="form-control rounded-3" value="<?= $from_date ?>"></div>
<div class="col-md-4"><label class="form-label small fw-bold"><?= __('to_date') ?></label><input type="date" name="to_date" class="form-control rounded-3" value="<?= $to_date ?>"></div>
<div class="col-md-4 d-flex gap-2">
<button type="submit" class="btn btn-primary px-4 w-100 rounded-3"><i class="bi bi-filter me-1"></i> <?= __('filter') ?></button>
<button type="button" class="btn btn-outline-dark px-4 w-100 rounded-3" onclick="window.print()"><i class="bi bi-printer me-1"></i> <?= __('print') ?></button>
</div>
</form>
</div>
<!-- Tabs -->
<ul class="nav nav-tabs d-print-none mb-4 border-0 gap-2">
<li class="nav-item">
<a class="nav-link rounded-3 fw-bold <?= $active_tab === 'financial' ? 'active bg-primary text-white border-primary' : 'bg-white text-muted border' ?>" href="?id=<?= $customer_id ?>&tab=financial&from_date=<?= $from_date ?>&to_date=<?= $to_date ?>">
<i class="bi bi-cash-stack me-2"></i><?= __('financial_statement') ?? 'Financial Statement' ?>
</a>
</li>
<li class="nav-item">
<a class="nav-link rounded-3 fw-bold <?= $active_tab === 'loyalty' ? 'active bg-primary text-white border-primary' : 'bg-white text-muted border' ?>" href="?id=<?= $customer_id ?>&tab=loyalty&from_date=<?= $from_date ?>&to_date=<?= $to_date ?>">
<i class="bi bi-star-fill me-2"></i><?= __('loyalty_statement') ?? 'Loyalty Statement' ?>
</a>
</li>
</ul>
<div id="printableStatement" class="card p-4 p-md-5 border-0 shadow-sm rounded-4">
<!-- Formal Header -->
<div class="d-none d-print-block mb-5">
<div class="row align-items-center mb-4">
<div class="col-7">
<?php if (!empty($company_info['logo'])): ?><img src="<?= $company_info['logo'] ?>" alt="Logo" style="max-height: 100px;" class="mb-3"><?php endif; ?>
<h2 class="fw-bold mb-1"><?= htmlspecialchars($display_company_name) ?></h2>
<div class="text-muted small"><?= htmlspecialchars($display_address) ?><br><?= __('phone') ?>: <?= htmlspecialchars($company_info['phone']) ?></div>
</div>
<div class="col-5 text-end">
<h1 class="fw-bold text-uppercase mb-2 text-primary"><?= $active_tab === 'loyalty' ? (__('loyalty_statement') ?? 'Loyalty Statement') : __('statement') ?></h1>
<div class="mt-3 small">
<p class="mb-0 fw-bold"><?= __('date') ?>: <?= date('d/m/Y') ?></p>
<?php if ($from_date || $to_date): ?><p class="mb-0 text-muted mt-1"><?= $from_date ? __('from_date').': '.date('d/m/Y',strtotime($from_date)) : '' ?> <?= $to_date ? __('to_date').': '.date('d/m/Y',strtotime($to_date)) : '' ?></p><?php endif; ?>
</div>
</div>
</div>
<div class="row p-3 bg-light rounded-3 mb-4 mx-0 border">
<div class="col-12"><h6 class="fw-bold text-muted text-uppercase mb-2 small"><?= __('customer_details') ?></h6><h4 class="fw-bold mb-1"><?= $lang === 'ar' ? ($customer['name_ar'] ?: $customer['name_en']) : $customer['name_en'] ?></h4><p class="mb-0 text-muted small"><?= $customer['phone'] ?> <?= $customer['email'] ? ' | '.$customer['email'] : '' ?></p></div>
</div>
</div>
<!-- Screen Header -->
<div class="d-print-none mb-4">
<h4 class="fw-bold mb-1"><?= $lang === 'ar' ? ($customer['name_ar'] ?: $customer['name_en']) : $customer['name_en'] ?></h4>
<p class="text-muted mb-0"><?= $customer['phone'] ?> <?= $customer['email'] ? ' | '.$customer['email'] : '' ?></p>
</div>
<?php if ($active_tab === 'financial'): ?>
<div class="table-responsive">
<table class="table table-striped align-middle mt-2">
<thead class="table-dark">
<tr><th><?= __('date') ?></th><th><?= __('description') ?></th><th class="text-center"><?= __('ref') ?></th><th class="text-end"><?= __('debit') ?></th><th class="text-end"><?= __('credit') ?></th><th class="text-end"><?= __('balance') ?></th></tr>
</thead>
<tbody>
<?php if (empty($transactions)): ?><tr><td colspan="6" class="text-center py-5 text-muted"><?= __('no_transactions_found') ?></td></tr>
<?php else: foreach ($transactions as $t): ?>
<tr><td class="small"><?= date('d/m/Y H:i', strtotime($t['date'])) ?></td><td><?= $t['description'] ?></td><td class="text-center"><span class="badge bg-light text-dark border"><?= $t['ref'] ?></span></td><td class="text-end"><?= $t['debit'] > 0 ? format_amount($t['debit']) : '-' ?></td><td class="text-end"><?= $t['credit'] > 0 ? format_amount($t['credit']) : '-' ?></td><td class="text-end fw-bold"><?= format_amount($t['running_balance']) ?></td></tr>
<?php endforeach; endif; ?>
</tbody>
<tfoot class="table-light fw-bold"><tr><td colspan="3" class="text-end"><?= __('total') ?></td><td class="text-end"><?= format_amount($total_debit) ?></td><td class="text-end"><?= format_amount($total_credit) ?></td><td class="text-end text-primary"><?= format_amount($balance) ?></td></tr></tfoot>
</table>
</div>
<?php else: ?>
<div class="table-responsive">
<table class="table table-striped align-middle mt-2">
<thead class="table-dark">
<tr><th><?= __('date') ?></th><th><?= __('description') ?></th><th class="text-center"><?= __('ref') ?></th><th class="text-end"><?= __('earned') ?? 'Earned' ?></th><th class="text-end"><?= __('redeemed') ?? 'Redeemed' ?></th><th class="text-end"><?= __('balance') ?></th></tr>
</thead>
<tbody>
<?php if (empty($loyalty_transactions)): ?><tr><td colspan="6" class="text-center py-5 text-muted"><?= __('no_transactions_found') ?></td></tr>
<?php else: foreach ($loyalty_transactions as $lt): ?>
<tr>
<td class="small"><?= date('d/m/Y H:i', strtotime($lt['created_at'])) ?></td>
<td><?= $lt['description'] ?> <span class="badge bg-soft-primary text-primary small ms-2"><?= __($lt['type']) ?></span></td>
<td class="text-center"><?= $lt['order_number'] ? '<span class="badge bg-light text-dark border">'.$lt['order_number'].'</span>' : '-' ?></td>
<td class="text-end text-success"><?= $lt['points'] > 0 ? '+'.number_format($lt['points'], 2) : '-' ?></td>
<td class="text-end text-danger"><?= $lt['points'] < 0 ? number_format($lt['points'], 2) : '-' ?></td>
<td class="text-end fw-bold"><?= number_format($lt['running_balance'], 2) ?></td>
</tr>
<?php endforeach; endif; ?>
</tbody>
<tfoot class="table-light fw-bold"><tr><td colspan="5" class="text-end"><?= __('current_balance') ?? 'Current Balance' ?></td><td class="text-end text-primary"><?= number_format($customer['loyalty_points'], 2) ?></td></tr></tfoot>
</table>
</div>
<?php endif; ?>
<!-- Summary Box -->
<div class="row mt-5 d-print-none">
<div class="col-md-5 ms-auto">
<div class="card bg-light border-0 p-4 rounded-4">
<h6 class="fw-bold mb-3 text-muted text-uppercase small"><?= __('summary') ?></h6>
<?php if ($active_tab === 'financial'): ?>
<div class="d-flex justify-content-between mb-2"><span><?= __('total_debit') ?>:</span><span class="fw-bold"><?= format_amount($total_debit) ?></span></div>
<div class="d-flex justify-content-between mb-2"><span><?= __('total_credit') ?>:</span><span class="fw-bold"><?= format_amount($total_credit) ?></span></div>
<div class="d-flex justify-content-between pt-2 mt-2 border-top"><span class="fw-bold"><?= __('closing_balance') ?>:</span><span class="fw-bold text-primary"><?= format_amount($balance) ?></span></div>
<?php else: ?>
<div class="d-flex justify-content-between pt-2 mt-2 border-top"><span class="fw-bold"><?= __('loyalty_points') ?>:</span><span class="fw-bold text-primary fs-4"><?= number_format($customer['loyalty_points'], 2) ?></span></div>
<?php endif; ?>
</div>
</div>
</div>
</div>
<style>
.bg-soft-primary { background-color: rgba(13, 110, 253, 0.1); }
@media print {
body { background-color: white !important; font-size: 10px; }
.main-content { padding: 0 !important; margin: 0 !important; }
header, .sidebar, .d-print-none, .breadcrumb, nav { display: none !important; }
.container-fluid, .row, .col-lg-10 { padding: 0 !important; margin: 0 !important; width: 100% !important; max-width: 100% !important; flex: 0 0 100% !important; }
.card { box-shadow: none !important; border: none !important; padding: 0 !important; }
}
</style>
<?php require_once __DIR__ . '/includes/footer.php'; ?>