39728-vm/print_receipt.php
2026-04-19 09:52:55 +00:00

289 lines
9.4 KiB
PHP

<?php
require_once __DIR__ . '/includes/app.php';
$user = require_roles(['owner', 'manager', 'cashier']);
$id = (int) ($_GET['id'] ?? 0);
$sale = null;
$dbError = null;
if ($id > 0) {
try {
$sale = fetch_sale($id);
} catch (Throwable $e) {
$dbError = $e->getMessage();
}
}
if (!$sale) {
die("Sale not found.");
}
// Receipt Configuration
$storeName = current_lang() === 'ar' ? get_setting('company_name_ar', 'حلوى الريامي') : get_setting('company_name_en', 'Al Riyami Sweets');
$storeAddress = get_setting('company_address', '');
$vatNo = get_setting('company_vat_number', '300123456789012');
$registerNo = 'REG-01';
?>
<!DOCTYPE html>
<html lang="<?= current_lang() ?>" dir="<?= current_lang() === 'ar' ? 'rtl' : 'ltr' ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= h(tr('إيصال', 'Receipt')) ?> #<?= h($sale['receipt_no']) ?></title>
<style>
/* 80mm Receipt Styles */
body {
font-family: 'Courier New', Courier, monospace;
font-size: 13px;
color: #000;
background: #f8f9fa;
margin: 0;
padding: 20px;
display: flex;
justify-content: center;
}
.receipt-container {
width: 80mm;
max-width: 100%;
background: #fff;
padding: 15px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
@media print {
body {
background: #fff;
padding: 0;
margin: 0;
}
.receipt-container {
box-shadow: none;
width: 100%;
padding: 10px;
}
.no-print {
display: none !important;
}
@page {
margin: 0;
size: 80mm 297mm; /* standard 80mm paper roll size */
}
}
.text-center { text-align: center; }
.text-right { text-align: right; }
.text-left { text-align: left; }
.font-bold { font-weight: bold; }
.logo-area {
margin-bottom: 10px;
}
.logo-area img {
max-width: 60px;
filter: grayscale(100%);
}
.header-info { margin-bottom: 15px; line-height: 1.4; }
.header-info div { margin-bottom: 2px; }
.divider {
border-bottom: 1px dashed #000;
margin: 10px 0;
}
.sale-info {
display: flex;
justify-content: space-between;
margin-bottom: 3px;
}
table.items {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
}
table.items th, table.items td {
padding: 4px 0;
vertical-align: top;
}
table.items th {
border-bottom: 1px dashed #000;
font-weight: bold;
}
.col-qty { width: 15%; text-align: center; }
.col-price { width: 25%; text-align: <?= current_lang() === 'ar' ? 'left' : 'right' ?>; }
.col-total { width: 25%; text-align: <?= current_lang() === 'ar' ? 'left' : 'right' ?>; font-weight: bold; }
.col-name { width: 35%; }
.totals-area {
margin-top: 10px;
}
.totals-row {
display: flex;
justify-content: space-between;
font-size: 14px;
margin-bottom: 4px;
}
.totals-row.grand-total {
font-size: 18px;
font-weight: bold;
border-top: 1px dashed #000;
border-bottom: 1px dashed #000;
padding: 8px 0;
margin-top: 5px;
margin-bottom: 15px;
}
.footer-msg {
text-align: center;
margin-top: 15px;
font-size: 12px;
line-height: 1.4;
}
.barcode {
text-align: center;
margin-top: 10px;
font-family: 'Libre Barcode 39', cursive;
font-size: 40px;
}
/* Interactive actions */
.print-actions {
position: fixed;
bottom: 20px;
right: 20px;
display: flex;
gap: 10px;
}
.btn {
background: #0d6efd;
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
font-family: Arial, sans-serif;
font-size: 14px;
text-decoration: none;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}
.btn-secondary { background: #6c757d; }
</style>
</head>
<body>
<div class="receipt-container">
<!-- Logo -->
<div class="text-center logo-area">
<!-- SVG Placeholder Logo -->
<?php if (get_setting('company_logo')): ?>
<img src="<?= h(get_setting('company_logo')) ?>" alt="Logo" style="max-height: 80px; max-width: 150px;">
<?php else: ?>
<svg width="60" height="60" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="100" height="100" rx="20" fill="#000"/>
<path d="M50 20 L80 80 L20 80 Z" fill="#fff"/>
</svg>
<?php endif; ?>
</div>
<!-- Store Info -->
<div class="text-center header-info">
<div class="font-bold" style="font-size: 16px;"><?= h($storeName) ?></div>
<div><?= h($storeAddress) ?></div>
<div>VAT: <?= h($vatNo) ?></div>
<div><?= h(tr('هاتف', 'Tel')) ?>: <?= h(get_setting('company_phone', '')) ?></div>
</div>
<div class="divider"></div>
<!-- Receipt Meta -->
<div class="sale-info">
<span><?= h(tr('رقم الفاتورة', 'Receipt No')) ?>:</span>
<span class="font-bold"><?= h($sale['receipt_no']) ?></span>
</div>
<div class="sale-info">
<span><?= h(tr('التاريخ', 'Date')) ?>:</span>
<span><?= h(date('Y-m-d H:i', strtotime((string)$sale['sale_date']))) ?></span>
</div>
<div class="sale-info">
<span><?= h(tr('الكاشير', 'Cashier')) ?>:</span>
<span><?= h($sale['cashier_name']) ?> (<?= h($registerNo) ?>)</span>
</div>
<?php if(!empty($sale['customer_name'])): ?>
<div class="sale-info">
<span><?= h(tr('العميل', 'Customer')) ?>:</span>
<span><?= h($sale['customer_name']) ?></span>
</div>
<?php endif; ?>
<div class="divider"></div>
<!-- Items -->
<table class="items">
<thead>
<tr>
<th class="text-<?= current_lang() === 'ar' ? 'right' : 'left' ?> col-name"><?= h(tr('الصنف', 'Item')) ?></th>
<th class="col-qty"><?= h(tr('كمية', 'Qty')) ?></th>
<th class="col-price"><?= h(tr('سعر', 'Price')) ?></th>
<th class="col-total"><?= h(tr('إجمالي', 'Total')) ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($sale['items'] as $item):
$name = current_lang() === 'ar' ? ($item['name_ar'] ?? $item['sku']) : ($item['name_en'] ?? $item['sku']);
?>
<tr>
<td class="col-name"><?= h($name) ?></td>
<td class="col-qty"><?= h($item['qty']) ?></td>
<td class="col-price"><?= number_format((float)$item['price'], 3) ?></td>
<td class="col-total"><?= number_format((float)$item['line_total'], 3) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div class="divider"></div>
<!-- Totals -->
<div class="totals-area">
<div class="totals-row">
<span><?= h(tr('المجموع الفرعي', 'Subtotal')) ?></span>
<span><?= number_format((float)$sale['subtotal'], 3) ?></span>
</div>
<div class="totals-row">
<span><?= h(tr('ضريبة القيمة المضافة (مشمولة)', 'VAT (Inclusive)')) ?></span>
<span><?= number_format((float)($sale['vat_amount'] ?? 0), 3) ?></span>
</div>
<div class="totals-row grand-total">
<span><?= h(tr('الإجمالي', 'Total')) ?></span>
<span><?= number_format((float)$sale['total_amount'], 3) ?> <?= h(tr('ر.ع', 'OMR')) ?></span>
</div>
<div class="totals-row">
<span><?= h(tr('طريقة الدفع', 'Payment Method')) ?></span>
<span><?= h(ucfirst((string)$sale['payment_method'])) ?></span>
</div>
</div>
<!-- Footer -->
<div class="footer-msg">
<p class="font-bold"><?= h(tr('شكراً لتسوقكم معنا!', 'Thank you for shopping with us!')) ?></p>
<p><?= h(tr('البضاعة المباعة ترد وتستبدل خلال 14 يوماً من تاريخ الشراء', 'Items can be returned or exchanged within 14 days of purchase.')) ?></p>
</div>
</div>
<!-- Print Actions -->
<div class="print-actions no-print">
<a href="pos.php" class="btn btn-secondary"><?= h(tr('رجوع لـ POS', 'Back to POS')) ?></a>
<button onclick="window.print()" class="btn"><?= h(tr('طباعة الآن', 'Print Now')) ?></button>
</div>
<script>
// Auto print when page loads
window.onload = function() {
setTimeout(() => {
window.print();
}, 500);
};
</script>
</body>
</html>