V4 quotation print

This commit is contained in:
Flatlogic Bot 2026-02-17 08:34:19 +00:00
parent f4f4d49502
commit 4ce50d5774

115
index.php
View File

@ -3751,6 +3751,7 @@ document.addEventListener('DOMContentLoaded', function() {
});
}
const companySettings = <?= json_encode($data['settings']) ?>;
const invoiceType = '<?= in_array($page, ["sales", "quotations"]) ? "sale" : ($page === "purchases" ? "purchase" : "") ?>';
initInvoiceForm('productSearchInput', 'searchSuggestions', 'invoiceItemsTableBody', 'grandTotal', 'subtotal', 'totalVat');
initInvoiceForm('editProductSearchInput', 'editSearchSuggestions', 'editInvoiceItemsTableBody', 'edit_grandTotal', 'edit_subtotal', 'edit_totalVat');
@ -3818,21 +3819,54 @@ document.addEventListener('DOMContentLoaded', function() {
`;
});
// Company Logo and Header Construction
const logoUrl = companySettings.company_logo || '';
const logoImg = logoUrl ? `<img src="${logoUrl}" alt="Logo" class="invoice-logo mb-3">` : '';
const companyName = companySettings.company_name || 'Accounting System';
const companyAddress = (companySettings.company_address || '').replace(/\n/g, '<br>');
const companyVat = companySettings.vat_number ? `<p class="text-muted small mb-0">VAT: ${companySettings.vat_number}</p>` : '';
const companyPhone = companySettings.company_phone ? `<p class="text-muted small mb-0">Tel: ${companySettings.company_phone}</p>` : '';
// Quotation Header Construction
const quotDate = data.quotation_date;
const quotValid = data.valid_until || 'N/A';
const quotNo = 'QUO-' + data.id.toString().padStart(5, '0');
const customerName = data.customer_name || 'Walk-in Customer';
const statusBadge = `<span class="badge ${data.status === 'converted' ? 'bg-success' : 'bg-secondary'}">${data.status.toUpperCase()}</span>`;
content.innerHTML = `
<div class="p-5">
<div class="d-flex justify-content-between mb-4 border-bottom pb-3">
<div>
<h3 class="text-primary fw-bold">QUOTATION</h3>
<p class="mb-0"><strong>No:</strong> QUO-${data.id.toString().padStart(5, '0')}</p>
<p class="mb-0"><strong>Date:</strong> ${data.quotation_date}</p>
<p class="mb-0"><strong>Valid Until:</strong> ${data.valid_until || 'N/A'}</p>
</div>
<div class="text-end">
<h4 class="fw-bold">${data.customer_name || 'Walk-in Customer'}</h4>
<p class="mb-0">Status: <span class="badge ${data.status === 'converted' ? 'bg-success' : 'bg-secondary'}">${data.status.toUpperCase()}</span></p>
<div class="invoice-header mb-4">
<div class="row align-items-center">
<div class="col-6">
${logoImg}
<h3 class="mb-1 fw-bold">${companyName}</h3>
<p class="text-muted small mb-0">${companyAddress}</p>
${companyVat}
${companyPhone}
</div>
<div class="col-6 text-end">
<h1 class="invoice-title fw-bold mb-0 text-uppercase">Quotation</h1>
<div class="mt-2">${statusBadge}</div>
<div class="mt-3">
<p class="mb-0 fs-5">No: <strong class="text-primary">${quotNo}</strong></p>
<p class="mb-0">Date: <span class="fw-bold">${quotDate}</span></p>
<p class="mb-0">Valid Until: <span class="fw-bold">${quotValid}</span></p>
</div>
</div>
</div>
</div>
<table class="table table-bordered table-striped">
<div class="row mb-4 g-3">
<div class="col-6">
<div class="invoice-info-card">
<p class="text-muted small text-uppercase fw-bold mb-2 border-bottom pb-1">To</p>
<h5 class="mb-1 fw-bold">${customerName}</h5>
</div>
</div>
</div>
<table class="table table-bordered table-formal">
<thead class="bg-dark text-white">
<tr>
<th>#</th>
@ -3859,10 +3893,11 @@ document.addEventListener('DOMContentLoaded', function() {
</tr>
</tfoot>
</table>
<div class="mt-5 pt-3 border-top">
<div class="row">
<div class="col-6">
<p class="small text-muted">Terms & Conditions:</p>
<p class="small text-muted text-uppercase fw-bold">Terms & Conditions:</p>
<ul class="small text-muted">
<li>Quotation is valid until the date mentioned above.</li>
<li>Prices are inclusive of VAT where applicable.</li>
@ -3873,6 +3908,9 @@ document.addEventListener('DOMContentLoaded', function() {
</div>
</div>
</div>
<div class="mt-4 text-center">
<p class="text-muted x-small mb-0">Generated by ${companyName}</p>
</div>
</div>
`;
@ -3899,7 +3937,6 @@ document.addEventListener('DOMContentLoaded', function() {
editBtn.onclick = function() {
const editModal = new bootstrap.Modal(document.getElementById('editQuotationModal'));
modal.hide();
// Trigger the existing edit button click logic or manually populate
const originalEditBtn = document.querySelector(`.edit-quotation-btn[data-json*='"id":${data.id},']`) ||
document.querySelector(`.edit-quotation-btn[data-json*='"id":${data.id}']`);
if (originalEditBtn) originalEditBtn.click();
@ -4387,11 +4424,29 @@ document.addEventListener('DOMContentLoaded', function() {
table:not(.table-formal), .bg-light:not(.invoice-info-card):not(.p-3), .modal-backdrop { display: none !important; }
body { background: white !important; margin: 0 !important; padding: 0 !important; }
.main-content { margin: 0 !important; padding: 0 !important; background: white !important; }
.modal { position: absolute !important; left: 0 !important; top: 0 !important; margin: 0 !important; padding: 0 !important; overflow: visible !important; display: block !important; visibility: visible !important; background: white !important; }
#viewInvoiceModal { display: block !important; background: white !important; }
#viewInvoiceModal .modal-dialog { max-width: 100% !important; width: 100% !important; margin: 0 !important; padding: 0 !important; }
#viewInvoiceModal .modal-content { border: none !important; box-shadow: none !important; background: white !important; }
#viewInvoiceModal .modal-body { padding: 0 !important; margin: 0 !important; background: white !important; }
/* Hide all modals by default */
.modal { display: none !important; }
/* Show ONLY the active modal */
.modal.show {
position: absolute !important;
left: 0 !important;
top: 0 !important;
margin: 0 !important;
padding: 0 !important;
overflow: visible !important;
display: block !important;
visibility: visible !important;
background: white !important;
width: 100% !important;
height: 100% !important;
}
.modal.show .modal-dialog { max-width: 100% !important; width: 100% !important; margin: 0 !important; padding: 0 !important; }
.modal.show .modal-content { border: none !important; box-shadow: none !important; background: white !important; }
.modal.show .modal-body { padding: 0 !important; margin: 0 !important; background: white !important; }
.table-bordered th, .table-bordered td { border: 1px solid #dee2e6 !important; }
.bg-light { background-color: #f8f9fa !important; -webkit-print-color-adjust: exact; }
.text-primary { color: #0d6efd !important; -webkit-print-color-adjust: exact; }
@ -4399,7 +4454,7 @@ document.addEventListener('DOMContentLoaded', function() {
/* Ensure the modal is the only thing visible */
body > *:not(.main-content):not(.modal) { display: none !important; }
.main-content > *:not(#viewInvoiceModal):not(.modal) { display: none !important; }
.main-content > *:not(.modal) { display: none !important; }
}
.invoice-logo { max-height: 80px; width: auto; }
.invoice-header { border-bottom: 2px solid #333; padding-bottom: 20px; }
@ -5099,27 +5154,7 @@ document.addEventListener('DOMContentLoaded', function() {
});
</script>
<style>
@media print {
.no-print, .sidebar, .topbar, .card, .btn, .modal-header, .modal-footer, .d-print-none, .table-responsive,
table:not(.table-formal), .bg-light:not(.invoice-info-card):not(.p-3), .modal-backdrop { display: none !important; }
body { background: white !important; margin: 0 !important; padding: 0 !important; }
.main-content { margin: 0 !important; padding: 0 !important; background: white !important; }
.modal { position: absolute !important; left: 0 !important; top: 0 !important; margin: 0 !important; padding: 0 !important; overflow: visible !important; display: block !important; visibility: visible !important; background: white !important; }
#viewInvoiceModal { display: block !important; background: white !important; }
#viewInvoiceModal .modal-dialog { max-width: 100% !important; width: 100% !important; margin: 0 !important; padding: 0 !important; }
#viewInvoiceModal .modal-content { border: none !important; box-shadow: none !important; background: white !important; }
#viewInvoiceModal .modal-body { padding: 0 !important; margin: 0 !important; background: white !important; }
.table-bordered th, .table-bordered td { border: 1px solid #dee2e6 !important; }
.bg-light { background-color: #f8f9fa !important; -webkit-print-color-adjust: exact; }
.text-primary { color: #0d6efd !important; -webkit-print-color-adjust: exact; }
.badge { border: 1px solid #000; color: #000 !important; }
/* Ensure the modal is the only thing visible */
body > *:not(.main-content):not(.modal) { display: none !important; }
.main-content > *:not(#viewInvoiceModal):not(.modal) { display: none !important; }
}
</style>
<script>
window.printItemBarcode = function(sku, name, price) {