new message for overdue

This commit is contained in:
2026-03-25 15:42:51 -05:00
parent cc154141bd
commit acd5b7d605
2 changed files with 44 additions and 23 deletions

View File

@@ -2,7 +2,7 @@
// Modal to review and send invoice emails via AWS SES // Modal to review and send invoice emails via AWS SES
// With Stripe Payment Link integration // With Stripe Payment Link integration
import { showSpinner, hideSpinner } from '../utils/helpers.js'; import { showSpinner, hideSpinner, formatDate } from '../utils/helpers.js';
let currentInvoice = null; let currentInvoice = null;
let quillInstance = null; let quillInstance = null;
@@ -118,6 +118,7 @@ function renderModalContent() {
// Variablen für den Text aufbereiten // Variablen für den Text aufbereiten
const invoiceNum = currentInvoice.invoice_number || currentInvoice.id; const invoiceNum = currentInvoice.invoice_number || currentInvoice.id;
const totalDue = parseFloat(currentInvoice.balance ?? currentInvoice.total).toFixed(2); const totalDue = parseFloat(currentInvoice.balance ?? currentInvoice.total).toFixed(2);
const customerName = currentInvoice.customer_name || 'Valued Customer';
// Datum formatieren // Datum formatieren
let dueDateStr = 'Upon Receipt'; let dueDateStr = 'Upon Receipt';
@@ -135,17 +136,46 @@ function renderModalContent() {
} else { } else {
paymentText = 'Our terms are Net 30.'; paymentText = 'Our terms are Net 30.';
} }
const customerName = currentInvoice.customer_name || 'Valued Customer';
const defaultHtml = ` // Detect overdue: unpaid + older than 30 days
<p>Dear ${customerName},</p> const invoiceDateParsed = currentInvoice.invoice_date
<p>Attached is invoice <strong>#${invoiceNum}</strong> for service performed at your location. The total amount due is <strong>$${totalDue}</strong>, ${paymentText}</p> ? new Date(currentInvoice.invoice_date.split('T')[0])
<p>Please pay at your earliest convenience. We appreciate your continued business.</p> : null;
<p>If you have any questions about the invoice, feel free to reply to this email.</p> const daysSinceInvoice = invoiceDateParsed
<p>Best regards,</p> ? Math.floor((new Date() - invoiceDateParsed) / 86400000)
<p><strong>Claudia Knuth</strong></p> : 0;
<p>Bay Area Affiliates, Inc.</p> const isOverdue = !currentInvoice.paid_date && daysSinceInvoice > 30;
<p>accounting@bayarea-cc.com</p>
`; let defaultHtml = '';
if (isOverdue) {
// Reminder / Overdue template
defaultHtml = `
<p>Dear ${customerName},</p>
<p>We hope this message finds you well. Our records indicate that invoice <strong>#${invoiceNum}</strong> in the amount of <strong>$${totalDue}</strong>, dated ${formatDate(currentInvoice.invoice_date)}, remains unpaid.</p>
<p>This invoice is now <strong>${daysSinceInvoice} days past the invoice date</strong>. We kindly request prompt payment at your earliest convenience.</p>
<p>For your convenience, you can pay securely online using the payment link included below. We accept both Credit Card and ACH bank transfer.</p>
<p>If payment has already been sent, please disregard this notice. Should you have any questions or need to discuss payment arrangements, please do not hesitate to reply to this email.</p>
<p>Thank you for your attention to this matter. We value your business and look forward to continuing our partnership.</p>
<p>Best regards,</p>
<p><strong>Claudia Knuth</strong></p>
<p>Bay Area Affiliates, Inc.</p>
<p>accounting@bayarea-cc.com</p>
`;
} else {
// Standard template
defaultHtml = `
<p>Dear ${customerName},</p>
<p>Attached is invoice <strong>#${invoiceNum}</strong> for service performed at your location. The total amount due is <strong>$${totalDue}</strong>, ${paymentText}</p>
<p>Please pay at your earliest convenience. We appreciate your continued business.</p>
<p>If you have any questions about the invoice, feel free to reply to this email.</p>
<p>Best regards,</p>
<p><strong>Claudia Knuth</strong></p>
<p>Bay Area Affiliates, Inc.</p>
<p>accounting@bayarea-cc.com</p>
`;
}
quillInstance.root.innerHTML = defaultHtml; quillInstance.root.innerHTML = defaultHtml;
// Bind Submit Handler // Bind Submit Handler

View File

@@ -269,19 +269,10 @@ function renderInvoiceRow(invoice) {
if (hasQbo && !paid && !overdue && invoice.email_status !== 'sent') { if (hasQbo && !paid && !overdue && invoice.email_status !== 'sent') {
sendBtn = `<button onclick="window.invoiceView.setEmailStatus(${invoice.id}, 'sent')" class="text-indigo-600 hover:text-indigo-800 text-xs font-medium" title="Mark as sent to customer">📤 Mark Sent</button>`; sendBtn = `<button onclick="window.invoiceView.setEmailStatus(${invoice.id}, 'sent')" class="text-indigo-600 hover:text-indigo-800 text-xs font-medium" title="Mark as sent to customer">📤 Mark Sent</button>`;
} }
// if (hasQbo && !paid && !overdue) {
// sendBtn = `
// <button onclick="window.invoiceView.setEmailStatus(${invoice.id}, 'sent')" class="text-gray-600 hover:text-gray-900 text-xs font-medium mr-4" title="Nur Status ändern">
// ✔️ Mark Sent
// </button>
// <button onclick="window.emailModal.open(${invoice.id})" class="text-indigo-600 hover:text-indigo-800 text-xs font-medium" title="E-Mail via SES versenden">
// 📧 Send Email
// </button>
// `; }
const delBtn = `<button onclick="window.invoiceView.remove(${invoice.id})" class="text-red-600 hover:text-red-900">Del</button>`; const delBtn = `<button onclick="window.invoiceView.remove(${invoice.id})" class="text-red-600 hover:text-red-900">Del</button>`;
const stripeEmailBtn = (hasQbo && !paid && !overdue && invoice.email_status !== 'sent') const stripeEmailBtn = (hasQbo && !paid && (invoice.email_status !== 'sent' || ((invoice.email_status === 'sent' && overdue))))
? `<button onclick="window.emailModal.open(${invoice.id})" title="Email with Stripe Payment Link" class="px-2 py-1 bg-purple-100 text-purple-700 rounded hover:bg-purple-200 text-xs font-semibold">💳 Pay Link</button>` ? `<button onclick="window.emailModal.open(${invoice.id})" title="Email with Stripe Payment Link" class="px-2 py-1 bg-purple-100 text-purple-700 rounded hover:bg-purple-200 text-xs font-semibold">💳 Pay Link</button>`
: ''; : '';