Unpaid calcualtion corrected

This commit is contained in:
marijo 2026-06-09 18:22:41 +00:00
parent a382f00ba4
commit dfd4a178ea

35
app.js
View file

@ -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;
}
}