V4 quotation print
This commit is contained in:
parent
f4f4d49502
commit
4ce50d5774
115
index.php
115
index.php
@ -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" : "") ?>';
|
const invoiceType = '<?= in_array($page, ["sales", "quotations"]) ? "sale" : ($page === "purchases" ? "purchase" : "") ?>';
|
||||||
initInvoiceForm('productSearchInput', 'searchSuggestions', 'invoiceItemsTableBody', 'grandTotal', 'subtotal', 'totalVat');
|
initInvoiceForm('productSearchInput', 'searchSuggestions', 'invoiceItemsTableBody', 'grandTotal', 'subtotal', 'totalVat');
|
||||||
initInvoiceForm('editProductSearchInput', 'editSearchSuggestions', 'editInvoiceItemsTableBody', 'edit_grandTotal', 'edit_subtotal', 'edit_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 = `
|
content.innerHTML = `
|
||||||
<div class="p-5">
|
<div class="p-5">
|
||||||
<div class="d-flex justify-content-between mb-4 border-bottom pb-3">
|
<div class="invoice-header mb-4">
|
||||||
<div>
|
<div class="row align-items-center">
|
||||||
<h3 class="text-primary fw-bold">QUOTATION</h3>
|
<div class="col-6">
|
||||||
<p class="mb-0"><strong>No:</strong> QUO-${data.id.toString().padStart(5, '0')}</p>
|
${logoImg}
|
||||||
<p class="mb-0"><strong>Date:</strong> ${data.quotation_date}</p>
|
<h3 class="mb-1 fw-bold">${companyName}</h3>
|
||||||
<p class="mb-0"><strong>Valid Until:</strong> ${data.valid_until || 'N/A'}</p>
|
<p class="text-muted small mb-0">${companyAddress}</p>
|
||||||
</div>
|
${companyVat}
|
||||||
<div class="text-end">
|
${companyPhone}
|
||||||
<h4 class="fw-bold">${data.customer_name || 'Walk-in Customer'}</h4>
|
</div>
|
||||||
<p class="mb-0">Status: <span class="badge ${data.status === 'converted' ? 'bg-success' : 'bg-secondary'}">${data.status.toUpperCase()}</span></p>
|
<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>
|
||||||
</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">
|
<thead class="bg-dark text-white">
|
||||||
<tr>
|
<tr>
|
||||||
<th>#</th>
|
<th>#</th>
|
||||||
@ -3859,10 +3893,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div class="mt-5 pt-3 border-top">
|
<div class="mt-5 pt-3 border-top">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6">
|
<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">
|
<ul class="small text-muted">
|
||||||
<li>Quotation is valid until the date mentioned above.</li>
|
<li>Quotation is valid until the date mentioned above.</li>
|
||||||
<li>Prices are inclusive of VAT where applicable.</li>
|
<li>Prices are inclusive of VAT where applicable.</li>
|
||||||
@ -3873,6 +3908,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-4 text-center">
|
||||||
|
<p class="text-muted x-small mb-0">Generated by ${companyName}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -3899,7 +3937,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
editBtn.onclick = function() {
|
editBtn.onclick = function() {
|
||||||
const editModal = new bootstrap.Modal(document.getElementById('editQuotationModal'));
|
const editModal = new bootstrap.Modal(document.getElementById('editQuotationModal'));
|
||||||
modal.hide();
|
modal.hide();
|
||||||
// Trigger the existing edit button click logic or manually populate
|
|
||||||
const originalEditBtn = document.querySelector(`.edit-quotation-btn[data-json*='"id":${data.id},']`) ||
|
const originalEditBtn = document.querySelector(`.edit-quotation-btn[data-json*='"id":${data.id},']`) ||
|
||||||
document.querySelector(`.edit-quotation-btn[data-json*='"id":${data.id}']`);
|
document.querySelector(`.edit-quotation-btn[data-json*='"id":${data.id}']`);
|
||||||
if (originalEditBtn) originalEditBtn.click();
|
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; }
|
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; }
|
body { background: white !important; margin: 0 !important; padding: 0 !important; }
|
||||||
.main-content { margin: 0 !important; padding: 0 !important; background: white !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; }
|
/* Hide all modals by default */
|
||||||
#viewInvoiceModal .modal-dialog { max-width: 100% !important; width: 100% !important; margin: 0 !important; padding: 0 !important; }
|
.modal { display: none !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; }
|
/* 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; }
|
.table-bordered th, .table-bordered td { border: 1px solid #dee2e6 !important; }
|
||||||
.bg-light { background-color: #f8f9fa !important; -webkit-print-color-adjust: exact; }
|
.bg-light { background-color: #f8f9fa !important; -webkit-print-color-adjust: exact; }
|
||||||
.text-primary { color: #0d6efd !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 */
|
/* Ensure the modal is the only thing visible */
|
||||||
body > *:not(.main-content):not(.modal) { display: none !important; }
|
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-logo { max-height: 80px; width: auto; }
|
||||||
.invoice-header { border-bottom: 2px solid #333; padding-bottom: 20px; }
|
.invoice-header { border-bottom: 2px solid #333; padding-bottom: 20px; }
|
||||||
@ -5099,27 +5154,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
});
|
});
|
||||||
</script>
|
</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>
|
<script>
|
||||||
window.printItemBarcode = function(sku, name, price) {
|
window.printItemBarcode = function(sku, name, price) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user