From dfd4a178ea9eaab8a7ee41d6c01c3310d1490e37 Mon Sep 17 00:00:00 2001 From: marijo Date: Tue, 9 Jun 2026 18:22:41 +0000 Subject: [PATCH] Unpaid calcualtion corrected --- app.js | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/app.js b/app.js index 74a0d7a..c5f5faf 100644 --- a/app.js +++ b/app.js @@ -611,6 +611,8 @@ function calculatePlan(settings, entries, corrections = {}, feriefridageOverride usedFeriefridage: 0, usedFlex: 0, usedFlexDays: 0, + usedUnpaid: 0, + allowUnpaid: Boolean(Number(entry.allow_unpaid)), }; current.entries.push(monthEntry); } @@ -619,6 +621,7 @@ function calculatePlan(settings, entries, corrections = {}, feriefridageOverride monthEntry.usedFeriefridage += allocation.usedFeriefridage; monthEntry.usedFlex += allocation.usedFlex; monthEntry.usedFlexDays += allocation.usedFlexDays; + monthEntry.usedUnpaid += allocation.usedUnpaid; }; if (isThisMonth) { @@ -631,6 +634,10 @@ function calculatePlan(settings, entries, corrections = {}, feriefridageOverride vacationBalance += current.earnedVacation; + if (vacationBalance < -0.001) { + vacationBalance = convertNegativeVacationToUnpaid(current, entrySummaries, vacationBalance); + } + if (month === Number(settings.feriefridage_expiry_month || 8) && year === today.getFullYear() && feriefridageBalance > 0.001) { warnings.push({ level: 'warn', text: `${days(feriefridageBalance)} feriefridage remain at the end of August ${year}; they must be used before 31 August.` }); } @@ -676,6 +683,26 @@ function calculatePlan(settings, entries, corrections = {}, feriefridageOverride }; } +function convertNegativeVacationToUnpaid(month, entrySummaries, vacationBalance) { + let remaining = -vacationBalance; + for (const monthEntry of [...month.entries].reverse()) { + if (!monthEntry.allowUnpaid || monthEntry.usedVacation <= 0 || remaining <= 0.001) continue; + const convert = Math.min(monthEntry.usedVacation, remaining); + monthEntry.usedVacation -= convert; + monthEntry.usedUnpaid += convert; + month.usedVacation -= convert; + month.usedUnpaid += convert; + const summary = entrySummaries[monthEntry.id]; + if (summary) { + summary.usedVacation -= convert; + summary.usedUnpaid += convert; + } + vacationBalance += convert; + remaining -= convert; + } + return vacationBalance; +} + function calculateCurrentSnapshot(settings, entries, corrections = {}, feriefridageOverrides = {}, flexOverrides = {}) { const today = dateFromParts(new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()); const previousMonths = Number(settings.previous_months ?? 5); @@ -870,12 +897,8 @@ function allocateDay(entry, date, balances, settings, fraction = 1) { } if (remaining > 0) { - if (allowUnpaid) { - result.usedUnpaid += remaining; - } else { - result.usedVacation += remaining; - vacationBalance -= remaining; - } + result.usedVacation += remaining; + vacationBalance -= remaining; } }