/** * Auto-calculates invoice Due Date from Invoice Date + Payment Terms. * Parses common terms formats: "Net 30", "N/15", "Due on Receipt", "COD", "2% 10 Net 30". * Only fires when Terms or Invoice Date changes; user can always override the Due Date field. */ (function () { /// /// Extracts the net payment days from a free-text terms string. /// Returns null when the string can't be parsed (due date is left unchanged). /// function parseDays(terms) { if (!terms || !terms.trim()) return null; const t = terms.trim().toLowerCase(); if (/\b(receipt|due\s*now|cod|immediate)\b/.test(t)) return 0; // "Net N" or "N/N" (e.g., "2% 10 Net 30" or "N/30") let m = t.match(/\bnet\s+(\d+)/) || t.match(/\bn\/(\d+)/); if (m) return parseInt(m[1], 10); // Plain number (e.g., "30 days", "30") m = t.match(/\b(\d+)\b/); if (m) return parseInt(m[1], 10); return null; } function recalcDueDate() { const termsEl = document.getElementById('Terms'); const invoiceDateEl = document.getElementById('InvoiceDate'); const dueDateEl = document.getElementById('DueDate'); if (!termsEl || !invoiceDateEl || !dueDateEl) return; const days = parseDays(termsEl.value); if (days === null) return; const rawDate = invoiceDateEl.value; if (!rawDate) return; // Parse as local date to avoid UTC-offset shifting the day const [y, mo, d] = rawDate.split('-').map(Number); const due = new Date(y, mo - 1, d + days); const yyyy = due.getFullYear(); const mm = String(due.getMonth() + 1).padStart(2, '0'); const dd = String(due.getDate()).padStart(2, '0'); dueDateEl.value = `${yyyy}-${mm}-${dd}`; } document.addEventListener('DOMContentLoaded', function () { const termsEl = document.getElementById('Terms'); const invoiceDateEl = document.getElementById('InvoiceDate'); if (termsEl) { termsEl.addEventListener('change', recalcDueDate); termsEl.addEventListener('blur', recalcDueDate); } if (invoiceDateEl) { invoiceDateEl.addEventListener('change', recalcDueDate); } }); })();