diff --git a/backend/src/lib/workforce.js b/backend/src/lib/workforce.js index 1ca4a4e..be8fb2d 100644 --- a/backend/src/lib/workforce.js +++ b/backend/src/lib/workforce.js @@ -180,16 +180,17 @@ export async function syncActuals(from, to) { } } + // syncActuals recomputes the entire [from, to] range from the API on every call, so any + // shift that vanished or moved department since the last sync (edited, deleted, reassigned) + // must have its old row cleared here — otherwise it lingers as a stale orphan (department + // totals get overwritten to the new figure, but the old per-employee detail row never does). + await pool.query(`DELETE FROM wage_actuals WHERE date >= $1 AND date <= $2`, [from, to]) + await pool.query(`DELETE FROM wage_actuals_detail WHERE date >= $1 AND date <= $2`, [from, to]) + for (const row of Object.values(byDateDept)) { await pool.query( `INSERT INTO wage_actuals (date, department_id, department_name, base_cost, total_cost, shift_count, cached_at) - VALUES ($1, $2, $3, $4, $5, $6, NOW()) - ON CONFLICT (date, department_id) DO UPDATE SET - department_name = EXCLUDED.department_name, - base_cost = EXCLUDED.base_cost, - total_cost = EXCLUDED.total_cost, - shift_count = EXCLUDED.shift_count, - cached_at = NOW()`, + VALUES ($1, $2, $3, $4, $5, $6, NOW())`, [row.date, row.department_id, row.department_name, row.base_cost.toFixed(2), row.total_cost.toFixed(2), row.shift_count] ) @@ -198,13 +199,7 @@ export async function syncActuals(from, to) { for (const row of Object.values(byDateDeptEmp)) { await pool.query( `INSERT INTO wage_actuals_detail (date, department_id, employee_id, employee_name, base_cost, total_cost, shift_count, cached_at) - VALUES ($1, $2, $3, $4, $5, $6, $7, NOW()) - ON CONFLICT (date, department_id, employee_id) DO UPDATE SET - employee_name = EXCLUDED.employee_name, - base_cost = EXCLUDED.base_cost, - total_cost = EXCLUDED.total_cost, - shift_count = EXCLUDED.shift_count, - cached_at = NOW()`, + VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())`, [row.date, row.department_id, row.employee_id, row.employee_name, row.base_cost.toFixed(2), row.total_cost.toFixed(2), row.shift_count] )