55h Regel - nun aktivierbar für eine schnellere Übersicht. #24

Merged
samuelzielke merged 1 commits from 26-5-55h_Regel into main 3 days ago

@ -409,3 +409,42 @@ function sumDurations(data, type = null, roundToHalfHour = false) {
return totalDuration; return totalDuration;
} }
// Gesamtstunden (in Minuten) für ein Dienstjahr berechnen, optional mit "55h-Regel".
// Wenn rule55Active true ist: jeder Kalendermonat, der LDC- oder Sonstiges-Stunden (type 2/3)
// enthält, wird für die Summe auf maximal 55h gedeckelt. Reine Dienststunden (type 1) zählen
// in jedem Monat immer voll, auch wenn sie allein schon über 55h liegen - der Deckel greift
// nur, sobald LDC/Sonstiges dazukommt.
function calculateServiceYearTotal(entries, rule55Active = false) {
if (!rule55Active) {
return sumDurations(entries, null, true);
}
const CAP_MINUTES = 55 * 60;
// Einträge nach Kalendermonat gruppieren (Jahr+Monat, damit Dez/Jan nicht vermischt werden)
const monthBuckets = {};
entries.forEach(entry => {
const entryDate = new Date(entry.date);
const key = `${entryDate.getFullYear()}-${entryDate.getMonth()}`;
if (!monthBuckets[key]) {
monthBuckets[key] = [];
}
monthBuckets[key].push(entry);
});
let total = 0;
Object.values(monthBuckets).forEach(bucketEntries => {
const normalMinutes = sumDurations(bucketEntries, 1);
const capRuleMinutes = sumDurations(bucketEntries, 2) + sumDurations(bucketEntries, 3);
let monthTotal = normalMinutes + capRuleMinutes;
if (capRuleMinutes > 0) {
monthTotal = Math.min(monthTotal, CAP_MINUTES);
}
total += Math.round(monthTotal / 30) * 30;
});
return total;
}

@ -4,10 +4,15 @@ const mins = document.getElementById('minuten');
const NewEntryButton = document.getElementById('newEntrySubmitButton') const NewEntryButton = document.getElementById('newEntrySubmitButton')
const SETStudySaveButton = document.getElementById('SETStudySaveButton') const SETStudySaveButton = document.getElementById('SETStudySaveButton')
const SETMonthGoalSaveButton = document.getElementById('SETMonthGoalSaveButton') const SETMonthGoalSaveButton = document.getElementById('SETMonthGoalSaveButton')
const rule55hCheck = document.getElementById('rule55hCheck')
var allowToSend = false; var allowToSend = false;
const monate = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]; const monate = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"];
const currentDate = new Date(); const currentDate = new Date();
// 55h-Regel (Jahresansicht): wird beim Start aus den Settings geladen und beim Umschalten
// live aktualisiert, damit getActualDataAndFillView() sie synchron verwenden kann.
var rule55Active = false;
// //
// Trigger // Trigger
@ -15,10 +20,13 @@ const currentDate = new Date();
// Wenn das Dokument komplett geladen ist // Wenn das Dokument komplett geladen ist
document.addEventListener('DOMContentLoaded', (event) => { document.addEventListener('DOMContentLoaded', (event) => {
initDB().then(() => { initDB().then(async () => {
console.log('IndexedDB erfolgreich initialisiert.'); console.log('IndexedDB erfolgreich initialisiert.');
// Hier kannst du die App weiter initialisieren, z.B. Daten laden oder die UI aufbauen // Hier kannst du die App weiter initialisieren, z.B. Daten laden oder die UI aufbauen
// 55h-Regel Einstellung laden, bevor die erste Jahresansicht berechnet wird
await loadRule55Setting();
// Bildschirm mit dem Inhalt für den aktuellen Tag füllen // Bildschirm mit dem Inhalt für den aktuellen Tag füllen
getActualDataAndFillView(); getActualDataAndFillView();
@ -28,6 +36,46 @@ document.addEventListener('DOMContentLoaded', (event) => {
}); });
}); });
// Lädt die 55h-Regel Einstellung (SettingsID 3) aus der DB, setzt rule55Active
// und synchronisiert die Checkbox sowie den Badge in der Jahres-Card.
async function loadRule55Setting() {
const result = await getAllEntries('settings')
const setting = result.find(element => element.SettingsID === 3)
rule55Active = (setting == undefined) ? false : !!parseInt(setting.SettingsValue)
rule55hCheck.checked = rule55Active
updateRule55Badge()
}
// Zeigt/versteckt den "55h-Regel aktiv"-Hinweis an der Jahres-Card
function updateRule55Badge() {
document.getElementById('rule55Badge').classList.toggle('d-none', !rule55Active)
}
// Einstellungen wenn die 55h-Regel umgeschaltet wird
rule55hCheck.addEventListener('change', () => {
rule55Active = rule55hCheck.checked
updateRule55Badge()
const Rule55SettingsData = {
SettingsID: 3,
SettingsValue: rule55Active ? 1 : 0,
}
getAllEntries('settings')
.then(function(result) {
const SETDBData = result.find(element => element.SettingsID === 3)
if (SETDBData != undefined) {
updateEntry(SETDBData.id, 'settings', Rule55SettingsData)
} else {
addEntry(Rule55SettingsData, 'settings')
}
// Jahresansicht mit/ohne Deckel neu berechnen
getActualDataAndFillView(cursorMonth, cursorYear)
})
})
// Änderungen überwachen damit die das Formular nicht zu früh abgesendet wird // Änderungen überwachen damit die das Formular nicht zu früh abgesendet wird
@ -216,12 +264,15 @@ async function getActualDataAndFillView(monat = currentDate.getMonth(), jahr = c
document.getElementById('monthHourOther').innerText = formatDuration(sumDurations(filteredEntries,3,true), true) document.getElementById('monthHourOther').innerText = formatDuration(sumDurations(filteredEntries,3,true), true)
// Jahres Ansicht füllen (Dienstjahr, gekoppelt an den gerade angezeigten Monat/Jahr) // Jahres Ansicht füllen (Dienstjahr, gekoppelt an den gerade angezeigten Monat/Jahr)
// Bei aktiver 55h-Regel wird jeder Monat mit LDC/Sonstiges-Anteil auf max. 55h gedeckelt,
// reine Dienststunden zählen dabei immer voll (siehe calculateServiceYearTotal).
var requestServiceYear = getServiceYear(new Date(jahr, monat, 1)); var requestServiceYear = getServiceYear(new Date(jahr, monat, 1));
var yearData = await filterEntriesByServiceYear(requestServiceYear) var yearEntries = await filterEntriesByServiceYear(requestServiceYear)
yearData = formatDuration(sumDurations(yearData, null, true), true) var yearData = formatDuration(calculateServiceYearTotal(yearEntries, rule55Active), true)
document.getElementById('yearHours').innerText = yearData document.getElementById('yearHours').innerText = yearData
document.getElementById('yearRest').innerText = 600 - parseInt(yearData) document.getElementById('yearRest').innerText = 600 - parseInt(yearData)
document.getElementById('prBarYear').style.width = `${Math.round((100/600)*parseInt(yearData))}%` document.getElementById('prBarYear').style.width = `${Math.round((100/600)*parseInt(yearData))}%`
updateRule55Badge()
} catch (error) { } catch (error) {
console.error('Fehler bei der Initialisierung oder Filterung:', error); console.error('Fehler bei der Initialisierung oder Filterung:', error);

@ -44,6 +44,10 @@
<input type="number" class="w-25 btn btn-secondary" name="MonthGoalInput" id="MonthGoalInput" value="50" onfocus="document.getElementById('SETMonthGoalSaveButton').classList.remove('d-none')"> <input type="number" class="w-25 btn btn-secondary" name="MonthGoalInput" id="MonthGoalInput" value="50" onfocus="document.getElementById('SETMonthGoalSaveButton').classList.remove('d-none')">
<button class="btn d-none" id="SETMonthGoalSaveButton">Sichern</button> <button class="btn d-none" id="SETMonthGoalSaveButton">Sichern</button>
</li> </li>
<li class="list-group-item d-flex justify-content-between align-items-center">
55h-Regel (Jahr):
<input type="checkbox" name="rule55hCheck" id="rule55hCheck" style="position: static; width: 1.5rem; height: 1.5rem; margin: 0;">
</li>
<h5 class="mt-5 text-white text-center">Kontakt</h5> <h5 class="mt-5 text-white text-center">Kontakt</h5>
<li class="list-group-item d-flex justify-content-between align-items-center"> <li class="list-group-item d-flex justify-content-between align-items-center">
WhatsApp Community WhatsApp Community

@ -45,7 +45,7 @@
<div class="row justify-content-around mt-3" style="width: 100vw; color: black;"> <div class="row justify-content-around mt-3" style="width: 100vw; color: black;">
<div class="col-11" id="dashbord_year_area" style="height: 5vh; padding: 1rem; border-radius:1rem; box-shadow: 0 0 0.5rem gray"> <div class="col-11" id="dashbord_year_area" style="height: 5vh; padding: 1rem; border-radius:1rem; box-shadow: 0 0 0.5rem gray">
<div class="row justify-content-between"> <div class="row justify-content-between">
<p class="col-6" style="font-size: 1rem; margin-top: -0.75rem;"><b>Jahr:</b> <span id="yearHours"></span>h/600h</p> <p class="col-6" style="font-size: 1rem; margin-top: -0.75rem; white-space: nowrap;"><b>Jahr:</b> <span id="yearHours"></span>h/600h<span id="rule55Badge" class="badge badge-warning d-none" title="55h-Regel aktiv: Monate mit LDC/Sonstiges werden auf 55h gedeckelt" style="font-size: 0.55rem; vertical-align: middle; margin-left: 0.25rem;">55h</span></p>
<p class="offset-1 col-5" style="font-size: 1rem; margin-top: -0.75rem;"><b>Offen:</b> <span id="yearRest"></span>h</p> <p class="offset-1 col-5" style="font-size: 1rem; margin-top: -0.75rem;"><b>Offen:</b> <span id="yearRest"></span>h</p>
</div> </div>
<div class="progress" style="height: 5px; width: 100%; border-radius: 2rem; background-color: lightgray; margin-top: -1rem;"> <div class="progress" style="height: 5px; width: 100%; border-radius: 2rem; background-color: lightgray; margin-top: -1rem;">

Loading…
Cancel
Save

Powered by TurnKey Linux.