328 lines
11 KiB
PHP
328 lines
11 KiB
PHP
<?php
|
|
require_once __DIR__ . '/db/config.php';
|
|
require_once __DIR__ . '/includes/lang.php';
|
|
|
|
$order_id = $_GET['id'] ?? null;
|
|
if (!$order_id) {
|
|
die("Order ID is required");
|
|
}
|
|
|
|
// Fetch Global Company Info
|
|
$stmt = db()->query("SELECT * FROM companies LIMIT 1");
|
|
$company = $stmt->fetch();
|
|
|
|
// Fetch Order Details with Customer and Branch info
|
|
$stmt = db()->prepare("SELECT o.*,
|
|
c.name_en as customer_name_en, c.name_ar as customer_name_ar, c.phone as customer_phone,
|
|
b.name_en as branch_name_en, b.name_ar as branch_name_ar, b.address_en as branch_address_en, b.address_ar as branch_address_ar, b.phone as branch_phone
|
|
FROM orders o
|
|
LEFT JOIN customers c ON o.customer_id = c.id
|
|
JOIN branches b ON o.branch_id = b.id
|
|
WHERE o.id = ?");
|
|
$stmt->execute([$order_id]);
|
|
$order = $stmt->fetch();
|
|
|
|
if (!$order) {
|
|
die("Order not found");
|
|
}
|
|
|
|
// Fetch Order Items
|
|
$stmt = db()->prepare("SELECT oi.*, i.name_en as item_en, i.name_ar as item_ar,
|
|
s.name_en as service_en, s.name_ar as service_ar
|
|
FROM order_items oi
|
|
JOIN items i ON oi.item_id = i.id
|
|
JOIN services s ON oi.service_id = s.id
|
|
WHERE oi.order_id = ?");
|
|
$stmt->execute([$order_id]);
|
|
$order_items = $stmt->fetchAll();
|
|
|
|
// Fetch Payments
|
|
$stmt = db()->prepare("SELECT SUM(amount) as total_paid FROM payments WHERE order_id = ?");
|
|
$stmt->execute([$order_id]);
|
|
$total_paid = $stmt->fetch()['total_paid'] ?? 0;
|
|
$remaining = $order['total_price'] - $total_paid;
|
|
|
|
// Bilingual Helper for Labels
|
|
function b_label($key) {
|
|
global $translations;
|
|
$en = $translations['en'][$key] ?? $key;
|
|
$ar = $translations['ar'][$key] ?? $key;
|
|
return '<span class="label-en">' . $en . '</span> / <span class="label-ar">' . $ar . '</span>';
|
|
}
|
|
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en" dir="ltr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Receipt #<?= $order['order_number'] ?></title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;700&family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
|
<style>
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
body {
|
|
font-family: 'Inter', 'Cairo', sans-serif;
|
|
font-size: 12px;
|
|
line-height: 1.4;
|
|
color: #000;
|
|
background-color: #fff;
|
|
width: 80mm;
|
|
padding: 5mm;
|
|
margin: 0 auto;
|
|
}
|
|
.text-center { text-align: center; }
|
|
.text-end { text-align: right; }
|
|
.text-start { text-align: left; }
|
|
.fw-bold { font-weight: bold; }
|
|
.mb-1 { margin-bottom: 2mm; }
|
|
.mb-2 { margin-bottom: 4mm; }
|
|
.mt-2 { margin-top: 4mm; }
|
|
|
|
.logo {
|
|
max-width: 50mm;
|
|
max-height: 30mm;
|
|
margin-bottom: 3mm;
|
|
}
|
|
|
|
.receipt-header {
|
|
border-bottom: 1px dashed #000;
|
|
padding-bottom: 3mm;
|
|
margin-bottom: 3mm;
|
|
}
|
|
|
|
.info-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-bottom: 1.5mm;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.info-label {
|
|
font-size: 10px;
|
|
flex-shrink: 0;
|
|
margin-right: 2mm;
|
|
}
|
|
|
|
.info-value {
|
|
text-align: right;
|
|
word-break: break-all;
|
|
}
|
|
|
|
.label-en { font-size: 10px; }
|
|
.label-ar { font-size: 11px; font-family: 'Cairo', sans-serif; }
|
|
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin-bottom: 3mm;
|
|
}
|
|
|
|
th {
|
|
text-align: inherit;
|
|
border-bottom: 1px solid #000;
|
|
padding: 1mm 0;
|
|
font-size: 10px;
|
|
}
|
|
|
|
td {
|
|
padding: 2mm 0;
|
|
vertical-align: top;
|
|
border-bottom: 0.1mm solid #eee;
|
|
}
|
|
|
|
.item-name-ar {
|
|
font-family: 'Cairo', sans-serif;
|
|
font-size: 11px;
|
|
display: block;
|
|
margin-top: 0.5mm;
|
|
}
|
|
|
|
.item-service {
|
|
font-size: 9px;
|
|
color: #555;
|
|
display: block;
|
|
}
|
|
|
|
.totals {
|
|
border-top: 1px dashed #000;
|
|
padding-top: 2mm;
|
|
}
|
|
|
|
.total-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-bottom: 1mm;
|
|
align-items: center;
|
|
}
|
|
|
|
.grand-total {
|
|
font-size: 14px;
|
|
border-top: 1px solid #000;
|
|
padding-top: 1mm;
|
|
margin-top: 1mm;
|
|
}
|
|
|
|
.footer {
|
|
margin-top: 5mm;
|
|
border-top: 1px dashed #000;
|
|
padding-top: 3mm;
|
|
font-size: 10px;
|
|
}
|
|
|
|
.arabic-text {
|
|
font-family: 'Cairo', sans-serif;
|
|
direction: rtl;
|
|
}
|
|
|
|
@media print {
|
|
body {
|
|
width: 80mm;
|
|
margin: 0;
|
|
padding: 3mm;
|
|
}
|
|
.no-print {
|
|
display: none;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="no-print text-center mb-2">
|
|
<button onclick="window.print()" style="padding: 10px 20px; cursor: pointer; border-radius: 8px; border: 1px solid #000; background: #eee;">Print / طباعة</button>
|
|
<button onclick="window.close()" style="padding: 10px 20px; cursor: pointer; border-radius: 8px; border: 1px solid #000; background: #fff;">Close / إغلاق</button>
|
|
</div>
|
|
|
|
<div class="text-center receipt-header">
|
|
<?php if ($company['logo']): ?>
|
|
<img src="<?= $company['logo'] ?>" alt="Logo" class="logo">
|
|
<?php endif; ?>
|
|
|
|
<h3 class="fw-bold"><?= $company['name_en'] ?></h3>
|
|
<h3 class="fw-bold arabic-text"><?= $company['name_ar'] ?></h3>
|
|
|
|
<div class="mt-1">
|
|
<div class="fw-bold"><?= $order['branch_name_en'] ?></div>
|
|
<div class="fw-bold arabic-text"><?= $order['branch_name_ar'] ?></div>
|
|
</div>
|
|
|
|
<div class="small mt-1">
|
|
<div><?= $order['branch_address_en'] ?></div>
|
|
<div class="arabic-text"><?= $order['branch_address_ar'] ?></div>
|
|
</div>
|
|
|
|
<div class="mt-1">
|
|
<span><?= $translations['en']['phone'] ?> / <?= $translations['ar']['phone'] ?>:</span>
|
|
<span><?= $order['branch_phone'] ?></span>
|
|
</div>
|
|
|
|
<?php if (!empty($company['ctr_no'])): ?>
|
|
<div>
|
|
<span><?= $translations['en']['ctr_no'] ?> / <?= $translations['ar']['ctr_no'] ?>:</span>
|
|
<span><?= $company['ctr_no'] ?></span>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if (!empty($company['vat_no']) || !empty($company['vat_number'])): ?>
|
|
<div>
|
|
<span><?= $translations['en']['vat_no'] ?> / <?= $translations['ar']['vat_no'] ?>:</span>
|
|
<span><?= $company['vat_no'] ?: $company['vat_number'] ?></span>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<div class="info-row">
|
|
<div class="info-label"><?= b_label('order') ?> #</div>
|
|
<div class="info-value fw-bold"><?= $order['order_number'] ?></div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label"><?= b_label('date') ?></div>
|
|
<div class="info-value"><?= date('d/m/Y H:i', strtotime($order['created_at'])) ?></div>
|
|
</div>
|
|
<div class="info-row">
|
|
<div class="info-label"><?= b_label('customer') ?></div>
|
|
<div class="info-value">
|
|
<div><?= $order['customer_name_en'] ?: 'Walk-in' ?></div>
|
|
<?php if ($order['customer_name_ar']): ?>
|
|
<div class="arabic-text"><?= $order['customer_name_ar'] ?></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<?php if ($order['customer_phone']): ?>
|
|
<div class="info-row">
|
|
<div class="info-label"><?= b_label('phone') ?></div>
|
|
<div class="info-value"><?= $order['customer_phone'] ?></div>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 55%;"><?= b_label('item') ?></th>
|
|
<th class="text-center" style="width: 15%;"><?= b_label('qty') ?></th>
|
|
<th class="text-end" style="width: 30%;"><?= b_label('total') ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach($order_items as $item): ?>
|
|
<tr>
|
|
<td>
|
|
<div class="fw-bold" style="font-size: 11px;"><?= $item['item_en'] ?></div>
|
|
<div class="item-name-ar"><?= $item['item_ar'] ?></div>
|
|
<div class="item-service"><?= $item['service_en'] ?> / <span class="arabic-text"><?= $item['service_ar'] ?></span></div>
|
|
</td>
|
|
<td class="text-center"><?= $item['quantity'] ?></td>
|
|
<td class="text-end fw-bold"><?= number_format($item['subtotal'] + ($item['vat_amount'] * $item['quantity']), decimals()) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="totals">
|
|
<div class="total-row">
|
|
<div class="info-label"><?= b_label('subtotal') ?></div>
|
|
<div class="info-value"><?= format_amount($order['total_price'] - $order['vat_total']) ?></div>
|
|
</div>
|
|
<div class="total-row">
|
|
<div class="info-label"><?= b_label('vat') ?></div>
|
|
<div class="info-value"><?= format_amount($order['vat_total']) ?></div>
|
|
</div>
|
|
<div class="total-row fw-bold grand-total">
|
|
<div class="info-label"><?= b_label('total') ?></div>
|
|
<div class="info-value" style="font-size: 16px;"><?= format_amount($order['total_price']) ?></div>
|
|
</div>
|
|
|
|
<div class="total-row mt-2">
|
|
<div class="info-label"><?= b_label('paid') ?></div>
|
|
<div class="info-value"><?= format_amount($total_paid) ?></div>
|
|
</div>
|
|
<?php if ($remaining > 0): ?>
|
|
<div class="total-row">
|
|
<div class="info-label"><?= b_label('remaining_amount') ?></div>
|
|
<div class="info-value fw-bold text-danger"><?= format_amount($remaining) ?></div>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div class="text-center footer">
|
|
<div class="fw-bold mb-1">Thank you for your visit!</div>
|
|
<div class="fw-bold arabic-text mb-1">شكراً لزيارتكم!</div>
|
|
<div class="mt-1">Please keep your receipt</div>
|
|
<div class="arabic-text">يرجى الاحتفاظ بالإيصال</div>
|
|
</div>
|
|
|
|
<script>
|
|
window.onload = function() {
|
|
// Check if we are in the print iframe
|
|
if (window.location.search.includes('id=')) {
|
|
// Auto print is handled by the parent in pos.php
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|