diff --git a/assets/js/project_details.js b/assets/js/project_details.js index 628e7a2..e4046f2 100644 --- a/assets/js/project_details.js +++ b/assets/js/project_details.js @@ -1,4 +1,3 @@ - document.addEventListener('DOMContentLoaded', function () { const overrideBtn = document.getElementById('override-btn'); @@ -16,12 +15,14 @@ document.addEventListener('DOMContentLoaded', function () { makeEditable('Opening-Balance', month); makeEditable('Billings', month); makeEditable('Expenses', month); + makeEditable('Cost', month); } else if (this.textContent.trim() === 'Save') { const wip = document.getElementById(`wip-${month}-input`).value; const openingBalance = document.getElementById(`opening-balance-${month}-input`).value; const billings = document.getElementById(`billings-${month}-input`).value; const expenses = document.getElementById(`expenses-${month}-input`).value; + const cost = document.getElementById(`cost-${month}-input`).value; const formData = new FormData(); formData.append('projectId', projectId); @@ -30,6 +31,7 @@ document.addEventListener('DOMContentLoaded', function () { formData.append('openingBalance', openingBalance); formData.append('billings', billings); formData.append('expenses', expenses); + formData.append('cost', cost); fetch('save_override.php', { method: 'POST', @@ -43,10 +45,14 @@ document.addEventListener('DOMContentLoaded', function () { this.classList.add('btn-secondary'); this.disabled = true; - updateCell('WIP', month, wip); - updateCell('Opening-Balance', month, openingBalance); - updateCell('Billings', month, billings); - updateCell('Expenses', month, expenses); + updateMetricCell('WIP', month, wip); + updateMetricCell('Opening-Balance', month, openingBalance); + updateMetricCell('Billings', month, billings); + updateMetricCell('Expenses', month, expenses); + updateMetricCell('Cost', month, cost); + updateMetricCell('NSR', month, data.nsr); + updateMetricCell('Margin', month, data.margin); + } else { alert('Error saving override: ' + data.error); } @@ -60,22 +66,31 @@ document.addEventListener('DOMContentLoaded', function () { } function makeEditable(metric, month) { - const cell = document.getElementById(`${metric.toLowerCase().replace(/\s/g, '-')}-${month}`); + const cellId = `${metric.toLowerCase().replace(/\s/g, '-')}-${month}`; + const cell = document.getElementById(cellId); if (cell) { - let value = cell.textContent.replace(/€/g, '').replace(/,/g, ''); + let value = cell.textContent.replace(/[€%]/g, '').replace(/,/g, '').trim(); let numericValue = parseFloat(value); if (isNaN(numericValue)) { numericValue = 0; } - cell.innerHTML = ``; + if (metric === 'Margin') { + numericValue = numericValue / 100; + } + cell.innerHTML = ``; } } - function updateCell(metric, month, value) { - const cell = document.getElementById(`${metric.toLowerCase().replace(/\s/g, '-')}-${month}`); + function updateMetricCell(metric, month, value) { + const cellId = `${metric.toLowerCase().replace(/\s/g, '-')}-${month}`; + const cell = document.getElementById(cellId); if (cell) { const numericValue = value === '' ? 0 : parseFloat(value); - cell.innerHTML = `€${numericValue.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; + if (metric === 'Margin') { + cell.innerHTML = `${(numericValue * 100).toFixed(2)}%`; + } else { + cell.innerHTML = `€${numericValue.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; + } } } -}); +}); \ No newline at end of file diff --git a/project_details.php b/project_details.php index 5f7dd80..7fc5afb 100644 --- a/project_details.php +++ b/project_details.php @@ -143,27 +143,30 @@ if ($project_id) { } // 3. Fetch and apply overridden data - $override_stmt = $pdo->prepare("SELECT month, MAX(CASE WHEN metricName = 'wip' THEN value ELSE 0 END) as wip, MAX(CASE WHEN metricName = 'opening_balance' THEN value ELSE 0 END) as opening_balance, MAX(CASE WHEN metricName = 'billing' THEN value ELSE 0 END) as billing, MAX(CASE WHEN metricName = 'expenses' THEN value ELSE 0 END) as expenses FROM projectFinanceMonthly WHERE projectId = :pid AND is_overridden = 1 GROUP BY month"); + $override_stmt = $pdo->prepare("SELECT month, metricName, value FROM projectFinanceMonthly WHERE projectId = :pid AND is_overridden = 1"); $override_stmt->execute([':pid' => $project_id]); + $overridden_data = $override_stmt->fetchAll(PDO::FETCH_ASSOC); - while ($row = $override_stmt->fetch(PDO::FETCH_ASSOC)) { + $metric_name_map = [ + 'wip' => 'WIP', + 'opening_balance' => 'Opening Balance', + 'billing' => 'Billings', + 'expenses' => 'Expenses', + 'cost' => 'Cost', + 'nsr' => 'NSR', + 'margin' => 'Margin' + ]; + + foreach ($overridden_data as $row) { $month = $row['month']; - if (in_array($month, $months)) { - $financial_data['WIP'][$month] = $row['wip']; - $financial_data['Opening Balance'][$month] = $row['opening_balance']; - $financial_data['Billings'][$month] = $row['billing']; - $financial_data['Expenses'][$month] = $row['expenses']; + $metric_db_name = $row['metricName']; + $value = $row['value']; + + if (in_array($month, $months) && isset($metric_name_map[$metric_db_name])) { + $metric_display_name = $metric_name_map[$metric_db_name]; + $financial_data[$metric_display_name][$month] = $value; } } - - // 4. Recalculate dependent metrics (NSR and Margin) after override - foreach ($months as $month) { - $nsr = $financial_data['WIP'][$month] + $financial_data['Billings'][$month] - $financial_data['Opening Balance'][$month] - $financial_data['Expenses'][$month]; - $financial_data['NSR'][$month] = $nsr; - - $margin = ($nsr != 0) ? (($nsr - $financial_data['Cost'][$month]) / $nsr) : 0; - $financial_data['Margin'][$month] = $margin; - } } } @@ -276,7 +279,7 @@ if (!$project) {