Corporate Social Responsibility (CSR) Expense Tracker
Tracker Setup
Manage CSR Focus Areas/Categories
Define the focus areas for your CSR activities.
Current Focus Areas:
Log CSR Expense/Activity
Logged CSR Expenses
| Date | Activity Name | Focus Area | Beneficiary | Amount ($) | Notes/Impact | Actions |
|---|
CSR Expense Summary
Tracker Name:
Company Name:
Reporting Period:
Total CSR Spend for Period: $0.00
Spend by CSR Focus Area
| Focus Area | Total Spend ($) | % of Total CSR Spend |
|---|
CSR Spend Distribution by Focus Area
Chart library not loaded.
"; return; } const ctx = chartCanvas.getContext('2d'); const chartColors = ['#28a745', '#007bff', '#ffc107', '#17a2b8', '#6f42c1', '#fd7e14', '#6c757d', '#dc3545']; if (csrFocusAreaChartInstance) csrFocusAreaChartInstance.destroy(); if (labels.length > 0 && data.some(d => d > 0)) { csrFocusAreaChartInstance = new Chart(ctx, { type: 'pie', data: { labels: labels, datasets: [{ label: 'Spend by Focus Area', data: data, backgroundColor: labels.map((_,i)=>chartColors[i % chartColors.length]), borderColor: varGet('--csr-light-text'), borderWidth:1 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'top' }, tooltip: {callbacks: {label: c=>`${c.label}: $${c.parsed.toFixed(2)}`}} } } }); } else { ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); ctx.textAlign='center'; ctx.fillStyle = varGet('--csr-secondary-color'); ctx.font = "16px Arial"; ctx.fillText("No CSR expense data to display chart.", ctx.canvas.width/2, ctx.canvas.height/2); csrFocusAreaChartInstance = null; } } function varGet(varName) { return getComputedStyle(document.documentElement).getPropertyValue(varName).trim(); } // --- PDF Download --- window.csrDownloadPDF = function() { if (typeof jsPDF === 'undefined' || typeof autoTable === 'undefined') { alert("PDF libraries not loaded."); return; } const { jsPDF: JSPDF } = window.jspdf; const localAutoTable = window.jspdf.autoTable; const doc = new JSPDF(); csrUpdateSummaryReport(); // Ensure data is current const trackerName = csrTrackerSettings.trackerName; const companyName = csrTrackerSettings.companyName; let periodString = csrTrackerSettings.reportingPeriodType; if (csrTrackerSettings.reportingPeriodType === 'Annually') periodString = `Annually (${csrTrackerSettings.reportingYear})`; else if (csrTrackerSettings.reportingPeriodType === 'Quarterly') periodString = `${csrTrackerSettings.reportingQuarter}, ${csrTrackerSettings.reportingYear}`; else if (csrTrackerSettings.reportingPeriodType === 'Custom' && csrTrackerSettings.customStartDate && csrTrackerSettings.customEndDate) { periodString = `${csrTrackerSettings.customStartDate} to ${csrTrackerSettings.customEndDate}`; } const generationDate = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }) + " (Reference Time: Friday, May 16, 2025)"; doc.setFontSize(18); doc.setTextColor(varGet('--csr-primary-color')); doc.text(trackerName, doc.internal.pageSize.getWidth() / 2, 15, { align: 'center' }); doc.setFontSize(11); doc.setTextColor(varGet('--csr-dark-text')); doc.text(`Company: ${companyName || 'N/A'}`, 14, 25); doc.text(`Reporting Period: ${periodString}`, doc.internal.pageSize.getWidth() - 14, 25, { align: 'right' }); doc.setFontSize(9); doc.setTextColor(varGet('--csr-secondary-color')); doc.text(`Report Generated: ${generationDate}`, 14, 31); let yPos = 40; const totalSpend = csrExpenses.reduce((sum, exp) => sum + exp.amount, 0); doc.setFontSize(12); doc.setTextColor(varGet('--csr-primary-color')); doc.text("Overall CSR Spend Summary", 14, yPos); yPos += 7; doc.setFontSize(10); doc.setTextColor(varGet('--csr-dark-text')); doc.text(`Total CSR Spend for Period: $${totalSpend.toFixed(2)}`, 14, yPos); yPos += 10; doc.setFontSize(12); doc.setTextColor(varGet('--csr-primary-color')); doc.text("Logged CSR Expenses", 14, yPos); yPos += 7; const expHead = [['Date', 'Activity', 'Focus Area', 'Beneficiary', 'Amount ($)', 'Notes/Impact']]; const expBody = csrExpenses.map(exp => [ exp.date, exp.activityName, exp.focusArea, exp.beneficiary || '-', exp.amount.toFixed(2), exp.notes || '-' ]); localAutoTable(doc, { head: expHead, body: expBody, startY: yPos, theme: 'grid', headStyles: { fillColor: varGet('--csr-primary-color'), textColor: varGet('--csr-light-text')}, styles: { fontSize: 8, cellPadding: 1.5, overflow: 'linebreak' }, columnStyles: { 0:{cellWidth:20}, 1:{cellWidth:40}, 2:{cellWidth:35}, 3:{cellWidth:35}, 4:{halign:'right', cellWidth:20}, 5:{cellWidth: 'auto'} }, didDrawPage: data => yPos = data.cursor.y }); yPos = doc.lastAutoTable.finalY + 10; // Chart const chartCanvas = document.getElementById('csrFocusAreaChart'); if (chartCanvas && csrFocusAreaChartInstance && csrFocusAreaChartInstance.data.datasets[0].data.some(d => d > 0)) { if (yPos > doc.internal.pageSize.getHeight() - 80) { doc.addPage(); yPos = 20;} doc.setFontSize(12); doc.setTextColor(varGet('--csr-primary-color')); doc.text("CSR Spend Distribution by Focus Area", doc.internal.pageSize.getWidth() / 2, yPos, { align: 'center' }); yPos += 7; try { const chartImage = chartCanvas.toDataURL('image/png', 1.0); const imgProps = doc.getImageProperties(chartImage); const pdfChartWidth = doc.internal.pageSize.getWidth() * 0.7; const chartHeight = (imgProps.height * pdfChartWidth) / imgProps.width; const xOffset = (doc.internal.pageSize.getWidth() - pdfChartWidth) / 2; if (yPos + chartHeight > doc.internal.pageSize.getHeight() -10 ) { doc.addPage(); yPos = 20; doc.text("CSR Spend Distribution (cont.)", doc.internal.pageSize.getWidth() / 2, yPos, {align: 'center'}); yPos += 7; } doc.addImage(chartImage, 'PNG', xOffset, yPos, pdfChartWidth, chartHeight); } catch(e) { console.error("Error adding chart to PDF:", e); } } doc.save(`${trackerName.replace(/[^a-z0-9]/gi, '_').toLowerCase()}_csr_expenses.pdf`); } // --- Initialization --- const today = new Date().toISOString().split('T')[0]; document.getElementById('csrExpenseDate').value = today; document.getElementById('csrCustomStartDate').value = today; const endDate = new Date(); endDate.setFullYear(endDate.getFullYear() + 1); endDate.setDate(endDate.getDate() -1); // Default custom to 1 year document.getElementById('csrCustomEndDate').value = endDate.toISOString().split('T')[0]; csrRenderFocusAreas(); csrRenderExpensesTable(); csrShowTab(0); csrUpdateSummaryReport(); // Initial call for summary tab content });