From 0b7a05f3a8a902fe3a27bfd6a9819279493fb723 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 3 May 2026 13:09:07 +0000 Subject: [PATCH] index no end changes --- index.php | 22 ++- pages/lpo_quotation_script.php | 145 +++++++++++------- ...sales_purchases_invoice_actions_script.php | 34 +--- .../sales_purchases_invoice_form_helpers.php | 94 ++++++++++++ pages/sales_purchases_page_script.php | 1 - pages/sales_purchases_view.php | 5 +- 6 files changed, 211 insertions(+), 90 deletions(-) diff --git a/index.php b/index.php index b14e2b2..04cb306 100644 --- a/index.php +++ b/index.php @@ -8827,11 +8827,15 @@ runtime_debug_mark('page:rendering', ['page' => (string)$page]);
- + - +
+ + + +
@@ -8950,9 +8954,13 @@ runtime_debug_mark('page:rendering', ['page' => (string)$page]); - + - +
+ + + +
@@ -12000,7 +12008,13 @@ document.addEventListener('DOMContentLoaded', function() { }); }); + + 'script', 'page' => (string)$page]); ?> + + + 'script', 'page' => (string)$page]); ?> + 'script', 'page' => (string)$page]); ?> diff --git a/pages/lpo_quotation_script.php b/pages/lpo_quotation_script.php index 1ce41eb..b46f8c2 100644 --- a/pages/lpo_quotation_script.php +++ b/pages/lpo_quotation_script.php @@ -2,36 +2,77 @@ initInvoiceForm('lpoProductSearchInput', 'lpoSearchSuggestions', 'lpoItemsTableBody', 'lpo_grand_display', 'lpo_subtotal_display', 'lpo_vat_display'); initInvoiceForm('editLpoProductSearchInput', 'editLpoSearchSuggestions', 'editLpoItemsTableBody', 'edit_lpo_grand_display', 'edit_lpo_subtotal_display', 'edit_lpo_vat_display'); + + const parseLpoQuotationButtonPayload = (btn) => { + if (!btn || !btn.dataset || !btn.dataset.json) return {}; + try { + return JSON.parse(btn.dataset.json); + } catch (error) { + console.warn('Failed to parse LPO/Quotation payload from button data.', error); + return {}; + } + }; + + const renderExistingDocumentItems = (items, tableBodyId, grandTotalId, subtotalId, totalVatId) => { + const tableBody = document.getElementById(tableBodyId); + const grandTotalEl = document.getElementById(grandTotalId); + const subtotalEl = document.getElementById(subtotalId); + const totalVatEl = document.getElementById(totalVatId); + + if (!tableBody) return; + tableBody.innerHTML = ''; + + if (!Array.isArray(items) || items.length === 0) { + if (typeof recalculate === 'function') { + recalculate(tableBody, grandTotalEl, subtotalEl, totalVatEl); + } + return; + } + + items.forEach(item => { + addItemToTable({ + id: item.item_id || item.id, + name_en: item.name_en || item.item_name_en || 'Item', + name_ar: item.name_ar || item.item_name_ar || '', + sku: item.sku || '', + vat_rate: item.vat_rate || 0, + stock_quantity: item.stock_quantity || 0 + }, tableBody, null, null, grandTotalEl, subtotalEl, totalVatEl, { + quantity: item.quantity, + unit_price: item.unit_price + }); + }); + }; + document.querySelectorAll('.edit-lpo-btn').forEach(btn => { btn.addEventListener('click', function() { - const data = JSON.parse(this.dataset.json); - document.getElementById('edit_lpo_id').value = data.id; + const data = parseLpoQuotationButtonPayload(this); + if (Object.keys(data).length === 0) return; + const supplierSelect = document.getElementById('edit_lpo_supplier_id'); - supplierSelect.value = data.supplier_id; - if (window.jQuery && $(supplierSelect).data('select2')) { - $(supplierSelect).trigger('change'); + const supplierId = data.supplier_id ?? ''; + const supplierLabel = data.supplier_name || ''; + + invoiceEnsureSelectOption('edit_lpo_supplier_id', supplierId, supplierLabel); + + const lpoIdInput = document.getElementById('edit_lpo_id'); + const lpoDateInput = document.getElementById('edit_lpo_date'); + const deliveryDateInput = document.getElementById('edit_lpo_delivery_date'); + const statusSelect = document.getElementById('edit_lpo_status'); + const termsInput = document.getElementById('edit_lpo_terms'); + + if (lpoIdInput) lpoIdInput.value = data.id || ''; + if (supplierSelect) { + invoiceSetBlankSelectOptionLabel(supplierSelect, (supplierId === '' && supplierLabel) ? supplierLabel : '---'); + supplierSelect.value = supplierId; + invoiceSyncSelect2Value(supplierSelect); } - document.getElementById('edit_lpo_date').value = data.lpo_date; - document.getElementById('edit_lpo_delivery_date').value = data.delivery_date || ''; - document.getElementById('edit_lpo_status').value = data.status || 'pending'; - document.getElementById('edit_lpo_terms').value = data.terms_conditions || ''; - - const tableBody = document.getElementById('editLpoItemsTableBody'); - tableBody.innerHTML = ''; - - data.items.forEach(item => { - addItemToTable({ - id: item.item_id, - name_en: item.name_en, - name_ar: item.name_ar, - sku: '', - vat_rate: item.vat_rate || 0 - }, tableBody, null, null, - document.getElementById('edit_lpo_grand_display'), - document.getElementById('edit_lpo_subtotal_display'), - document.getElementById('edit_lpo_vat_display'), - { quantity: item.quantity, unit_price: item.unit_price }); - }); + if (lpoDateInput) lpoDateInput.value = data.lpo_date || ''; + if (deliveryDateInput) deliveryDateInput.value = data.delivery_date || ''; + if (statusSelect) statusSelect.value = data.status || 'pending'; + if (termsInput) termsInput.value = data.terms_conditions || ''; + + renderExistingDocumentItems(data.items || [], 'editLpoItemsTableBody', 'edit_lpo_grand_display', 'edit_lpo_subtotal_display', 'edit_lpo_vat_display'); }); }); @@ -182,29 +223,31 @@ document.querySelectorAll('.edit-quotation-btn').forEach(btn => { btn.addEventListener('click', function() { - const data = JSON.parse(this.dataset.json); - document.getElementById('edit_quotation_id').value = data.id; - document.getElementById('edit_quot_customer_id').value = data.customer_id; - document.getElementById('edit_quot_date').value = data.quotation_date; - document.getElementById('edit_quot_valid').value = data.valid_until || ''; - document.getElementById('edit_quot_status').value = data.status || 'pending'; - - const tableBody = document.getElementById('editQuotItemsTableBody'); - tableBody.innerHTML = ''; - - data.items.forEach(item => { - addItemToTable({ - id: item.item_id, - name_en: item.name_en, - name_ar: item.name_ar, - sku: '', - vat_rate: item.vat_rate || 0 - }, tableBody, null, null, - document.getElementById('edit_quot_grand_display'), - document.getElementById('edit_quot_subtotal_display'), - document.getElementById('edit_quot_vat_display'), - { quantity: item.quantity, unit_price: item.unit_price }); - }); + const data = parseLpoQuotationButtonPayload(this); + if (Object.keys(data).length === 0) return; + + const customerSelect = document.getElementById('edit_quot_customer_id'); + const customerId = data.customer_id ?? ''; + const customerLabel = data.customer_name || data.party_name || ''; + + invoiceEnsureSelectOption('edit_quot_customer_id', customerId, customerLabel); + + const quotationIdInput = document.getElementById('edit_quotation_id'); + const quotationDateInput = document.getElementById('edit_quot_date'); + const validUntilInput = document.getElementById('edit_quot_valid'); + const statusSelect = document.getElementById('edit_quot_status'); + + if (quotationIdInput) quotationIdInput.value = data.id || ''; + if (customerSelect) { + invoiceSetBlankSelectOptionLabel(customerSelect, (customerId === '' && customerLabel) ? customerLabel : '---'); + customerSelect.value = customerId; + invoiceSyncSelect2Value(customerSelect); + } + if (quotationDateInput) quotationDateInput.value = data.quotation_date || ''; + if (validUntilInput) validUntilInput.value = data.valid_until || ''; + if (statusSelect) statusSelect.value = data.status || 'pending'; + + renderExistingDocumentItems(data.items || [], 'editQuotItemsTableBody', 'edit_quot_grand_display', 'edit_quot_subtotal_display', 'edit_quot_vat_display'); }); }); @@ -355,10 +398,8 @@ editBtn.className = 'btn btn-primary'; editBtn.innerHTML = ' Edit'; editBtn.onclick = function() { - const editModal = new bootstrap.Modal(document.getElementById('editQuotationModal')); modal.hide(); - const originalEditBtn = document.querySelector(`.edit-quotation-btn[data-json*='"id":${data.id},']`) || - document.querySelector(`.edit-quotation-btn[data-json*='"id":${data.id}']`); + const originalEditBtn = document.querySelector(`.edit-quotation-btn[data-id="${data.id}"]`); if (originalEditBtn) originalEditBtn.click(); }; actionButtons.appendChild(editBtn); diff --git a/pages/sales_purchases_invoice_actions_script.php b/pages/sales_purchases_invoice_actions_script.php index fb6e408..8d3cf38 100644 --- a/pages/sales_purchases_invoice_actions_script.php +++ b/pages/sales_purchases_invoice_actions_script.php @@ -9,34 +9,6 @@ } }; - const syncSelect2Value = (select) => { - if (!select) return; - if (select.classList.contains('select2') && window.jQuery && jQuery.fn && jQuery.fn.select2) { - jQuery(select).trigger('change'); - } - }; - - const ensureSelectOption = (selectId, value, label = '') => { - const select = document.getElementById(selectId); - if (!select || value === null || value === undefined || String(value) === '') return; - - const alreadyExists = Array.from(select.options || []).some(option => option.value == String(value)); - if (!alreadyExists) { - const option = document.createElement('option'); - option.value = String(value); - option.textContent = label || String(value); - select.appendChild(option); - } - }; - - const setBlankSelectOptionLabel = (select, label = '---') => { - if (!select) return; - const emptyOption = Array.from(select.options || []).find(option => option.value === ''); - if (emptyOption) { - emptyOption.textContent = label; - } - }; - const normalizeEditPaymentType = (paymentType) => { let normalized = String(paymentType || 'cash').toLowerCase().replace(/[\s-]+/g, '_'); if (normalized === 'pos') normalized = 'cash'; @@ -92,13 +64,13 @@ const partyId = data.customer_id ?? data.supplier_id ?? ''; const partyLabel = data.party_name || data.customer_name || data.supplier_name || ''; - ensureSelectOption('edit_customer_id', partyId, partyLabel); + invoiceEnsureSelectOption('edit_customer_id', partyId, partyLabel); if (invoiceIdInput) invoiceIdInput.value = data.id || ''; if (partySelect) { - setBlankSelectOptionLabel(partySelect, (partyId === '' && partyLabel) ? partyLabel : '---'); + invoiceSetBlankSelectOptionLabel(partySelect, (partyId === '' && partyLabel) ? partyLabel : '---'); partySelect.value = partyId; - syncSelect2Value(partySelect); + invoiceSyncSelect2Value(partySelect); } if (invoiceDateInput) invoiceDateInput.value = data.invoice_date || ''; if (dueDateInput) dueDateInput.value = data.due_date || ''; diff --git a/pages/sales_purchases_invoice_form_helpers.php b/pages/sales_purchases_invoice_form_helpers.php index 45b3cf4..f2bd2f1 100644 --- a/pages/sales_purchases_invoice_form_helpers.php +++ b/pages/sales_purchases_invoice_form_helpers.php @@ -53,6 +53,100 @@ }); }; + + const invoiceSyncSelect2Value = (select) => { + if (!select) return; + if (select.classList.contains('select2') && window.jQuery && window.jQuery.fn && window.jQuery.fn.select2) { + window.jQuery(select).trigger('change'); + } + }; + + const invoiceEnsureSelectOption = (selectId, value, label = '') => { + const select = document.getElementById(selectId); + if (!select || value === null || value === undefined || String(value) === '') return; + + const alreadyExists = Array.from(select.options || []).some(option => option.value == String(value)); + if (!alreadyExists) { + const option = document.createElement('option'); + option.value = String(value); + option.textContent = label || String(value); + select.appendChild(option); + } + }; + + const invoiceSetBlankSelectOptionLabel = (select, label = '---') => { + if (!select) return; + const emptyOption = Array.from(select.options || []).find(option => option.value === ''); + if (emptyOption) { + emptyOption.textContent = label; + } + }; + + const invoiceShowConfirmDialog = async ({ + title = 'Are you sure?', + text = '', + confirmButtonText = 'Yes, continue', + cancelButtonText = 'Cancel', + icon = 'warning' + } = {}) => { + if (window.Swal) { + const result = await Swal.fire({ + title, + text, + icon, + showCancelButton: true, + confirmButtonText, + cancelButtonText, + reverseButtons: true, + focusCancel: true, + confirmButtonColor: '#dc3545', + cancelButtonColor: '#6c757d' + }); + return !!result.isConfirmed; + } + + return window.confirm(text ? `${title} + +${text}` : title); + }; + + const bindInvoiceSweetConfirmForms = () => { + document.querySelectorAll('.js-swal-confirm-form').forEach(form => { + if (form.dataset.confirmBound === '1') return; + form.dataset.confirmBound = '1'; + + form.addEventListener('submit', async function(event) { + if (form.dataset.skipConfirm === '1') { + delete form.dataset.skipConfirm; + return; + } + + event.preventDefault(); + + const confirmed = await invoiceShowConfirmDialog({ + title: form.dataset.confirmTitle || 'Are you sure?', + text: form.dataset.confirmText || '', + confirmButtonText: form.dataset.confirmButton || 'Yes, continue', + cancelButtonText: form.dataset.cancelButton || 'Cancel', + icon: form.dataset.confirmIcon || 'warning' + }); + + if (!confirmed) return; + + const submitter = event.submitter || null; + if (submitter && typeof form.requestSubmit === 'function') { + form.dataset.skipConfirm = '1'; + form.requestSubmit(submitter); + return; + } + + HTMLFormElement.prototype.submit.call(form); + }); + }); + }; + + bindInvoiceSweetConfirmForms(); + function addItemToTable(item, tableBody, searchInput, suggestions, grandTotalEl, subtotalEl, totalVatEl, customData = null) { if (suggestions) suggestions.style.display = 'none'; if (searchInput) searchInput.value = ''; diff --git a/pages/sales_purchases_page_script.php b/pages/sales_purchases_page_script.php index 83f6f17..c242ecd 100644 --- a/pages/sales_purchases_page_script.php +++ b/pages/sales_purchases_page_script.php @@ -1,6 +1,5 @@ " data-total="" data-paid="" data-bs-toggle="modal" data-bs-target="#payInvoiceModal" title="Payment"> -
+ - + +