38471-vm/pages/sales_purchases_invoice_actions_script.php
2026-05-03 13:09:07 +00:00

121 lines
5.3 KiB
PHP

// 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 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 || '';
invoiceEnsureSelectOption('edit_customer_id', partyId, partyLabel);
if (invoiceIdInput) invoiceIdInput.value = data.id || '';
if (partySelect) {
invoiceSetBlankSelectOptionLabel(partySelect, (partyId === '' && partyLabel) ? partyLabel : '---');
partySelect.value = partyId;
invoiceSyncSelect2Value(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 = '<tr><td colspan="6" class="text-center"><div class="spinner-border spinner-border-sm text-primary"></div> <span data-en="Loading invoice..." data-ar="جاري تحميل الفاتورة...">Loading invoice...</span></td></tr>';
}
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