update
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
// payment-modal.js — ES Module v3
|
||||
// Invoice payments only: multi-invoice, partial, editable amounts
|
||||
// Downpayment is handled separately in customer view
|
||||
// payment-modal.js — ES Module v3 (clean)
|
||||
// Invoice payments: multi-invoice, partial, overpay
|
||||
// No downpayment functionality
|
||||
|
||||
let bankAccounts = [];
|
||||
let paymentMethods = [];
|
||||
let selectedInvoices = []; // { invoice, payAmount }
|
||||
let customerCredit = 0; // Unapplied credit from QBO
|
||||
let dataLoaded = false;
|
||||
|
||||
// ============================================================
|
||||
@@ -32,7 +31,6 @@ async function loadQboData() {
|
||||
export async function openPaymentModal(invoiceIds = []) {
|
||||
await loadQboData();
|
||||
selectedInvoices = [];
|
||||
customerCredit = 0;
|
||||
|
||||
for (const id of invoiceIds) {
|
||||
try {
|
||||
@@ -47,18 +45,6 @@ export async function openPaymentModal(invoiceIds = []) {
|
||||
} catch (e) { console.error('Error loading invoice:', id, e); }
|
||||
}
|
||||
|
||||
// Check customer credit if we have invoices
|
||||
if (selectedInvoices.length > 0) {
|
||||
const custQboId = selectedInvoices[0].invoice.customer_qbo_id;
|
||||
if (custQboId) {
|
||||
try {
|
||||
const res = await fetch(`/api/qbo/customer-credit/${custQboId}`);
|
||||
const data = await res.json();
|
||||
customerCredit = data.credit || 0;
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
}
|
||||
|
||||
ensureModalElement();
|
||||
renderModalContent();
|
||||
document.getElementById('payment-modal').classList.add('active');
|
||||
@@ -68,7 +54,6 @@ export function closePaymentModal() {
|
||||
const modal = document.getElementById('payment-modal');
|
||||
if (modal) modal.classList.remove('active');
|
||||
selectedInvoices = [];
|
||||
customerCredit = 0;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
@@ -146,22 +131,10 @@ function renderModalContent() {
|
||||
|
||||
const accountOptions = bankAccounts.map(a => `<option value="${a.id}">${a.name}</option>`).join('');
|
||||
const filtered = paymentMethods.filter(p => /check|ach/i.test(p.name));
|
||||
const methods = (filtered.length > 0 ? filtered : paymentMethods);
|
||||
const methods = filtered.length > 0 ? filtered : paymentMethods;
|
||||
const methodOptions = methods.map(p => `<option value="${p.id}">${p.name}</option>`).join('');
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
|
||||
// Credit banner
|
||||
let creditBanner = '';
|
||||
if (customerCredit > 0) {
|
||||
creditBanner = `
|
||||
<div class="bg-green-50 border border-green-200 rounded-lg p-3 mb-4">
|
||||
<p class="text-sm text-green-800">
|
||||
💰 <strong>Customer has $${customerCredit.toFixed(2)} unapplied credit.</strong>
|
||||
This can be applied in QBO when processing the payment.
|
||||
</p>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
modal.innerHTML = `
|
||||
<div class="bg-white rounded-lg shadow-2xl w-full max-w-2xl mx-auto p-8">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
@@ -173,8 +146,6 @@ function renderModalContent() {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
${creditBanner}
|
||||
|
||||
<!-- Invoice List -->
|
||||
<div class="mb-6">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-2">Invoices</label>
|
||||
@@ -285,13 +256,11 @@ function updateTotal() {
|
||||
|
||||
const payTotal = selectedInvoices.reduce((s, si) => s + si.payAmount, 0);
|
||||
const invTotal = selectedInvoices.reduce((s, si) => s + parseFloat(si.invoice.total), 0);
|
||||
|
||||
totalEl.textContent = `$${payTotal.toFixed(2)}`;
|
||||
|
||||
if (noteEl) {
|
||||
if (payTotal > invTotal && invTotal > 0) {
|
||||
const overpay = payTotal - invTotal;
|
||||
noteEl.textContent = `⚠️ Overpayment of $${overpay.toFixed(2)} will be stored as customer credit in QBO.`;
|
||||
noteEl.textContent = `⚠️ Overpayment of $${(payTotal - invTotal).toFixed(2)} will be stored as customer credit in QBO.`;
|
||||
noteEl.classList.remove('hidden');
|
||||
} else {
|
||||
noteEl.classList.add('hidden');
|
||||
@@ -336,7 +305,6 @@ async function submitPayment() {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
mode: 'invoice',
|
||||
invoice_payments: selectedInvoices.map(si => ({
|
||||
invoice_id: si.invoice.id,
|
||||
amount: si.payAmount
|
||||
|
||||
Reference in New Issue
Block a user