From 4783b5ec102b96b308bd60eadbf719e8fbfff544 Mon Sep 17 00:00:00 2001 From: chamiakJ Date: Thu, 12 Jun 2025 16:21:48 +0530 Subject: [PATCH] fix(finance-table): refine budget and variance calculations for improved accuracy - Updated budget calculations to consistently include fixed costs across all tasks. - Adjusted variance logic to align with the new budget calculations, ensuring accurate financial reporting. - Increased save delay for fixed cost input to 5 seconds, allowing users more time to edit values. - Added text selection on input focus for better user experience. --- .../finance-table/finance-table-wrapper.tsx | 5 ++-- .../finance-table/finance-table.tsx | 26 ++++++++++++------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/worklenz-frontend/src/pages/projects/projectView/finance/finance-tab/finance-table/finance-table-wrapper.tsx b/worklenz-frontend/src/pages/projects/projectView/finance/finance-tab/finance-table/finance-table-wrapper.tsx index 251e6ff5..10acc136 100644 --- a/worklenz-frontend/src/pages/projects/projectView/finance/finance-tab/finance-table/finance-table-wrapper.tsx +++ b/worklenz-frontend/src/pages/projects/projectView/finance/finance-tab/finance-table/finance-table-wrapper.tsx @@ -85,13 +85,14 @@ const FinanceTableWrapper: React.FC = ({ activeTablesL } else { // Leaf task - calculate values from individual task properties const leafTotalActual = (task.actual_cost_from_logs || 0) + (task.fixed_cost || 0); + const leafTotalBudget = (task.estimated_cost || 0) + (task.fixed_cost || 0); return { hours: acc.hours + (task.estimated_seconds || 0), cost: acc.cost + (task.actual_cost_from_logs || 0), fixedCost: acc.fixedCost + (task.fixed_cost || 0), - totalBudget: acc.totalBudget + (task.estimated_cost || 0), + totalBudget: acc.totalBudget + leafTotalBudget, totalActual: acc.totalActual + leafTotalActual, - variance: acc.variance + (leafTotalActual - (task.estimated_cost || 0)), + variance: acc.variance + (leafTotalActual - leafTotalBudget), total_time_logged: acc.total_time_logged + (task.total_time_logged_seconds || 0), estimated_cost: acc.estimated_cost + (task.estimated_cost || 0) }; diff --git a/worklenz-frontend/src/pages/projects/projectView/finance/finance-tab/finance-table/finance-table.tsx b/worklenz-frontend/src/pages/projects/projectView/finance/finance-tab/finance-table/finance-table.tsx index 596bdd1c..2423a4c6 100644 --- a/worklenz-frontend/src/pages/projects/projectView/finance/finance-tab/finance-table/finance-table.tsx +++ b/worklenz-frontend/src/pages/projects/projectView/finance/finance-tab/finance-table/finance-table.tsx @@ -230,10 +230,9 @@ const FinanceTable = ({ // Only save if the value actually changed if (newFixedCost !== currentFixedCost && value !== null) { handleFixedCostChange(value, taskId); - setSelectedTask(null); - setEditingFixedCostValue(null); + // Don't close the input automatically - let user explicitly close it } - }, 1000); // Save after 1 second of inactivity + }, 5000); // Save after 5 seconds of inactivity }; // Immediate save function (for enter/blur) @@ -442,6 +441,10 @@ const FinanceTable = ({ // Immediate save on enter immediateSaveFixedCost(editingFixedCostValue, task.id); }} + onFocus={(e) => { + // Select all text when input is focused + e.target.select(); + }} autoFocus style={{ width: '100%', textAlign: 'right', fontSize: Math.max(12, 14 - level * 0.5) }} formatter={(value) => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} @@ -472,22 +475,27 @@ const FinanceTable = ({ ); case FinanceTableColumnKeys.VARIANCE: + const taskTotalBudgetForVariance = (task.estimated_cost || 0) + (task.fixed_cost || 0); + const taskTotalActualForVariance = (task.actual_cost_from_logs || 0) + (task.fixed_cost || 0); + const taskVariance = taskTotalActualForVariance - taskTotalBudgetForVariance; return ( 0 ? '#FF0000' : '#6DC376', + color: taskVariance > 0 ? '#FF0000' : '#6DC376', fontSize: Math.max(12, 14 - level * 0.5) }} > - {task.variance < 0 ? '+' + formatNumber(Math.abs(task.variance)) : - task.variance > 0 ? '-' + formatNumber(task.variance) : - formatNumber(task.variance)} + {taskVariance < 0 ? '+' + formatNumber(Math.abs(taskVariance)) : + taskVariance > 0 ? '-' + formatNumber(taskVariance) : + formatNumber(taskVariance)} ); case FinanceTableColumnKeys.TOTAL_BUDGET: - return {formatNumber(task.total_budget)}; + const taskTotalBudget = (task.estimated_cost || 0) + (task.fixed_cost || 0); + return {formatNumber(taskTotalBudget)}; case FinanceTableColumnKeys.TOTAL_ACTUAL: - return {formatNumber(task.total_actual)}; + const taskTotalActual = (task.actual_cost_from_logs || 0) + (task.fixed_cost || 0); + return {formatNumber(taskTotalActual)}; case FinanceTableColumnKeys.COST: return {formatNumber(task.actual_cost_from_logs || 0)}; default: