/** * report-helpers.js — geteilte Bausteine der Report-/Accounting-Views * * Extrahiert aus accounting-view.js im Zuge der UI-Reorganisation * (Reports und Sales Tax haben eigene Tabs bekommen). Inhaltlich 1:1 * übernommen — einzige Ausnahme ist showError, das den Fehlertitel jetzt * als Parameter bekommt, damit "QBO Error" und "Report Error" beide * erhalten bleiben. * * Genutzt von: accounting-view.js, reports-view.js, salestax-view.js */ // ── Formatierung ──────────────────────────────────────────────────── /** * Accounting-Variante, um eine Number()-Koersion ergänzt. * * Das Original rief toLocaleString direkt auf dem Argument auf. Bei einer * Zahl korrekt — bei einem String greift aber String.prototype.toLocaleString, * das die Optionen ignoriert und den Rohwert zurückgibt ("19152.81" statt * "$19,152.81"). accounting-view.js übergibt ausschließlich Zahlen und war * davon nie betroffen; reports-view.js übergibt numeric-Strings vom * pg-Treiber und hätte sonst still unformatierte Beträge angezeigt. * Für Zahl-Eingaben ist die Ausgabe unverändert. */ export function fmtMoney(n) { if (n == null || n === '' || isNaN(n)) return ''; return Number(n).toLocaleString('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2, maximumFractionDigits: 2 }); } export function escapeHtml(s) { if (s == null) return ''; return String(s) .replace(/&/g, '&').replace(//g, '>') .replace(/"/g, '"').replace(/'/g, '''); } // ── Datums-Helfer ─────────────────────────────────────────────────── export function todayISO() { return new Date().toISOString().split('T')[0]; } export function firstOfMonthISO(year, month) { const d = year != null ? new Date(year, month, 1) : new Date(); return year != null ? d.toISOString().split('T')[0] : new Date(d.getFullYear(), d.getMonth(), 1).toISOString().split('T')[0]; } export function lastOfMonthISO(year, month) { const d = year != null ? new Date(year, month + 1, 0) : new Date(); return year != null ? d.toISOString().split('T')[0] : new Date(d.getFullYear(), d.getMonth() + 1, 0).toISOString().split('T')[0]; } export function prevMonthISO() { const d = new Date(); const m = d.getMonth() === 0 ? 11 : d.getMonth() - 1; const y = d.getMonth() === 0 ? d.getFullYear() - 1 : d.getFullYear(); return `${y}-${String(m + 1).padStart(2, '0')}`; } export function firstOfYearISO() { const d = new Date(); return new Date(d.getFullYear(), 0, 1).toISOString().split('T')[0]; } // ── Statusanzeigen ────────────────────────────────────────────────── /** * @param {string} title Überschrift der Fehlerbox — "QBO Error" im * Accounting-/Sales-Tax-Kontext, "Report Error" auf dem Reports-Tab. */ export function showError(slotId, message, title = 'QBO Error') { const el = document.getElementById(slotId); if (!el) return; el.innerHTML = `
${escapeHtml(title)}
${escapeHtml(message)}
No report data.
`; const cols = (report.Columns && report.Columns.Column) || []; const headerRow = cols.map(c => `