EMAILOUT / frontend /src /lib /wonBillingEmailFormat.js
Seth
update
00a69e6
/**
* Matches backend/app/main.py helpers used in _notify_tenant_admins_deal_won (won-deal email body).
*/
export function wonCurrencyLabel(raw) {
const c = String(raw || 'USD').trim().toUpperCase();
return c === 'CAD' ? 'CAD' : 'USD';
}
export function fmtWonMoney(amount, currencyRaw) {
const lab = wonCurrencyLabel(currencyRaw);
const sym = lab === 'CAD' ? 'CA$' : '$';
let n = Number(amount);
if (!Number.isFinite(n)) n = 0;
const s = n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
return `${sym}${s} ${lab}`;
}
export function wonBillingIntervalLabel(raw) {
const s = String(raw || 'monthly').trim().toLowerCase();
if (['one_time', 'onetime', 'one-time', 'non-recurring'].includes(s)) return 'One-time';
if (['quarterly', 'quarter', 'every 3 months'].includes(s)) return 'Every 3 months';
if (['annual', 'year', 'yearly', 'every year'].includes(s)) return 'Every year';
return 'Every month';
}
/** Python {:g}-style qty for line display */
export function fmtQtyG(qf) {
if (!Number.isFinite(qf)) return '0';
return Number.isInteger(qf) ? String(qf) : String(qf);
}
/**
* One numbered line item line, same text as the admin email (excluding leading newline).
*/
export function wonEmailLineItemBodyLine(index1, li) {
const ps = String(li.product_service || '').trim();
const cur = wonCurrencyLabel(li.currency);
let qf = Number(li.qty);
let rf = Number(li.rate);
let af = Number(li.amount);
if (!Number.isFinite(qf)) qf = 0;
if (!Number.isFinite(rf)) rf = 0;
if (!Number.isFinite(af)) af = 0;
const cadence = wonBillingIntervalLabel(li.billing_interval);
return ` ${index1}. ${ps} | ${cadence} | Qty ${fmtQtyG(qf)} × ${fmtWonMoney(rf, cur)} = ${fmtWonMoney(af, cur)}`;
}
export function wonEmailSubtotalLine(lines, subtotal) {
const st = Number(subtotal);
const sum = Number.isFinite(st) ? st : 0;
if (!lines?.length) {
return `Subtotal: ${sum.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}
const distinct = new Set(lines.map((li) => wonCurrencyLabel(li.currency)));
if (distinct.size === 1) {
const only = distinct.values().next().value;
return `Subtotal: ${fmtWonMoney(sum, only)}`;
}
return `Subtotal (numeric sum of line amounts; USD and CAD lines are not converted between currencies): ${sum.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}