Have been on travel once again, and really found filling the ThoughtWorks T&E expense form is really painful.
So I spent some time to refine the scripts that wrote last year when I was on Travel, which could be stimulate the pain when filing the form.
Post and managed as Gist
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
// Script to add empty rows in activity | |
(function($){ | |
function addRows(moreRow) { | |
var $addRow = $(containerId+' [alt=Addrow_button]:first') | |
var $spinner = $(containerId+' img[alt=Ajax-loader]').parent() | |
var totalRows = $(containerId + ' td select[id$=category]').length + moreRow; | |
function needAddRow(){ | |
var result = $(containerId + ' td select[id$=category]').length < totalRows | |
console.log('need more row ' + result); | |
return result | |
} | |
function addRow() { | |
$addRow.click(); | |
setTimeout(wait, 200); | |
} | |
function wait(){ | |
if($spinner.is(':hidden')){ | |
if(needAddRow()){ | |
console.log('add row') | |
addRow(); | |
} | |
else{ | |
alert('done'); | |
} | |
} | |
else { | |
console.log('wait') | |
setTimeout(wait,200); | |
} | |
} | |
if(needAddRow()){ | |
addRow(); | |
} | |
else{ | |
alert('done'); | |
} | |
} | |
var containerId = '#activities_0_area' | |
addRows(10); | |
})(jQuery); |
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
/* Script to complete texi entries | |
* Entries must be in first activity | |
* Manually filling the date amount and date, script will finish the rest | |
* | |
* Syntax sugar: | |
* Date: Suppose today is 2013-06-01 | |
* #: Explained as day of month: 5 -> 5 JUN 2013 | |
* #/# or #-#: Explained as month and day: 5-3 -> 3 MAY 2013 | |
* Amount: | |
* Expression: Expression will be evaluated: 23 + 55 -> 78 | |
* Syntax Sugar: space between numbers will be explained as '+': 2 8 5 -> 2+8+5 -> 15 | |
*/ | |
(function($){ | |
var DAY_PATTERN = /(\d+)/; | |
var MONTH_DAY_PATTERN = /(\d+)[-\/](\d+)/ | |
var MONTH_NAMES = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'APR', 'SEP', 'OCT', 'NOV', 'DEC']; | |
var today = new Date(); | |
var THIS_YEAR = today.getFullYear(); | |
var THIS_MONTH = MONTH_NAMES[today.getMonth()]; | |
function fillColumnIfEmpty($row, selector, value) { | |
var $field = $row.find(selector); | |
if($field.val() == '') { | |
$row.find(selector).val(value).change(); | |
} | |
} | |
$('#activities_0_table .date_column').each(function(i){ | |
var $row = $(this).parents('tr'); | |
if ($row.find('td input[id$=amount]').val()) { | |
fillColumnIfEmpty($row, 'td select[id$=category]', 'EXPLTRAN'); | |
fillColumnIfEmpty($row, 'td select[id$=currency]', 'CNY'); | |
fillColumnIfEmpty($row, 'td input[id$=description]', 'Texi'); | |
fillColumnIfEmpty($row, 'td input[id$=vendor]', 'N/A'); | |
fillColumnIfEmpty($row, 'td select[id$=payment]', 'PMTPERS'); | |
var $dateField = $row.find('td input[id$=date_string]'); | |
var dateString = $dateField.val(); | |
var match, fullDate; | |
if(match = dateString.match(DAY_PATTERN)) { | |
fullDate = [match[1], THIS_MONTH, THIS_YEAR].join(' '); | |
$dateField.val(fullDate).change(); | |
} | |
if(match = dateString.match(MONTH_DAY_PATTERN)) { | |
var monthIndex = parseInt(match[1], 10) - 1; | |
fullDate = [match[2], MONTH_NAMES[monthIndex] , THIS_YEAR].join(' '); | |
$dateField.val(fullDate).change(); | |
} | |
var $amount = $row.find('td input[id$=amount]'); | |
var amountValue = $amount.val().trim(); | |
amountValue = amountValue.replace(/ /g, '+'); | |
amountValue = eval(amountValue); | |
$amount.val(amountValue).change(); | |
} | |
}); | |
})(jQuery); |
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
/* Script to delete entries from start date to next a number of days | |
*/ | |
(function($){ | |
function deleteRows() { | |
for(var i = 0; i < days; i++) { | |
var today = new Date(); | |
today.setDate(startDate.getDate() + i); | |
todayText = today.toFormattedString(); | |
if(today.getDate() < 10){ | |
todayText = '0' + todayText; | |
} | |
var targetRows = $(containerId + ' input[type="text"][value="' + todayText + '"]').parents('tr'); | |
var buttons = targetRows.find('img[id][alt=Delete]'); | |
rowCount = buttons.length; | |
console.log("Found "+ rowCount +"rows, deleting..."); | |
buttons.click(); | |
alert(rowCount + "row(s) are deleted."); | |
} | |
} | |
var containerId = "#activities_1_area" | |
var startDate = new Date('2012-9-30'); | |
var days = 8; | |
deleteRows(); | |
})(jQuery); |
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
// Script to generate per diem entries from start date to stop date. | |
// Filling all entries into second activity, which is needed to be created manually | |
(function($){ | |
function tomorrow(today){ | |
var date = new Date(today); | |
date.setDate(date.getDate() + 1); | |
return date | |
} | |
function addRows() { | |
var $addRow = $(containerId+' [alt=Addrow_button]:first') | |
var $spinner = $(containerId+' img[alt=Ajax-loader]').parent() | |
function needAddRow(){ | |
var result = $(containerId + ' td select[id$=category]').length < items.length | |
console.log('need more row ' + result); | |
return result | |
} | |
function addRow() { | |
$addRow.click(); | |
setTimeout(wait, 200); | |
} | |
function wait(){ | |
if($spinner.is(':hidden')){ | |
if(needAddRow()){ | |
console.log('add row') | |
addRow(); | |
} | |
else{ | |
console.log('fill data') | |
fillData(); | |
} | |
} | |
else { | |
console.log('wait') | |
setTimeout(wait,200); | |
} | |
} | |
if(needAddRow()){ | |
addRow(); | |
} | |
else{ | |
fillData(); | |
} | |
} | |
function fillData() { | |
$(containerId + ' .date_column').each(function(i){ | |
var $row = $(this).parents('tr'); | |
var amount = items[i].amount; | |
var date = items[i].date; | |
var desc = items[i].desc; | |
$row.find('td select[id$=category]').val('EXPSTIPEND').change(); | |
$row.find('td input[id$=date_string]').val(date).change(); | |
$row.find('td input[id$=amount]').val(amount).change(); | |
$row.find('td select[id$=currency]').val('CNY').change(); | |
$row.find('td input[id$=description]').val(desc).change(); | |
$row.find('td input[id$=vendor]').val('N/A').change(); | |
$row.find('td select[id$=payment]').val('PMTPERS').change(); | |
}); | |
} | |
var items = []; | |
function addItem(date, amount, desc) { | |
items.push({ | |
date: date.toFormattedString(), | |
amount: amount, | |
desc: desc | |
}); | |
} | |
function buildItems(startDate, stopDate){ | |
var current = startDate; | |
while(current.getTime() <= stopDate.getTime()) { | |
addItem(current, 150, "Travel Pay"); | |
if(current.getDay() % 6 == 0) { // is weekend | |
addItem(current, 200, "Weekend Travel Pay"); | |
} | |
current = tomorrow(current); | |
} | |
addRows(); | |
} | |
var containerId = "#activities_1_area" | |
var startDate = new Date('2013-06-04'); | |
var stopDate = new Date('2013-06-21'); | |
buildItems(startDate, stopDate); | |
})(jQuery); |