333 lines
13 KiB
PHP
333 lines
13 KiB
PHP
<?php
|
|
require_once __DIR__ . '/includes/app.php';
|
|
$user = require_roles(['owner', 'manager', 'cashier']);
|
|
$pageTitle = tr('تفاصيل الفاتورة الضريبية', 'Tax Invoice Details');
|
|
$activeNav = 'sales';
|
|
$id = (int) ($_GET['id'] ?? 0);
|
|
$sale = null;
|
|
$dbError = null;
|
|
if ($id > 0) {
|
|
try {
|
|
$sale = fetch_sale($id);
|
|
} catch (Throwable $e) {
|
|
$dbError = $e->getMessage();
|
|
}
|
|
}
|
|
|
|
// Company Info for Invoice
|
|
$companyName = tr('متجر فلات لوجيك', 'Flatlogic Store');
|
|
$companyAddress = tr('شارع الملك فهد، الرياض، المملكة العربية السعودية', 'King Fahd Road, Riyadh, KSA');
|
|
$companyVat = '300123456789012';
|
|
$companyEmail = 'info@flatlogic.com';
|
|
$companyPhone = '920000000';
|
|
|
|
require __DIR__ . '/includes/header.php';
|
|
?>
|
|
|
|
<style>
|
|
/* Full Page Borderless Invoice */
|
|
.invoice-page {
|
|
background: #fff;
|
|
min-height: 80vh;
|
|
max-width: 900px; margin: 0 auto; border-radius: 12px; box-shadow: 0 10px 40px rgba(0,0,0,0.08); overflow: hidden;
|
|
padding: 4rem 3rem;
|
|
position: relative;
|
|
}
|
|
.invoice-ribbon {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 12px;
|
|
background: linear-gradient(90deg, #212529, #6c757d);
|
|
}
|
|
.invoice-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-start;
|
|
margin-bottom: 4rem;
|
|
}
|
|
.company-details h2 {
|
|
font-weight: 800;
|
|
color: #212529;
|
|
font-size: 2.5rem;
|
|
letter-spacing: -1px;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.company-details p {
|
|
color: #adb5bd;
|
|
margin-bottom: 0.25rem;
|
|
font-size: 1rem;
|
|
}
|
|
.invoice-meta {
|
|
text-align: <?= current_lang() === 'ar' ? 'left' : 'right' ?>;
|
|
}
|
|
.invoice-meta h1 {
|
|
font-size: 4rem;
|
|
font-weight: 900;
|
|
color: #f8f9fa;
|
|
text-transform: uppercase;
|
|
letter-spacing: 2px;
|
|
line-height: 1;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.meta-box-row {
|
|
display: flex;
|
|
justify-content: <?= current_lang() === 'ar' ? 'flex-start' : 'flex-end' ?>;
|
|
gap: 2rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.meta-label {
|
|
color: #adb5bd;
|
|
font-size: 0.9rem;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
}
|
|
.meta-val {
|
|
font-weight: 700;
|
|
color: #212529;
|
|
font-size: 1.1rem;
|
|
}
|
|
.invoice-parties {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-bottom: 4rem;
|
|
padding-top: 3rem;
|
|
border-top: 1px dashed #dee2e6;
|
|
}
|
|
.party-box {
|
|
flex: 1;
|
|
}
|
|
.party-title {
|
|
font-size: 0.85rem;
|
|
color: #adb5bd;
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
margin-bottom: 1rem;
|
|
letter-spacing: 1px;
|
|
}
|
|
.party-info h4 {
|
|
font-weight: 800;
|
|
font-size: 1.5rem;
|
|
margin-bottom: 0.5rem;
|
|
color: #212529;
|
|
}
|
|
.party-info p {
|
|
color: #6c757d;
|
|
margin-bottom: 0;
|
|
font-size: 1.1rem;
|
|
}
|
|
.invoice-table {
|
|
width: 100%;
|
|
margin-bottom: 4rem;
|
|
border-collapse: collapse;
|
|
}
|
|
.invoice-table th {
|
|
color: #adb5bd;
|
|
font-weight: 600;
|
|
padding: 1rem 0;
|
|
border-bottom: 2px solid #212529;
|
|
text-transform: uppercase;
|
|
font-size: 0.85rem;
|
|
letter-spacing: 1px;
|
|
}
|
|
.invoice-table td {
|
|
padding: 1.5rem 0;
|
|
border-bottom: 1px solid #f8f9fa;
|
|
vertical-align: middle;
|
|
}
|
|
.invoice-table tr:last-child td { border-bottom: 1px solid #dee2e6; }
|
|
.totals-section {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
margin-bottom: 4rem;
|
|
}
|
|
.totals-box {
|
|
width: 100%;
|
|
max-width: 400px;
|
|
}
|
|
.totals-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-bottom: 1rem;
|
|
font-size: 1.2rem;
|
|
color: #6c757d;
|
|
}
|
|
.totals-row.grand-total {
|
|
font-size: 2.5rem;
|
|
font-weight: 900;
|
|
color: #212529;
|
|
margin-top: 1.5rem;
|
|
padding-top: 1.5rem;
|
|
border-top: 2px solid #212529;
|
|
margin-bottom: 0;
|
|
line-height: 1.2;
|
|
}
|
|
.invoice-footer {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-end;
|
|
color: #adb5bd;
|
|
font-size: 0.95rem;
|
|
border-top: 1px dashed #dee2e6;
|
|
padding-top: 3rem;
|
|
}
|
|
.qr-placeholder {
|
|
width: 120px;
|
|
height: 120px;
|
|
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect width="100" height="100" fill="%23f8f9fa"/><path d="M20 20h20v20H20zM60 20h20v20H60zM20 60h20v20H20zM50 50h10v10H50zM70 60h10v10H70zM60 70h10v10H60z" fill="%23dee2e6"/></svg>') center/cover;
|
|
}
|
|
.print-actions {
|
|
position: sticky;
|
|
top: 1rem;
|
|
z-index: 100;
|
|
background: rgba(255, 255, 255, 0.9);
|
|
backdrop-filter: blur(10px);
|
|
padding: 1rem;
|
|
border-radius: 100px;
|
|
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
|
|
}
|
|
|
|
/* Print Styles */
|
|
@media print {
|
|
body { background: #fff; margin: 0; padding: 0; }
|
|
.main-sidebar, .main-header, .print-actions, .alert { display: none !important; }
|
|
.main-content { margin: 0 !important; padding: 0 !important; width: 100% !important; }
|
|
.invoice-page { padding: 0; margin: 0; min-height: auto; }
|
|
@page { size: A4; margin: 1.5cm; }
|
|
}
|
|
</style>
|
|
|
|
<div class="container-fluid mb-5">
|
|
<?php if ($dbError): ?>
|
|
<div class="alert alert-warning"><?= h($dbError) ?></div>
|
|
<?php elseif (!$sale): ?>
|
|
<div class="empty-state bg-white rounded-4 shadow-sm p-5 text-center">
|
|
<i class="bi bi-file-earmark-x fs-1 text-muted d-block mb-3"></i>
|
|
<h4><?= h(tr('الفاتورة غير موجودة', 'Sale not found')) ?></h4>
|
|
<p class="text-muted"><?= h(tr('قد تكون الفاتورة خارج صلاحية هذا الحساب أو لم تعد موجودة.', 'The sale may be outside this account scope or no longer exists.')) ?></p>
|
|
<a class="btn btn-outline-secondary mt-3 rounded-pill px-4" href="<?= h(url_for('sales.php')) ?>"><?= h(tr('العودة إلى المبيعات', 'Back to sales')) ?></a>
|
|
</div>
|
|
<?php else: ?>
|
|
|
|
<!-- Print Actions (Hidden when printing) -->
|
|
<div class="print-actions d-flex justify-content-between align-items-center mb-4 mx-auto" style="max-width: 800px;">
|
|
<a href="sales.php" class="btn btn-link text-muted text-decoration-none">
|
|
<i class="bi bi-arrow-<?= current_lang() === 'ar' ? 'right' : 'left' ?> me-1"></i> <?= h(tr('رجوع للسجل', 'Back to ledger')) ?>
|
|
</a>
|
|
<button onclick="window.print()" class="btn btn-dark rounded-pill px-4 shadow-sm fs-6">
|
|
<i class="bi bi-printer me-2"></i><?= h(tr('طباعة الفاتورة (A4)', 'Print Invoice (A4)')) ?>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Invoice A4 Document -->
|
|
<div class="invoice-page">
|
|
<div class="invoice-ribbon"></div>
|
|
|
|
<div class="invoice-header flex-column flex-md-row">
|
|
<div class="company-details mb-4 mb-md-0">
|
|
<h2><?= h($companyName) ?></h2>
|
|
<p><?= h($companyAddress) ?></p>
|
|
<p>VAT NO: <?= h($companyVat) ?></p>
|
|
<p><?= h($companyEmail) ?> • <?= h($companyPhone) ?></p>
|
|
</div>
|
|
<div class="invoice-meta">
|
|
<h1><?= ($sale['status'] ?? 'completed') === 'order' ? h(tr('طلب حجز', 'ORDER')) : h(tr('فاتورة ضريبية', 'TAX INVOICE')) ?></h1>
|
|
<div class="meta-box-row">
|
|
<span class="meta-label"><?= h(tr('رقم الفاتورة', 'Invoice No.')) ?></span>
|
|
<span class="meta-val">#<?= h($sale['receipt_no']) ?></span>
|
|
</div>
|
|
<div class="meta-box-row">
|
|
<span class="meta-label"><?= h(tr('تاريخ الإصدار', 'Date Issued')) ?></span>
|
|
<span class="meta-val"><?= h(date('Y-m-d', strtotime((string) $sale['sale_date']))) ?></span>
|
|
</div>
|
|
<div class="meta-box-row">
|
|
<span class="meta-label"><?= h(tr('طريقة الدفع', 'Payment')) ?></span>
|
|
<span class="meta-val"><?= h(ucfirst((string) $sale['payment_method'])) ?></span>
|
|
</div>
|
|
<div class="meta-box-row">
|
|
<span class="meta-label"><?= h(tr('الحالة', 'Status')) ?></span>
|
|
<span class="meta-val"><?= ($sale['status'] ?? 'completed') === 'order' ? h(tr('طلب حجز (غير مدفوع)\", 'Order (Unpaid)\")) : h(tr('مدفوعة', 'Paid')) ?></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="invoice-parties">
|
|
<div class="party-box">
|
|
<div class="party-title"><?= h(tr('فاتورة إلى', 'Invoice To')) ?></div>
|
|
<div class="party-info">
|
|
<h4><?= h((string) ($sale['customer_name'] ?: tr('عميل نقدي', 'Walk-in Customer'))) ?></h4>
|
|
<p><?= h(tr('الفرع:', 'Branch:')) ?> <?= h(branch_label((string) $sale['branch_code'])) ?></p>
|
|
</div>
|
|
</div>
|
|
<div class="party-box text-<?= current_lang() === 'ar' ? 'left' : 'right' ?>">
|
|
<div class="party-title"><?= h(tr('بواسطة', 'Served By')) ?></div>
|
|
<div class="party-info">
|
|
<h4><?= h((string) $sale['cashier_name']) ?></h4>
|
|
<p><?= h(tr('موظف مبيعات', 'Sales Rep')) ?></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<table class="invoice-table">
|
|
<thead>
|
|
<tr>
|
|
<th width="50%" class="text-<?= current_lang() === 'ar' ? 'right' : 'left' ?>"><?= h(tr('وصف الصنف', 'Item Description')) ?></th>
|
|
<th width="15%" class="text-center"><?= h(tr('السعر', 'Price')) ?></th>
|
|
<th width="15%" class="text-center"><?= h(tr('الكمية', 'Qty')) ?></th>
|
|
<th width="20%" class="text-<?= current_lang() === 'ar' ? 'left' : 'right' ?>"><?= h(tr('الإجمالي', 'Line Total')) ?></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($sale['items'] as $item): ?>
|
|
<tr>
|
|
<td>
|
|
<div class="fw-bold fs-5 text-dark"><?= h(current_lang() === 'ar' ? ($item['name_ar'] ?? $item['sku']) : ($item['name_en'] ?? $item['sku'])) ?></div>
|
|
<div class="text-muted">SKU: <?= h($item['sku']) ?></div>
|
|
</td>
|
|
<td class="text-center fs-5"><?= h(number_format((float) ($item['price'] ?? 0), 3)) ?></td>
|
|
<td class="text-center fs-5 fw-bold"><?= h((string) ($item['qty'] ?? 0)) ?></td>
|
|
<td class="text-<?= current_lang() === 'ar' ? 'left' : 'right' ?> fs-4 fw-bold text-dark"><?= h(number_format((float) ($item['line_total'] ?? 0), 3)) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="totals-section">
|
|
<div class="totals-box">
|
|
<div class="totals-row">
|
|
<span><?= h(tr('المجموع الفرعي', 'Subtotal')) ?></span>
|
|
<span class="text-dark fw-bold"><?= h(number_format((float) $sale['subtotal'], 3)) ?></span>
|
|
</div>
|
|
<div class="totals-row">
|
|
<span><?= h(tr('ضريبة القيمة المضافة (15%)', 'VAT (15%)')) ?></span>
|
|
<span class="text-success"><?= h(tr('شامل', 'Inclusive')) ?></span>
|
|
</div>
|
|
<div class="totals-row grand-total">
|
|
<span><?= h(tr('الإجمالي', 'Total')) ?></span>
|
|
<span><?= h(number_format((float) $sale['total_amount'], 3)) ?> <small class="fs-5 text-muted"><?= h(tr('ر.ع', 'OMR')) ?></small></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (!empty($sale['notes'])): ?>
|
|
<div class="mb-5 px-4 py-3 bg-light" style="border-left: 4px solid #dee2e6;">
|
|
<strong class="text-uppercase text-muted fs-6 d-block mb-1"><?= h(tr('ملاحظات', 'Notes')) ?></strong>
|
|
<span class="fs-5 text-dark"><?= h((string) $sale['notes']) ?></span>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="invoice-footer">
|
|
<div>
|
|
<h5 class="fw-bold text-dark mb-1"><?= h(tr('شكراً لتعاملكم معنا!', 'Thank you for your business!')) ?></h5>
|
|
<p class="mb-0"><?= h(tr('هذه الفاتورة معتمدة ضريبياً، يُرجى الاحتفاظ بها لضمان حقوقك.', 'This is a certified tax invoice. Please keep it for your records.')) ?></p>
|
|
</div>
|
|
<div class="qr-placeholder"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<?php require __DIR__ . '/includes/footer.php'; ?>
|