Last active
February 12, 2020 12:43
-
-
Save pquerner/9145e193b2970b84a1d18447642124f2 to your computer and use it in GitHub Desktop.
KBMPro Timetracking JS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name KBMpro quick buttons for time tracking | |
// @namespace http://www.concept-design.de | |
// @updateUrl https://bitbucket.concept-design.de/snippets/raw/c3688c4bcaae441dae1216edf6bd31e2/kbmpro-quickbuttons.user.js | |
// @version 1.2 | |
// @description Adds quick buttons to KBMpro time tracking | |
// @author Daniel Mann (fork PQ) | |
// @match https://cundd.kbmpro.de/kbmpro/index.php?action=zeiten* | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
function runde(x, n) { | |
if (n < 1 || n > 14) return false; | |
var e = Math.pow(10, n); | |
var k = (Math.round(x * e) / e).toString(); | |
if (k.indexOf('.') == -1) k += '.'; | |
k += e.toString().substring(1); | |
return k.substring(0, k.indexOf('.') + n+1); | |
} | |
function interpolate(theString, argumentArray) { | |
var regex = /%s/; | |
var _r=function(p,c){return p.replace(regex,c);} | |
return argumentArray.reduce(_r, theString); | |
} | |
Date.prototype._formatDateCuD = function() { | |
var tmp = new Date(this.valueOf()); | |
var mm = tmp.getMonth() + 1; | |
if (mm < 10) mm = "0" + mm; | |
var dd = tmp.getDate(); | |
if (dd < 10) dd = "0" + dd; | |
return dd+mm+tmp.getFullYear(); | |
}; | |
var date = new Date(); | |
date.setMonth(parseInt(jQuery('#tagesuebersicht_start_inputmonth').val()-1)); | |
date.setYear(jQuery('#tagesuebersicht_start_inputyear').val()); | |
date.setDate(jQuery('#tagesuebersicht_start_inputday').val()); | |
date = date._formatDateCuD(); | |
var todayStart = jQuery('#tag_komplett_erfasst_'+date+'_start').val().toString(); | |
var todayEnde = jQuery('#tag_komplett_erfasst_'+date+'_ende').val().toString(); | |
debugger; | |
if(todayEnde.length > 0) { | |
jQuery('.sum_block_allg').append(`<tr> | |
<td>Info</td> | |
<td align="right" id="_nettoAnwesend"></td> | |
<td></td><td></td> | |
</tr`) | |
var stdstart = parseInt(todayStart.substr(0, 2), 10); | |
var minstart = parseInt(todayStart.substr(3, 5), 10); | |
if(isNaN(stdstart)) stdstart = 0; | |
if(isNaN(minstart)) minstart = 0; | |
var stdende = parseInt(todayEnde.substr(0, 2), 10); | |
var minende = parseInt(todayEnde.substr(3, 5), 10); | |
if(isNaN(stdende)) stdende = 0; | |
if(isNaN(minende)) minende = 0; | |
var stdpse = 0; | |
var minpse = parseInt(jQuery('#tag_komplett_erfasst_'+date+'_pause').val()); | |
if(isNaN(stdpse)) stdpse = 0; | |
if(isNaN(minpse)) minpse = 0; | |
if(minstart > 59 || minende > 59 || minstart < 0 || minende < 0) { | |
alert(unescape('Ung%FCltiger Minutenwert.')); | |
return false; | |
} | |
if(stdstart > 23 || stdende > 23 || stdstart < 0 || stdende < 0) { | |
alert(unescape('Ung%FCltiger Stundenwert.')); | |
return false; | |
} | |
var start = ((stdstart * 60) + minstart); | |
var ende = ((stdende * 60) + minende); | |
if(ende<=start) | |
ende = ende + (60 * 24); | |
var dauer = ende-start; | |
var stunden = dauer / 60; | |
stunden = runde(stunden, 2); | |
var gstunden = parseInt(stunden); | |
var gminuten = dauer - (gstunden*60); | |
var str = "Dauer (brutto, dez.): " + stunden + " Std.<br />"; | |
if(gstunden<10 && gstunden>0) gstunden = "0" + gstunden; | |
if(gminuten<10 && gminuten>0) gminuten = "0" + gminuten; | |
if(gstunden>-10 && gstunden<0) gstunden = "-0" + (gstunden*-1); | |
if(gminuten>-10 && gminuten<0) { gminuten = "0" + (gminuten*-1); gstunden = "-0" + (gstunden*-1);} | |
if(gminuten<-10 && gminuten>=-59) { gminuten = (gminuten*-1); gstunden = "-0" + (gstunden*-1);} | |
str += "Dauer (brutto): " + gstunden + ":" + gminuten + " H:M<br />"; | |
var pause = ((stdpse * 60) + minpse); | |
dauer = ende-start-pause; | |
if(dauer < 0) { | |
alert("Mehr Pause als Bruttodauer.\r\nGgf. Fehleingabe?"); | |
} | |
stunden = dauer / 60; | |
stunden = runde(stunden, 2); | |
gstunden = parseInt(stunden); | |
gminuten = dauer - (gstunden*60); | |
str += "Dauer (netto, dez.): " + stunden + " Std.<br />"; | |
if(gstunden<10 && gstunden>0) gstunden = "0" + gstunden; | |
if(gminuten<10 && gminuten>0) gminuten = "0" + gminuten; | |
if(gstunden>-10 && gstunden<0) gstunden = "-0" + (gstunden*-1); | |
if(gminuten>-10 && gminuten<0) { gminuten = "0" + (gminuten*-1); gstunden = "-0" + (gstunden*-1);} | |
if(gminuten<-10 && gminuten>=-59) { gminuten = (gminuten*-1); gstunden = "-0" + (gstunden*-1);} | |
str += "Dauer (netto): " + gstunden + ":" + gminuten + " H:M"; | |
jQuery('#_nettoAnwesend').append(str); | |
} | |
var timeslots = []; | |
var hoursPresent = jQuery( "td:contains('Anwesend (Netto)')" ).next().last().text().split(':')[0]; | |
var minutesPresent = jQuery( "td:contains('Anwesend (Netto)')" ).next().last().text().split(':')[1]; | |
var hoursWorked = jQuery( "td:contains('Gearbeitet')" ).next().last().text().split(':')[0]; | |
var minutesWorked = jQuery( "td:contains('Gearbeitet')" ).next().last().text().split(':')[1]; | |
var date1 = new Date(interpolate("01/17/2020 %s:%s:20",[hoursPresent, minutesPresent])); | |
date1.setMinutes(date1.getMinutes() - minutesWorked); | |
date1.setHours(date1.getHours() - hoursWorked); | |
var timeLeftHour = date1.getHours(); | |
var timeLeftMinutes = date1.getMinutes(); | |
var dailyStandup = new Timeslot(); | |
dailyStandup.title = 'Daily Standup'; | |
dailyStandup.project = '271'; | |
dailyStandup.phase = '553'; | |
dailyStandup.minutes = '10'; | |
dailyStandup.description = 'Daily Standup'; | |
dailyStandup.register(); | |
var weeklyStandup = new Timeslot(); | |
weeklyStandup.title = 'Montags-Standup'; | |
weeklyStandup.project = '271'; | |
weeklyStandup.phase = '553'; | |
weeklyStandup.minutes = '20'; | |
weeklyStandup.description = 'Wöchentliches Standup-Meeting'; | |
weeklyStandup.register(); | |
var teamMeetingDevelopment = new Timeslot(); | |
teamMeetingDevelopment.title = 'Teammeeting Development'; | |
teamMeetingDevelopment.project = '271'; | |
teamMeetingDevelopment.phase = '553'; | |
teamMeetingDevelopment.minutes = '40'; | |
teamMeetingDevelopment.description = 'Teammeeting Development'; | |
teamMeetingDevelopment.register(); | |
var leerZeit = new Timeslot(); | |
leerZeit.title = "Leerzeit Restzeit vom Tag"; | |
leerZeit.project = '271'; | |
leerZeit.phase = '557'; | |
leerZeit.activity = '1'; | |
leerZeit.hours = timeLeftHour; | |
leerZeit.minutes = timeLeftMinutes; | |
leerZeit.description = 'Leerzeit'; | |
leerZeit.register(); | |
var restZeitVWE = new Timeslot(); | |
restZeitVWE.title = "Restzeit für VWEntdecken"; | |
restZeitVWE.project = '322'; | |
restZeitVWE.phase = '842'; | |
restZeitVWE.activity = '1'; | |
restZeitVWE.hours = timeLeftHour; | |
restZeitVWE.minutes = timeLeftMinutes; | |
restZeitVWE.description = 'Umsetzung'; | |
restZeitVWE.register(); | |
var restZeitSFB = new Timeslot(); | |
restZeitSFB.title = "Restzeit für SFB"; | |
restZeitSFB.project = '306'; | |
restZeitSFB.phase = '742'; | |
restZeitSFB.activity = '1'; | |
restZeitSFB.hours = timeLeftHour; | |
restZeitSFB.minutes = timeLeftMinutes; | |
restZeitSFB.description = 'Umsetzung'; | |
restZeitSFB.register(); | |
var diverses = new Timeslot(); | |
diverses.title = 'Diverses'; | |
diverses.project = '271'; | |
diverses.phase = '558'; | |
diverses.activity = '1'; | |
diverses.minutes = '0'; | |
diverses.description = 'Diverses'; | |
diverses.register(); | |
var helfen = new Timeslot(); | |
helfen.title = 'Azubis Helfen'; | |
helfen.project = '271'; | |
helfen.phase = '554'; | |
helfen.activity = '1'; | |
helfen.minutes = '0'; | |
helfen.description = 'Azubis helfen:'; | |
helfen.register(); | |
var zeitengestern = new Timeslot(); | |
zeitengestern.title = 'Zeiten Gestern'; | |
zeitengestern.project = '271'; | |
zeitengestern.phase = '556'; | |
zeitengestern.activity = '1'; | |
zeitengestern.minutes = '10'; | |
zeitengestern.description = 'Zeiten eintragen von gestern'; | |
zeitengestern.register(); | |
var restlicheZeiten = new Timeslot(); | |
restlicheZeiten.title = 'Restzeit von Heute eintragen'; | |
restlicheZeiten.project = '271'; | |
restlicheZeiten.phase = '556'; | |
restlicheZeiten.activity = '1'; | |
restlicheZeiten.hours = timeLeftHour; | |
restlicheZeiten.minutes = timeLeftMinutes; | |
restlicheZeiten.description = 'Diverses'; | |
restlicheZeiten.register(); | |
var zeitenFr = new Timeslot(); | |
zeitenFr.title = 'Zeiten eintragen Freitag'; | |
zeitenFr.project = '271'; | |
zeitenFr.phase = '556'; | |
zeitenFr.activity = '1'; | |
zeitenFr.minutes = '10'; | |
zeitenFr.description = 'Zeiten eintragen von freitag'; | |
zeitenFr.register(); | |
/** | |
['projekt', 'leistungsart_zeit', 'phasen'].each(function(v,i) { | |
jQuery('#'+v).parent().append( "<span id='"+v+"_viewer'></span>" ); | |
jQuery('#'+v).on('change', function() { | |
jQuery('#'+v+'_viewer').html(this.value) | |
}); | |
}) | |
*/ | |
var timeSlotRow = '<tr><td> </td><td colspan="4" id="customPrefillButtons"></td></tr>'; | |
jQuery('.tableSubmit').before(timeSlotRow); | |
jQuery(timeslots).each(function(i) { | |
var timeslot = this; | |
jQuery('#customPrefillButtons').append('<button id="' + timeslot.id + '">' + timeslot.title + '</button>'); | |
if((i+1)%3==0) { jQuery('#customPrefillButtons').append('<br/>'); } | |
jQuery('#' + timeslot.id + '').on('click', {timeslot: timeslot}, function(event) { | |
prefillTimetrackingForm(event.data.timeslot); | |
event.preventDefault(); | |
}); | |
}); | |
jQuery('#customPrefillButtons').append('<br/><br/><button id="customPrefill-export">Export</button>'); | |
jQuery('#customPrefillButtons').append('<br/><br/><textarea id="exporttxt"></textarea>') | |
var jsTemplate = ` | |
var ###BUTTONNAME_var### = new Timeslot(); | |
###BUTTONNAME_var###.title = '###BUTTONNAME###'; | |
###BUTTONNAME_var###.project = '###PROJECTID###'; | |
###BUTTONNAME_var###.phase = '###PHASE###'; | |
###BUTTONNAME_var###.activity = '###ACTIVITY###'; | |
###BUTTONNAME_var###.minutes = '###MINUTES###'; | |
###BUTTONNAME_var###.hours = '###HOURS###'; | |
###BUTTONNAME_var###.description = '###DESCRIPTION###'; | |
###BUTTONNAME_var###.register(); | |
` | |
jQuery('#customPrefill-export').on('click', function(e) { | |
var btnName = prompt('Buttonname (keine Sonderzeichen!)', ''); | |
var jsVar = btnName.toLowerCase().trim().split(/[.\-_\s]/g) + '_' + Math.floor(Date.now() / 1000); | |
var _jsTemplate = jsTemplate; | |
_jsTemplate = _jsTemplate.replace(/###BUTTONNAME_var###/g, jsVar); | |
_jsTemplate = _jsTemplate.replace('###BUTTONNAME###', btnName); | |
_jsTemplate = _jsTemplate.replace('###PROJECTID###', jQuery('select#projekt').val()); | |
_jsTemplate = _jsTemplate.replace('###PHASE###', jQuery('select#phasen').val()); | |
_jsTemplate = _jsTemplate.replace('###ACTIVITY###', jQuery('select#leistungsart_zeit').val()); | |
_jsTemplate = _jsTemplate.replace('###MINUTES###', jQuery('#stop_min').val()); | |
_jsTemplate = _jsTemplate.replace('###HOURS###', jQuery('#stop_std').val()); | |
_jsTemplate = _jsTemplate.replace('###DESCRIPTION###', jQuery('#leistungsbeschreibung').val()); | |
jQuery('#exporttxt').val(_jsTemplate); | |
e.preventDefault(); | |
}); | |
function Timeslot(id, title, project, phase, activity, hours, minutes, description) { | |
this.title = title; | |
this.project = project ? project : '0'; | |
this.phase = phase ? phase : '0'; | |
this.activity = activity ? activity : '0'; | |
this.hours = hours ? hours : '0'; | |
this.minutes = minutes ? minutes : '0'; | |
this.description = description ? description : ''; | |
this.register = function() { | |
this.id = 'customPrefill-' + this.title.toLowerCase().trim().split(/[.\-_\s]/g).reduce((string, word) => string + word[0].toUpperCase() + word.slice(1));; | |
timeslots.push(this); | |
} | |
} | |
var prefillTimetrackingForm = function(timeslotItem) { | |
jQuery('select#projekt').val(timeslotItem.project).change(); // select project "Interne Meetings" | |
jQuery('select#phasen').val(timeslotItem.phase).change(); // select no phase | |
jQuery('select#leistungsart_zeit').val(timeslotItem.activity).change(); // select no activity | |
jQuery('#stop_std').val(timeslotItem.hours).change(); // duration 0 hours | |
jQuery('#stop_min').val(timeslotItem.minutes).change(); // duration 10 minutes | |
jQuery('#leistungsbeschreibung').val(timeslotItem.description).change(); // description | |
if(timeslotItem.hours > 0) { | |
jQuery('#stop_std').focus().select();; | |
} else { | |
jQuery('#stop_min').focus().select();; | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment