Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom hours daily #1091

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions js/time-balance.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,26 @@ function _getOverallBalanceStartDate()
return savedPreferences['overall-balance-start-date'];
}

function _getHoursPerDay()
// function _getHoursPerDay()
// {
// const savedPreferences = getUserPreferences();
// return savedPreferences['hours-per-day'];
// }

function _getHoursForDay(dayIndex)
{
const savedPreferences = getUserPreferences();
return savedPreferences['hours-per-day'];
const days = [
'sunday',
'monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday'
];
return savedPreferences[`hours-${days[dayIndex]}`] || '08:00';
}

/**
* Given an array of times from a day in the flexible calendar, returns the
* day total according to same calculation rules as those of the calendar.
Expand Down Expand Up @@ -170,7 +184,7 @@ async function computeAllTimeBalanceUntil(limitDate)
const totals = _getDayTotalsFromStores(firstDate, limitDate);

const preferences = getUserPreferences();
const hoursPerDay = _getHoursPerDay();
// const hoursPerDay = _getHoursPerDay();
let allTimeTotal = '00:00';
const date = new Date(firstDate);
const limitDateStr = getDateStr(limitDate);
Expand All @@ -179,8 +193,10 @@ async function computeAllTimeBalanceUntil(limitDate)
{
if (showDay(date.getFullYear(), date.getMonth(), date.getDate(), preferences))
{
const dayIndex = date.getDay();
const dayHours = _getHoursForDay(dayIndex);
const dayTotal = dateStr in totals ? totals[dateStr] : '00:00';
const dayBalance = subtractTime(hoursPerDay, dayTotal);
const dayBalance = subtractTime(dayHours, dayTotal);
allTimeTotal = sumTime(dayBalance, allTimeTotal);
}
date.setDate(date.getDate() + 1);
Expand Down
27 changes: 25 additions & 2 deletions js/user-preferences.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,14 @@ const defaultPreferences = {
'close-to-tray': true,
'minimize-to-tray': true,
'hide-non-working-days': false,
'hours-per-day': '08:00',
'hours-sunday': '08:00',
'hours-monday': '08:00',
'hours-tuesday': '08:00',
'hours-wednesday': '08:00',
'hours-thursday': '08:00',
'hours-friday': '08:00',
'hours-saturday': '08:00',
'hours-per-day': '08:00', //probably need to remove
'enable-prefill-break-time': false,
'break-time-interval': '00:30',
'notification': true,
Expand Down Expand Up @@ -76,6 +83,13 @@ const timeInputs = [
'notifications-interval',
'hours-per-day',
'break-time-interval',
'hours-sunday',
'hours-monday',
'hours-tuesday',
'hours-wednesday',
'hours-thursday',
'hours-friday',
'hours-saturday',
];

const isNotBoolean = (val) => typeof val !== 'boolean';
Expand Down Expand Up @@ -111,7 +125,9 @@ function savePreferences(preferencesOptions, filePath = getPreferencesFilePath()
{
try
{
getFs().writeFileSync(filePath, JSON.stringify(preferencesOptions));
const preferencesToSave = { ...defaultPreferences, ...preferencesOptions };
getFs().writeFileSync(filePath, JSON.stringify(preferencesToSave));

}
catch (err)
{
Expand Down Expand Up @@ -190,6 +206,13 @@ function initPreferencesFileIfNotExistsOrInvalid(filePath = getPreferencesFilePa
'notifications-interval' : () => isNotificationInterval(value),
'hours-per-day' : () => validateTime(value),
'break-time-interval' : () => validateTime(value),
'hours-sunday': () => validateTime(value),
'hours-monday': () => validateTime(value),
'hours-tuesday': () => validateTime(value),
'hours-wednesday': () => validateTime(value),
'hours-thursday': () => validateTime(value),
'hours-friday': () => validateTime(value),
'hours-saturday': () => validateTime(value),
};
if (!timeValidationEnum[key]())
{
Expand Down
20 changes: 18 additions & 2 deletions renderer/classes/BaseCalendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,20 @@ class BaseCalendar
return this._preferences['hours-per-day'];
}

_getHoursForDay(dayIndex)
{
const days = [
'sunday',
'monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday'
];
return this._preferences[`hours-${days[dayIndex]}`] || '08:00';
}

/**
* Returns if "hide non-working days" was set in preferences.
* @return {Boolean}
Expand Down Expand Up @@ -659,8 +673,10 @@ class BaseCalendar
}
if (timesAreProgressing)
{
const lastTime = validatedTimes[validatedTimes.length-1];
const remainingTime = subtractTime(dayTotal, this._getHoursPerDay());
const lastTime = validatedTimes[validatedTimes.length - 1];
const dayIndex = new Date(this._getTodayYear(), this._getTodayMonth(), this._getTodayDate()).getDay();
const dayHours = this._getHoursForDay(dayIndex);
const remainingTime = subtractTime(dayTotal, dayHours);
leaveBy = sumTime(lastTime, remainingTime);
}
}
Expand Down
48 changes: 34 additions & 14 deletions renderer/classes/FlexibleDayCalendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import {
isNegative,
multiplyTime,
subtractTime,
sumTime,
validateTime
Expand Down Expand Up @@ -49,6 +48,26 @@ class FlexibleDayCalendar extends BaseCalendar
$('#calendar').html(body);
$('html').attr('data-view', 'flexible-day');
}
/**
* Returns the working hours for the specified day of the week.
*/
_getHoursForDay(dayIndex)
{
const dayKeys = [
'hours-sunday',
'hours-monday',
'hours-tuesday',
'hours-wednesday',
'hours-thursday',
'hours-friday',
'hours-saturday'
];
if (dayIndex < 0 || dayIndex > 6)
{
throw new Error('Invalid dayIndex provided to _getHoursForDay.');
}
return this._preferences[dayKeys[dayIndex]] || '08:00';
}

/**
* Returns the header of the page, with the image, name and a message.
Expand Down Expand Up @@ -385,9 +404,8 @@ class FlexibleDayCalendar extends BaseCalendar
{
const yesterday = new Date(this._calendarDate);
yesterday.setDate(this._calendarDate.getDate() - 1);
let workingDaysToCompute = 0,
monthTotalWorked = '00:00';
let countDays = false;

let monthTotalWorked = '00:00';

const limit = this._getCountToday() ? this._getCalendarDate() : (yesterday.getMonth() !== this._getCalendarMonth() ? 0 : yesterday.getDate());
for (let day = 1; day <= limit; ++day)
Expand All @@ -396,27 +414,27 @@ class FlexibleDayCalendar extends BaseCalendar
{
continue;
}

const dayTotal = this._getDayTotal(this._getCalendarYear(), this._getCalendarMonth(), day);
if (dayTotal !== undefined)
{
countDays = true;
monthTotalWorked = sumTime(monthTotalWorked, dayTotal);
}
if (countDays)
{
workingDaysToCompute += 1;

const dayIndex = new Date(this._getCalendarYear(), this._getCalendarMonth(), day).getDay(); // Get current day
const hoursForDay = this._getHoursForDay(dayIndex);
const dayBalance = subtractTime(hoursForDay, dayTotal);
monthTotalWorked = sumTime(monthTotalWorked, dayBalance);
}

}
const monthTotalToWork = multiplyTime(this._getHoursPerDay(), workingDaysToCompute * -1);
const balance = sumTime(monthTotalToWork, monthTotalWorked);

const balance = monthTotalWorked;
const balanceElement = $('#month-balance');
if (balanceElement)
{
balanceElement.html(balance);
balanceElement.removeClass('text-success text-danger');
balanceElement.addClass(isNegative(balance) ? 'text-danger' : 'text-success');
}

}

/**
Expand All @@ -438,7 +456,9 @@ class FlexibleDayCalendar extends BaseCalendar
const dayTotal = $('.day-total span').html();
if (dayTotal !== undefined && dayTotal.length > 0)
{
const dayBalance = subtractTime(this._getHoursPerDay(), dayTotal);
const dayIndex = new Date(this._getTodayYear(), this._getTodayMonth(), this._getTodayDate()).getDay();
const dayHours = this._getHoursForDay(dayIndex);
const dayBalance = subtractTime(dayHours, dayTotal);
$('#leave-day-balance').val(dayBalance);
$('#leave-day-balance').removeClass('text-success text-danger');
$('#leave-day-balance').addClass(isNegative(dayBalance) ? 'text-danger' : 'text-success');
Expand Down
49 changes: 36 additions & 13 deletions renderer/classes/FlexibleMonthCalendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,20 @@ class FlexibleMonthCalendar extends BaseCalendar
}
return targetDate;
}

/* Returns the working hours for the specified day of the week. */
_getHoursForDay(dayIndex)
{
const dayKeys = [
'hours-sunday',
'hours-monday',
'hours-tuesday',
'hours-wednesday',
'hours-thursday',
'hours-friday',
'hours-saturday'
];
return this._preferences[dayKeys[dayIndex]] || '08:00'; // Default to '08:00' if no preference is set
}
/*
* Generates the calendar HTML view.
*/
Expand Down Expand Up @@ -503,15 +516,17 @@ class FlexibleMonthCalendar extends BaseCalendar
{
const now = new Date();
const monthLength = getMonthLength(this._getCalendarYear(), this._getCalendarMonth());
let workingDaysToCompute = 0;
const workingDaysToCompute = [];
let monthTotalWorked = '00:00';
let countDays = false;
let isNextDay = false;

for (let day = 1; day <= monthLength; ++day)
{
const isToday = (now.getDate() === day && now.getMonth() === this._getCalendarMonth() && now.getFullYear() === this._getCalendarYear());
// balance should consider preferences and count or not today
const isToday = now.getDate() === day &&
now.getMonth() === this._getCalendarMonth() &&
now.getFullYear() === this._getCalendarYear();

// balance should consider preferences and count or notyyyyyyyyyyyyyyyyyyyyyyyy today
if (isToday && !this._getCountToday() || isNextDay && this._getCountToday())
{
break;
Expand All @@ -524,18 +539,23 @@ class FlexibleMonthCalendar extends BaseCalendar
}

const dayTotal = this._getDayTotal(this._getCalendarYear(), this._getCalendarMonth(), day);
if (dayTotal !== undefined && dayTotal.length !== 0)
if (dayTotal)
{
countDays = true;
monthTotalWorked = sumTime(monthTotalWorked, dayTotal);
}
if (countDays)
{
workingDaysToCompute += 1;

const dayIndex = new Date(this._getCalendarYear(), this._getCalendarMonth(), day).getDay();
workingDaysToCompute.push(dayIndex);
}
}
const monthTotalToWork = multiplyTime(this._getHoursPerDay(), workingDaysToCompute * -1);

const monthTotalToWork = workingDaysToCompute.reduce((total, dayIndex) =>
{
return sumTime(total, multiplyTime(this._getHoursForDay(dayIndex), -1));
}, '00:00');

const balance = sumTime(monthTotalToWork, monthTotalWorked);


const balanceElement = $('#month-balance');
if (balanceElement)
{
Expand All @@ -546,6 +566,8 @@ class FlexibleMonthCalendar extends BaseCalendar
this._updateAllTimeBalance();
}



/*
* Updates data displayed based on the database.
*/
Expand Down Expand Up @@ -630,7 +652,8 @@ class FlexibleMonthCalendar extends BaseCalendar
const dayTotal = $('#' + dateKey).parent().find(' .day-total span').html();
if (dayTotal !== undefined && dayTotal.length > 0)
{
const dayBalance = subtractTime(this._getHoursPerDay(), dayTotal);
const dayIndex = new Date(this._getTodayYear(), this._getTodayMonth(), this._getTodayDate()).getDay();
const dayBalance = subtractTime(this._getHoursForDay(dayIndex), dayTotal);
$('#leave-day-balance').html(dayBalance);
$('#leave-day-balance').removeClass('text-success text-danger');
$('#leave-day-balance').addClass(isNegative(dayBalance) ? 'text-danger' : 'text-success');
Expand Down
12 changes: 7 additions & 5 deletions src/preferences.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,16 @@
<input type="checkbox" id="saturday" name="working-days-saturday" class="weekday" />
<label for="saturday" data-i18n="$Preferences.sat">Sat</label>
</div>
<div class="flex-box">

<section>
<div class="section-title" data-i18n="$Preferences.hoursPerDay">Hours per day</div>
<div id="hours-container">
</div>
</section>
<div class="flex-box"style="margin-top: 1rem;">
<p data-i18n="$Preferences.hideNonWorkingDay">Hide non-working days (Month View)</p>
<label id='non-working-label' class="switch"><input type="checkbox" name="hide-non-working-days"><span class="slider round"></span></label>
</div>
<div class="flex-box">
<p data-i18n="$Preferences.hoursPerDay">Hours per day</p>
<input data-i18n="[placeholder]$Preferences.hours-per-day;[oninvalid]$Generic.hours-on-invalid" type="text" name="hours-per-day" id="hours-per-day" maxlength=5 pattern="^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$" value="08:00" size=5 required oninput="this.setCustomValidity('');this.reportValidity()" onblur="this.value = this.checkValidity() ? this.value : '08:00';this.setCustomValidity('')">
</div>
<div class="flex-box">
<p><i class="fas fa-utensils"></i><span data-i18n="$Preferences.enablePrefillBreakTime">Enable prefilling of break time</span></p>
<label class="switch"><input type="checkbox" id='enable-prefill-break-time' name="enable-prefill-break-time"><span class="slider round"></span></label>
Expand Down
Loading