NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Attendo_ba_daily_work_time_extended // @namespace http://tampermonkey.net/ // @version 0.38 // @license MIT // @description Add missing work timer for current day to attendo.ba. Extended with monthly summary and daily pause display. // @author Bootta // @match https://attendo.ba/attendo/app/entry // @require https://code.jquery.com/jquery-3.3.1.min.js // @updateURL https://openuserjs.org/meta/Bootta11/Attendo_ba_daily_work_time_extended.meta.js // ==/UserScript== (function () { 'use strict'; let entries_refresh_interval_in_seconds = 300; let enable_time_without_pause = true; let $ = window.jQuery; let worklog_entries; let checkedout_time_periods_sum = 0; let open_time_period_start; let mandatory_break = 30 * 60 * 1000; let mandatory_break_left = mandatory_break; let meal_break_sum = 0; let refresh_enteries_interval; let today = new Date(); let dd = today.getDate(); let mm = today.getMonth() + 1; //January is 0! let yyyy = today.getFullYear(); let today_datetime_string = yyyy + '-' + aln(mm) + '-' + aln(dd); let daily_work_time_element = ` <li id="daily_work_timer_holder" > <a href="#" onclick="return false" disabled id='daily_time_holder' style="hidden:true"> Today worked: <big><span id="daily_work_timer" style="color: black"></span></big> </a> <a href="#" onclick="return false" disabled id='plus_minus_holder' style='hidden:true'> <span id="plus_or_minus"></span><big><span style="color: black" id='plus_minus_timer'></span></big> </a> </li>`; let plus_minus_worked_ms = 0; let cumulative_daily_time, previous_cumulative_daily_time = 0; let wanted_time = 0; let timer_is_running = false; refreshEnteries(function () { getMonthlySummary(); }); refresh_enteries_interval = setInterval(refreshEnteries, 1000 * entries_refresh_interval_in_seconds); setInterval(refreshDailyWorkTime, 1000); $('.navbar .navbar-right').prepend(daily_work_time_element); $('#daily_time_holder').mouseenter(function () { $('#daily_time_holder').hide(); $('#plus_minus_holder').show(); $('#plus_minus_holder').css('width', '350px'); $('#plus_minus_holder').attr('align', 'center'); }) $('#plus_minus_holder').mouseout(function (event) { if ($.contains(this, event.relatedTarget) || this == event.relatedTarget) { return; } $('#daily_time_holder').show(); $('#daily_time_holder').css('width', '350px') $('#daily_time_holder').css('text-align', 'center') $('#daily_time_timer').css('display', 'block') $('#plus_minus_holder').hide(); }) $('#plus_minus_holder').hide(); function refreshDailyWorkTime() { if (worklog_entries) { cumulative_daily_time = checkedout_time_periods_sum; if (open_time_period_start) { let open_time_period_current_datetime = new Date(); cumulative_daily_time += Math.abs(open_time_period_current_datetime - open_time_period_start); } let cumulative_daily_time_without_pause = cumulative_daily_time - (1000 * 60 * 30); //console.log(tsToDisplayTime(plus_minus_worked_ms), tsToDisplayTime(cumulative_daily_time), tsToDisplayTime(wanted_time), tsToDisplayTime(mandatory_break_left), timer_is_running, tsToDisplayTime(cumulative_daily_time - wanted_time - mandatory_break_left),tsToDisplayTime(plus_minus_worked_ms)); let monthly_time = plus_minus_worked_ms + (timer_is_running ? (cumulative_daily_time - wanted_time - mandatory_break_left) : 0); $('#plus_minus_timer').text(tsToDisplayTime(monthly_time)); $('#plus_or_minus').html('Monthly (' + (plus_minus_worked_ms >= 0 ? 'plus: ' : 'minus: ') + tsToDisplayTime(plus_minus_worked_ms) + '): '); var seconds = Math.floor(((cumulative_daily_time % (1000 * 60)) / 1000)); var minutes = Math.floor(((cumulative_daily_time % (1000 * 60 * 60)) / (1000 * 60))); var hours = Math.floor((cumulative_daily_time / (1000 * 60 * 60))); let display_time = tsToDisplayTime(cumulative_daily_time); let mandatory_minutes = Math.floor(((mandatory_break_left % (1000 * 60 * 60)) / (1000 * 60))); let mandatory_seconds = Math.floor(((mandatory_break_left % (1000 * 60)) / 1000)); display_time += (enable_time_without_pause ? '(-' + (aln(mandatory_minutes) + ' : ' + aln(mandatory_seconds)) + 'min)' : ''); $('#daily_work_timer').text(display_time); previous_cumulative_daily_time = cumulative_daily_time; } } function refreshEnteries(callback) { checkedout_time_periods_sum = 0; $.get('https://attendo.ba/attendo/app/api/employee/overview/daily?date=' + today_datetime_string, function (data) { worklog_entries = data.entries; if (data.calculation && data.calculation.summary && data.calculation.summary.wantedTime) { wanted_time = parsePTInterval(data.calculation.summary.wantedTime); } if (worklog_entries && worklog_entries.length > 0) { for (let i = 0; i < worklog_entries.length; i++) { let entry = worklog_entries[i]; if (entry.entryType == "CHECK_IN") { let check_in_start_datetime = new Date(entry.dateTime); let check_in_end_datetime = new Date(); if (worklog_entries[i + 1]) { check_in_end_datetime = new Date(worklog_entries[i + 1].dateTime); checkedout_time_periods_sum += Math.abs(check_in_end_datetime - check_in_start_datetime); } else { open_time_period_start = check_in_start_datetime; } } else if (entry.entryType == "MEAL_BREAK") { let meal_break_start_datetime = new Date(entry.dateTime); let meal_break_end_datetime = new Date(); if (worklog_entries[i + 1]) { meal_break_end_datetime = new Date(worklog_entries[i + 1].dateTime); meal_break_sum += Math.abs(meal_break_end_datetime - meal_break_start_datetime); if (meal_break_sum <= mandatory_break) { mandatory_break_left -= meal_break_sum; } else { mandatory_break_left = 0; } } } } if (open_time_period_start) { timer_is_running = true; } let cumulative_daily_time_without_pause = checkedout_time_periods_sum - (1000 * 60 * 30); } else { mandatory_break_left = 0; } callback(); }); } //add leading null function aln(n) { return (n < 10 ? '0' + n : n); } // timestamp to time function tsToDisplayTime(ts) { let minus = ''; if (ts < 0) { minus = '-'; ts = ts * -1; } var seconds = Math.floor(((ts % (1000 * 60)) / 1000)); var minutes = Math.floor(((ts % (1000 * 60 * 60)) / (1000 * 60))); var hours = Math.floor((ts / (1000 * 60 * 60))); return minus + aln(hours) + ' : ' + aln(minutes) + ' : ' + aln(seconds); } function parsePTInterval(pt_interval) { var reptms = /^PT(?:([0-9\-]+)H)?(?:([0-9\-]+)M)?(?:([0-9\-]+)S)?$/; let hours = 0, minutes = 0, seconds = 0, totalseconds = 0; if (reptms.test(pt_interval)) { var matches = reptms.exec(pt_interval); if (matches[1]) hours = Number(matches[1]); if (matches[2]) minutes = Number(matches[2]); if (matches[3]) seconds = Number(matches[3]); totalseconds = hours * 3600 + minutes * 60 + seconds; } return totalseconds * 1000; } function getMonthlySummary() { var date = new Date(); var firstDayOfMonth = formatDateForQuery(new Date(date.getFullYear(), date.getMonth(), 1)); var lastDayOfMonth = formatDateForQuery(new Date(date.getFullYear(), date.getMonth() + 1, 0)); $.get('https://attendo.ba/attendo/app/api/employee/overview/period?page=0&size=40&fromDate=' + firstDayOfMonth + '&toDate=' + lastDayOfMonth, function (data) { for (let i = 0; i < data.rows.length; i++) { if (timer_is_running && i == (data.rows.length - 1)) { continue; } plus_minus_worked_ms += parsePTInterval(data.rows[i].calculation.summary.difference); } }); } function formatDateForQuery(input_date) { let dd = input_date.getDate(); let mm = input_date.getMonth() + 1; //January is 0! let yyyy = input_date.getFullYear(); return yyyy + '-' + aln(mm) + '-' + aln(dd); } })();