// Edit Invoice Logic document.querySelectorAll('.edit-invoice-btn').forEach(btn => { btn.addEventListener('click', function() { const data = JSON.parse(this.dataset.json); document.getElementById('edit_invoice_id').value = data.id; document.getElementById('edit_customer_id').value = data.customer_id; document.getElementById('edit_invoice_date').value = data.invoice_date; document.getElementById('edit_due_date').value = data.due_date || ''; document.getElementById('edit_payment_type').value = data.payment_type || 'cash'; document.getElementById('edit_status').value = data.status || 'unpaid'; document.getElementById('edit_paid_amount').value = parseFloat(data.paid_amount || 0).toFixed(3); if (data.status === 'partially_paid') { document.getElementById('editPaidAmountContainer').style.display = 'block'; } else { document.getElementById('editPaidAmountContainer').style.display = 'none'; } const tableBody = document.getElementById('editInvoiceItemsTableBody'); tableBody.innerHTML = ''; data.items.forEach(item => { // We need more data than what's in invoice_items (like SKU and names, but we have them from the join in PHP) // The dataset-json already contains name_en, name_ar etc because of the PHP logic at line 1093 const itemMeta = { id: item.item_id, name_en: item.name_en, name_ar: item.name_ar, sku: '', // Optional, or fetch if needed vat_rate: 0 // Will be handled if we have it in the join }; // Fetch current item details to get VAT rate if possible, or use stored if available // For simplicity, let's assume we want to use the item's current VAT rate or store it. // Looking at the join at line 1093, it doesn't fetch vat_rate. Let's fix that in PHP too. addItemToTable({ id: item.item_id, name_en: item.name_en, name_ar: item.name_ar, sku: '', vat_rate: item.vat_rate || 0 // We'll add this to PHP join }, tableBody, null, null, document.getElementById('edit_grandTotal'), document.getElementById('edit_subtotal'), document.getElementById('edit_totalVat'), { quantity: item.quantity, unit_price: item.unit_price }); }); }); }); // View and Print Invoice Logic document.addEventListener('click', function(e) { if (e.target.closest('.view-invoice-btn')) { const btn = e.target.closest('.view-invoice-btn'); const data = JSON.parse(btn.dataset.json); if (window.viewAndPrintA4Invoice) { window.viewAndPrintA4Invoice(data, false); } } if (e.target.closest('.print-a4-btn')) { const btn = e.target.closest('.print-a4-btn'); const data = JSON.parse(btn.dataset.json); if (window.viewAndPrintA4Invoice) { window.viewAndPrintA4Invoice(data, true); } } }); // Return Logic (General for Sales and Purchase) const setupReturnLogic = (selectId, containerId, tbodyId, totalDisplayId, submitBtnId, type = "sale") => { const select = document.getElementById(selectId); if (!select) return; const calculateTotal = function() { let total = 0; document.querySelectorAll('#' + tbodyId + ' tr').forEach(row => { const qtyInput = row.querySelector('.return-qty-input'); if (!qtyInput) return; const qty = parseFloat(qtyInput.value) || 0; const price = parseFloat(qtyInput.dataset.price) || 0; const lineTotal = qty * price; const lineTotalDisplay = row.querySelector('.line-total'); if (lineTotalDisplay) { lineTotalDisplay.innerText = lineTotal.toFixed(3); } total += lineTotal; }); const totalDisplay = document.getElementById(totalDisplayId); if (totalDisplay) { totalDisplay.innerText = 'OMR ' + total.toFixed(3); } const submitBtn = document.getElementById(submitBtnId); if (submitBtn) { submitBtn.disabled = total <= 0; } }; const handleInvoiceChange = async function() { const invoiceId = select.value; const container = document.getElementById(containerId); const tbody = document.getElementById(tbodyId); const submitBtn = document.getElementById(submitBtnId); if (!invoiceId) { if (container) container.style.display = 'none'; if (submitBtn) submitBtn.disabled = true; return; } if (tbody) { tbody.innerHTML = '
Loading items...'; } if (container) container.style.display = 'block'; try { const resp = await fetch(`index.php?action=get_invoice_items&invoice_id=${invoiceId}&type=${type}`); const items = await resp.json(); if (tbody) { tbody.innerHTML = ''; if (items.length === 0) { tbody.innerHTML = 'No items found for this invoice.'; } else { let html = ''; items.forEach(item => { html += ` ${item.name_en}
${item.sku} ${parseFloat(item.quantity).toFixed(2)} ${parseFloat(item.unit_price).toFixed(3)} 0.000 `; }); tbody.innerHTML = html; } } if (submitBtn) submitBtn.disabled = true; const qtyInputs = tbody.querySelectorAll('.return-qty-input'); qtyInputs.forEach(input => { ['input', 'change', 'keyup'].forEach(evt => input.addEventListener(evt, calculateTotal)); }); calculateTotal(); } catch (e) { console.error(e); if (window.Swal) Swal.fire('Error', 'Failed to fetch invoice items', 'error'); } }; select.addEventListener('change', handleInvoiceChange); if (window.jQuery && jQuery.fn.select2) { $(select).on('select2:select change', handleInvoiceChange); } }; setupReturnLogic('return_invoice_select', 'return_items_container', 'return_items_tbody', 'return_total_display', 'submit_return_btn', 'sale'); setupReturnLogic('purchase_return_invoice_select', 'purchase_return_items_container', 'purchase_return_items_tbody', 'purchase_return_total_display', 'purchase_submit_return_btn', 'purchase'); // Return Invoice Button from Sales/Purchases list document.querySelectorAll('.return-invoice-btn').forEach(btn => { btn.addEventListener('click', function() { const invoiceId = this.dataset.id; const targetModal = this.dataset.bsTarget; const selectId = targetModal === '#addSalesReturnModal' ? 'return_invoice_select' : 'purchase_return_invoice_select'; const select = document.getElementById(selectId); if (select) { $(select).val(invoiceId).trigger('change'); } }); }); // View Return Logic document.querySelectorAll('.view-return-btn').forEach(btn => { btn.addEventListener('click', async function() { const returnId = this.dataset.id; const type = ''; const modal = new bootstrap.Modal(document.getElementById('viewReturnDetailsModal')); try { const resp = await fetch(`index.php?action=get_return_details&return_id=${returnId}&type=${type}`); const data = await resp.json(); if (data) { document.getElementById('view_return_no').innerText = (type === 'purchase' ? 'PRET-' : 'SRET-') + String(data.id).padStart(5, '0'); document.getElementById('view_return_party').innerText = data.party_name; document.getElementById('view_return_date').innerText = data.return_date; const refId = data.purchase_id || data.invoice_id; const refPrefix = type === 'purchase' ? 'PUR-' : 'INV-'; document.getElementById('view_return_invoice').innerText = refPrefix + String(refId).padStart(5, '0'); document.getElementById('view_return_total').innerText = 'OMR ' + parseFloat(data.total_amount).toFixed(3); document.getElementById('view_return_notes').innerText = data.notes || 'No notes'; let itemsHtml = ''; data.items.forEach(item => { itemsHtml += ` ${item.name_en}
${item.sku} ${parseFloat(item.quantity).toFixed(2)} ${parseFloat(item.unit_price).toFixed(3)} ${parseFloat(item.total_price).toFixed(3)} `; }); document.getElementById('view_return_items_tbody').innerHTML = itemsHtml; modal.show(); } } catch (e) { console.error(e); Swal.fire('Error', 'Failed to fetch return details', 'error'); } }); });