sent,mark sent

This commit is contained in:
2026-02-24 17:13:27 -06:00
parent ec3cd2b659
commit 73b869e2d9
2 changed files with 95 additions and 4 deletions

View File

@@ -239,6 +239,17 @@ function renderInvoiceRow(invoice) {
paidBtn = `<button onclick="window.paymentModal.open([${invoice.id}])" class="text-emerald-600 hover:text-emerald-800" title="Record Payment in QBO">💰 Payment</button>`;
}
// Send status button — only for QBO invoices
let sendBtn = '';
if (hasQbo && !paid) {
const isSent = invoice.email_status === 'sent';
if (isSent) {
sendBtn = `<button onclick="window.invoiceView.setEmailStatus(${invoice.id}, 'open')" class="text-gray-400 hover:text-gray-600 text-xs" title="Mark as not sent">✉️ Sent</button>`;
} else {
sendBtn = `<button onclick="window.invoiceView.setEmailStatus(${invoice.id}, 'sent')" class="text-indigo-600 hover:text-indigo-800 text-xs" title="Mark as sent to customer">📤 Mark Sent</button>`;
}
}
const delBtn = `<button onclick="window.invoiceView.remove(${invoice.id})" class="text-red-600 hover:text-red-900">Del</button>`;
const rowClass = paid ? (invoice.payment_status === 'Deposited' ? 'bg-blue-50/50' : 'bg-green-50/50') : partial ? 'bg-yellow-50/30' : overdue ? 'bg-red-50/50' : '';
@@ -252,7 +263,7 @@ function renderInvoiceRow(invoice) {
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">${invoice.terms}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-900 font-semibold">${amountDisplay}</td>
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium space-x-1">
${editBtn} ${qboBtn} ${pdfBtn} ${htmlBtn} ${paidBtn} ${delBtn}
${editBtn} ${qboBtn} ${pdfBtn} ${htmlBtn} ${sendBtn} ${paidBtn} ${delBtn}
</td>
</tr>`;
}
@@ -440,6 +451,23 @@ export async function syncFromQBO() {
finally { if (typeof hideSpinner === 'function') hideSpinner(); }
}
export async function setEmailStatus(id, status) {
const label = status === 'sent' ? 'Mark as sent' : 'Mark as not sent';
if (!confirm(`${label}?`)) return;
if (typeof showSpinner === 'function') showSpinner(`Updating status in QBO...`);
try {
const r = await fetch(`/api/invoices/${id}/email-status`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ status })
});
const d = await r.json();
if (r.ok) loadInvoices();
else alert(`${d.error}`);
} catch (e) { alert('Network error.'); }
finally { if (typeof hideSpinner === 'function') hideSpinner(); }
}
export async function resetQbo(id) {
if (!confirm('Reset QBO link?\nInvoice must be deleted in QBO first!')) return;
try {
@@ -471,6 +499,6 @@ export async function remove(id) {
// ============================================================
window.invoiceView = {
viewPDF, viewHTML, exportToQBO, syncToQBO, syncFromQBO, resetQbo, markPaid, edit, remove,
viewPDF, viewHTML, syncFromQBO, resetQbo, markPaid, setEmailStatus, edit, remove,
loadInvoices, renderInvoiceView, setStatus
};