// Edit Invoice Logic const parseInvoiceButtonPayload = (btn) => { if (!btn || !btn.dataset || !btn.dataset.json) return {}; try { return JSON.parse(btn.dataset.json); } catch (error) { console.warn('Failed to parse invoice payload from button data.', error); return {}; } }; 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'; if (!['cash', 'card', 'bank_transfer', 'credit'].includes(normalized)) { normalized = 'cash'; } return normalized; }; const renderEditInvoiceItems = (items) => { const tableBody = document.getElementById('editInvoiceItemsTableBody'); const grandTotalEl = document.getElementById('edit_grandTotal'); const subtotalEl = document.getElementById('edit_subtotal'); const totalVatEl = document.getElementById('edit_totalVat'); 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 }); }); }; const populateEditInvoiceModal = (data) => { if (!data) return; const invoiceIdInput = document.getElementById('edit_invoice_id'); const partySelect = document.getElementById('edit_customer_id'); const invoiceDateInput = document.getElementById('edit_invoice_date'); const dueDateInput = document.getElementById('edit_due_date'); const paymentTypeSelect = document.getElementById('edit_payment_type'); const statusSelect = document.getElementById('edit_status'); const paidAmountInput = document.getElementById('edit_paid_amount'); const paidAmountContainer = document.getElementById('editPaidAmountContainer'); 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); if (invoiceIdInput) invoiceIdInput.value = data.id || ''; if (partySelect) { setBlankSelectOptionLabel(partySelect, (partyId === '' && partyLabel) ? partyLabel : '---'); partySelect.value = partyId; syncSelect2Value(partySelect); } if (invoiceDateInput) invoiceDateInput.value = data.invoice_date || ''; if (dueDateInput) dueDateInput.value = data.due_date || ''; if (paymentTypeSelect) paymentTypeSelect.value = normalizeEditPaymentType(data.payment_type); if (statusSelect) statusSelect.value = data.status || 'unpaid'; if (paidAmountInput) paidAmountInput.value = parseFloat(data.paid_amount || 0).toFixed(3); if (paidAmountContainer) { paidAmountContainer.style.display = data.status === 'partially_paid' ? 'block' : 'none'; } renderEditInvoiceItems(data.items || []); }; document.querySelectorAll('.edit-invoice-btn').forEach(btn => { btn.addEventListener('click', async function() { const fallbackData = parseInvoiceButtonPayload(this); const invoiceId = this.dataset.id || fallbackData.id || ''; const type = this.dataset.type || fallbackData.type || invoiceType || 'sale'; const tableBody = document.getElementById('editInvoiceItemsTableBody'); if (Object.keys(fallbackData).length > 0) { populateEditInvoiceModal(fallbackData); } else if (tableBody) { tableBody.innerHTML = '
Loading invoice...'; } if (!invoiceId) return; try { const resp = await fetch(`index.php?action=get_invoice_details&invoice_id=${encodeURIComponent(invoiceId)}&type=${encodeURIComponent(type)}`); const data = await resp.json(); if (data && data.id) { populateEditInvoiceModal(data); } else if (data && data.error) { throw new Error(data.error); } } catch (error) { console.error('Failed to load invoice details for edit modal.', error); if (window.Swal) { Swal.fire('Error', 'Failed to load invoice details', 'error'); } } }); }); // View and Print Invoice Logic