Employee Remote Work Setup Cost Calculator

Estimation Setup

Cost Itemization for Remote Setup

Add New Cost Item

Enter the cost for one employee for this item.
Defaults to total employees from Setup, can be overridden.

Current Cost Items for Remote Setup

Item/Service Name Category Cost/Unit ($) # Employees Total Cost ($) Notes Actions

Total Estimated Costs & Report

Estimation Plan Name:

Company Name:

Total Employees for Setup:


Total Estimated Remote Work Setup Cost: $0.00

Average Setup Cost per Employee: $0.00

Estimated Costs by Category

CategoryTotal Estimated Cost ($)% of Grand Total

Cost Distribution by Category

Chart library not loaded.

"; return; } const ctx = chartCanvas.getContext('2d'); const chartColors = ['#007bff', '#28a745', '#ffc107', '#17a2b8', '#6f42c1', '#fd7e14', '#6c757d', '#dc3545', '#20c997']; if (rwscCategoryCostChartInstance) rwscCategoryCostChartInstance.destroy(); if (labels.length > 0 && data.some(d => d > 0)) { rwscCategoryCostChartInstance = new Chart(ctx, { type: 'pie', data: { labels: labels, datasets: [{ label: 'Cost by Category', data: data, backgroundColor: labels.map((_,i)=>chartColors[i % chartColors.length]), borderColor: varGet('--rwsc-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('--rwsc-secondary-color'); ctx.font = "16px Arial"; ctx.fillText("No cost data by category to display chart.", ctx.canvas.width/2, ctx.canvas.height/2); rwscCategoryCostChartInstance = null; } } function varGet(varName) { return getComputedStyle(document.documentElement).getPropertyValue(varName).trim(); } // --- PDF Download --- window.rwscDownloadPDF = 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(); rwscUpdateSummaryReport(); const planName = rwscEstimationConfig.planName; const companyName = rwscEstimationConfig.companyName; const totalEmployees = rwscEstimationConfig.totalEmployeesForSetup; 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('--rwsc-primary-color')); doc.text(planName, doc.internal.pageSize.getWidth() / 2, 15, { align: 'center' }); doc.setFontSize(11); doc.setTextColor(varGet('--rwsc-dark-text')); doc.text(`Company: ${companyName || 'N/A'}`, 14, 25); doc.text(`Total Employees for Setup: ${totalEmployees}`, doc.internal.pageSize.getWidth() - 14, 25, { align: 'right' }); doc.setFontSize(9); doc.setTextColor(varGet('--rwsc-secondary-color')); doc.text(`Report Generated: ${generationDate}`, 14, 31); let yPos = 40; const grandTotalCost = rwscCostItems.reduce((sum, item) => sum + item.totalCostForItem, 0); const avgCostPerEmployee = totalEmployees > 0 ? (grandTotalCost / totalEmployees) : 0; doc.setFontSize(12); doc.setTextColor(varGet('--rwsc-primary-color')); doc.text("Overall Cost Summary", 14, yPos); yPos += 7; doc.setFontSize(10); doc.setTextColor(varGet('--rwsc-dark-text')); doc.text(`Total Estimated Setup Cost: $${grandTotalCost.toFixed(2)}`, 14, yPos); yPos += 5; doc.text(`Average Setup Cost per Employee: $${avgCostPerEmployee.toFixed(2)}`, 14, yPos); yPos += 10; doc.setFontSize(12); doc.setTextColor(varGet('--rwsc-primary-color')); doc.text("Itemized Setup Costs", 14, yPos); yPos += 7; const itemHead = [['Item/Service', 'Category', 'Cost/Unit ($)', '# Employees', 'Total Cost ($)', 'Notes']]; const itemBody = rwscCostItems.map(item => [ item.name, item.category, item.costPerUnit.toFixed(2), item.numEmployeesForItem, item.totalCostForItem.toFixed(2), item.notes || '-' ]); localAutoTable(doc, { head: itemHead, body: itemBody, startY: yPos, theme: 'grid', headStyles: { fillColor: varGet('--rwsc-primary-color'), textColor: varGet('--rwsc-light-text')}, styles: { fontSize: 8, cellPadding: 1.5, overflow: 'linebreak' }, columnStyles: { 0:{cellWidth:40}, 1:{cellWidth:40}, 2:{halign:'right'}, 3:{halign:'right'}, 4:{halign:'right', fontStyle:'bold'}, 5:{cellWidth:'auto'} }, didDrawPage: data => yPos = data.cursor.y }); yPos = doc.lastAutoTable.finalY + 10; // Chart const chartCanvas = document.getElementById('rwscCategoryCostChart'); if (chartCanvas && rwscCategoryCostChartInstance && rwscCategoryCostChartInstance.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('--rwsc-primary-color')); doc.text("Cost Distribution by Category", 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.65; 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("Cost Distribution by Category (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(`${planName.replace(/[^a-z0-9]/gi, '_').toLowerCase()}_remote_setup_costs.pdf`); } // --- Initialization --- rwscRenderCostCategoriesSelect(); // Populate category dropdown // Set default for number of employees for item when tab 1 total employees changes document.getElementById('rwscTotalEmployeesForSetup').addEventListener('input', (e) => { const totalEmpl = parseInt(e.target.value) || 1; document.getElementById('rwscNumEmployeesForItem').value = totalEmpl > 0 ? totalEmpl : 1; rwscSaveEstimationConfig(); // Save immediately as other calcs might depend on it }); rwscRenderCostItemsTable(); rwscShowTab(0); rwscUpdateSummaryReport(); // Initial calculation for summary tab if needed });
Scroll to Top