Financial Control Dashboard

Monthly Overview for

Budget vs. Actual

Accounts Receivable Aging

Accounts Payable Aging

Top Overdue Invoices (AR)

Top Upcoming Bills (AP)

Monthly Budget

CategoryAmount

Transactions

CategoryAmountType

Actual Expenses

${formatCurrency(expenses)}

Net Income

${formatCurrency(netIncome)}

Net Cash Flow

$0

`; // Simplified cash flow }; renderCharts = (txns) => { const actualsByCategory = txns.reduce((acc, t) => { acc[t.category] = (acc[t.category]||0) + t.amount; return acc; }, {}); const budgetLabels = Object.keys(budget); renderChart('fc-budget-chart', 'bar', { labels: budgetLabels, datasets: [{ label: 'Budgeted', data: budgetLabels.map(l => budget[l]), backgroundColor: '#94a3b8' }, { label: 'Actual', data: budgetLabels.map(l => actualsByCategory[l] || 0), backgroundColor: '#0ea5e9' }] }, { responsive: true, maintainAspectRatio: false }); const today = new Date('2025-06-29'); const getAgingBuckets = (items) => { const buckets = { "Current": 0, "1-30": 0, "31-60": 0, "60+": 0 }; items.filter(i=>i.status.includes('Outstanding')||i.status.includes('Unpaid')).forEach(i => { const overdueDays = (today - new Date(i.dueDate)) / 864e5; if(overdueDays <= 0) buckets["Current"] += i.amount; else if(overdueDays <= 30) buckets["1-30"] += i.amount; else if(overdueDays <= 60) buckets["31-60"] += i.amount; else buckets["60+"] += i.amount; }); return Object.values(buckets); }; const agingLabels = ["Current", "1-30 Days", "31-60 Days", "60+ Days"]; renderChart('fc-ar-chart', 'bar', { labels: agingLabels, datasets: [{ label: 'Amount ($)', data: getAgingBuckets(ar), backgroundColor: '#fb923c' }] }, { responsive: true, maintainAspectRatio: false }); renderChart('fc-ap-chart', 'bar', { labels: agingLabels, datasets: [{ label: 'Amount ($)', data: getAgingBuckets(ap), backgroundColor: '#f87171' }] }, { responsive: true, maintainAspectRatio: false }); }; renderActionTables = () => { const today = new Date('2025-06-29'); elements.arTable.innerHTML = ar.filter(i=>i.status==='Outstanding' && new Date(i.dueDate) < today).map(i=>`${i.customer}${formatCurrency(i.amount)}`).join(''); elements.apTable.innerHTML = ap.filter(i=>i.status==='Unpaid' && new Date(i.dueDate) >= today).map(i=>`${i.vendor}${formatCurrency(i.amount)}`).join(''); } window.fcDownloadPDF = () => { html2canvas(document.getElementById('fc-pdf-content'), { scale: 2 }).then(canvas => { const pdf = new jspdf.jsPDF({ orientation: 'landscape', unit: 'pt', format: 'a4' }); pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 40, 40, pdf.internal.pageSize.getWidth() - 80, 0); pdf.save('Financial_Control_Dashboard.pdf'); }); }; initialize(); });
Scroll to Top