Last active
April 30, 2018 07:24
-
-
Save bobbzorzen/cca44208ad03501bd5e36a7ea3c101c9 to your computer and use it in GitHub Desktop.
A greasemonkey/tampermonkey script to fetch times from ticketeer and auto report to maconomy
This file contains 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 Ticketeer Timesheet Integration Dev | |
// @namespace my.Home | |
// @version 1.0 | |
// @description Makes your life better one friday at a time | |
// @author Tommy Svenningsson | |
// @grant none | |
// @match https://ter.istone.com/cgi-bin/Maconomy/* | |
// @require https://code.jquery.com/jquery-3.1.1.min.js | |
// ==/UserScript== | |
var apiKey = 'xxxx'; | |
var user = '[email protected]'; | |
var pass = 'xxxx'; | |
var debug = false; | |
var ticketeerTimers, doc, weekDates, addedTimeIds; | |
window.onload = function(){ | |
if (apiKey === ""){return;} | |
checkDOMChange(); | |
}; | |
function checkDOMChange() | |
{ | |
for (var i = 0; i < window.frames.length; i++) { | |
(function(frame) { | |
// called whenever a frame is loaded or reloaded | |
if(frame.getAttribute("name") == "componentframe"){ | |
doc = $(frame.contentDocument || frame.contentWindow.document); | |
scrapeDates(frame); | |
} | |
})(window.frames[i].frameElement); | |
} | |
} | |
function findRow(timer){ | |
var row = false; | |
doc.find("#timeSheetTable tbody").children().each(function(){ | |
var rowFavourite = $(this).find("input[title='"+timer.board_name+"']"); | |
var rowDescription = $(this).find("input[title='"+timer.task_name+"']"); | |
if(rowFavourite.length && rowDescription.length){ | |
row = $(this); | |
} | |
}); | |
return row; | |
} | |
function scrapeDates(frame){ | |
var timeTable = doc.find("#timeSheetTable"); | |
var datePicker = doc.find("#calendar"); | |
datePicker.bind("DOMSubtreeModified",function(){ | |
if(datePicker.find("span.selected")[0]){ | |
var startDate = datePicker.find("span.selected span").attr("onclick").match(/.*?(\d+\.\d+\.\d+).*?/)[1].replace(/[.]/g,"-"); | |
var endDate = datePicker.find("span.selected").parent().siblings(".days").last().find(".clickable").attr("onclick").match(/.*?(\d+\.\d+\.\d+).*?/)[1].replace(/[.]/g,"-"); | |
loadTimers(startDate, endDate); | |
weekDates = getDates(new Date(startDate), new Date(endDate)); | |
} | |
}); | |
} | |
function loadTimers(startDate, endDate){ | |
$.ajax ( { | |
type:'POST', | |
url:'https://www.ticketeer.se/api/get_time_report', | |
dataType:'json', | |
data:{key:apiKey, fromDate:startDate, toDate:endDate}, | |
beforeSend: function (xhr){ | |
xhr.setRequestHeader("Authorization", "Basic " + btoa(user + ":" + pass)); | |
}, | |
success:function(data){ | |
doc.find("#updateTimes").parent().parent().remove(); | |
if (data.length > 0){ | |
var hours = 0; | |
ticketeerTimers = sortJsonArray(data, "task_id"); | |
$.each(data, function( index, timer ) { | |
hours += timer.hours; | |
}); | |
var ticketeerButtonHTML = '<td class="button"><div><input type="button" id="updateTimes" value="Add '+hours+' hours from ticketeer"></div></td>'; | |
doc.find(".innerArea .buttonsTop .button").parent().append(ticketeerButtonHTML); | |
doc.find("#updateTimes").on("click", function(){ | |
$(this).prop('value', "Working, please don't touch anything"); | |
$(this).prop('disabled', true); | |
addedTimeIds = new Array(); | |
populateTimesheet(0,null); | |
}); | |
} | |
} | |
}); | |
} | |
function populateTimesheet(index, prevTaskId){ | |
var timeSheet = doc.find("#timeSheetTable"); | |
var newRowButton = timeSheet.find("th.rowAction .button"); | |
var inputs, timer, arrPos, existingRow; | |
if(index < ticketeerTimers.length){ | |
timer = ticketeerTimers[index]; | |
arrPos = $.inArray(timer.date,weekDates); | |
existingRow = findRow(timer); | |
if(timer.task_id == prevTaskId){ | |
echo("Adding time to same row"); | |
inputs = doc.find("#timeSheetTable tr.selected").children(); | |
echo(inputs); | |
if(inputs.length > 0){ | |
$(inputs[6+arrPos]).find("input").val(timer.hours); | |
$(inputs[6+arrPos]).find("input").attr("title", timer.hours); | |
addedTimeIds.push(timer.id); | |
checkTimer(timer.id); | |
} | |
populateTimesheet(index+1, timer.task_id); | |
}else if(existingRow){ | |
echo("Adding to another existing row"); | |
inputs = existingRow.children(); | |
if(inputs.length > 0){ | |
var timeInput = $(inputs[6+arrPos]).find("input"); | |
timeInput.focus(); | |
var selectCheck = window.setInterval(function(){ | |
if(timeInput.closest("tr").hasClass("selected")){ | |
timeInput.val(timer.hours); | |
timeInput.attr("title", timer.hours); | |
addedTimeIds.push(timer.id); | |
checkTimer(timer.id); | |
populateTimesheet(index+1, timer.task_id); | |
timeInput.trigger("keypress"); | |
clearInterval(selectCheck); | |
} | |
}, 100); | |
} | |
}else{ | |
echo("Adding new row for task_id:"+timer.task_id); | |
newRowButton.trigger("click"); | |
doc.one("focus", "input", function() { | |
var favouriteField = $(this); | |
echo(favouriteField); | |
if(favouriteField[0]){ | |
favouriteField.attr("title",timer.board_name); | |
favouriteField.val(timer.board_name); | |
var e = $.Event('keypress'); | |
e.which = 13; | |
setTimeout(function() { | |
favouriteField.trigger(e); | |
doc.one("DOMSubtreeModified","#timeSheetTable", function(){ | |
setTimeout(function() { | |
var inputs = doc.find("#timeSheetTable tr.selected").children(); | |
if(inputs.length > 0){ | |
$(inputs[6+arrPos]).find("input").val(timer.hours); | |
$(inputs[6+arrPos]).find("input").attr("title", timer.hours); | |
$(inputs[17]).find("input").val(timer.task_name); | |
addedTimeIds.push(timer.id); | |
checkTimer(timer.id); | |
} | |
populateTimesheet(index+1,timer.task_id); | |
},100); | |
}); | |
}, 100); | |
} | |
}); | |
} | |
}else{ | |
setTimeout(function() { | |
alert(addedTimeIds.length+' of '+ticketeerTimers.length+" entries successfully added!"); | |
}, 100); | |
echo(addedTimeIds); | |
doc.find("#updateTimes").parent().parent().remove(); | |
} | |
} | |
function checkTimer(timerId){ | |
$.ajax ( { | |
type:'POST', | |
url:'https://www.ticketeer.se/api/check_timer', | |
dataType:'json', | |
data:{key:apiKey, timerId:timerId}, | |
beforeSend: function (xhr){ | |
xhr.setRequestHeader("Authorization", "Basic " + btoa(user + ":" + pass)); | |
}, | |
success:function(data){ | |
echo(data); | |
} | |
}); | |
} | |
function getFormatedDate(date) { | |
var dd = date.getDate(); | |
var mm = date.getMonth()+1; //January is 0! | |
var yyyy = date.getFullYear(); | |
if(dd<10){ | |
dd='0'+dd; | |
} | |
if(mm<10){ | |
mm='0'+mm; | |
} | |
var today = yyyy +'-'+ mm +'-'+ dd; | |
return today; | |
} | |
function getDates(startDate, stopDate) { | |
var dateArray = new Array(); | |
var datePicker = doc.find("#calendar"); | |
var currentDate = startDate; | |
var pos = 0; | |
while (currentDate <= stopDate) { | |
var currentTd = datePicker.find("span.selected").parent().siblings("td").eq(pos); | |
var isWorkday = currentTd.hasClass('days'); | |
if(isWorkday){ | |
dateArray[pos] = getFormatedDate(currentDate); | |
}else{ | |
dateArray[pos] = null; | |
} | |
currentDate = currentDate.addDays(1); | |
pos ++; | |
} | |
return dateArray; | |
} | |
Date.prototype.addDays = function(days) { | |
var dat = new Date(this.valueOf()); | |
dat.setDate(dat.getDate() + days); | |
return dat; | |
}; | |
Date.prototype.reverseDays = function(days) { | |
var dat = new Date(this.valueOf()); | |
dat.setDate(dat.getDate() - days); | |
return dat; | |
}; | |
function echo(logString){ | |
if(debug){ | |
console.log(logString); | |
} | |
} | |
function sortJsonArray(arr, prop) { | |
arr = arr.sort(function(a, b) { | |
return (b[prop] > a[prop]) ? 1 : ((b[prop] < a[prop]) ? -1 : 0); | |
}); | |
return arr; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment