Last active
January 12, 2016 18:59
-
-
Save megawertz/5587042 to your computer and use it in GitHub Desktop.
Gets unbilled hours from Freshbooks and formats them into a CSV for Panic's Status Board app. This only shows unbilled totals per project. It suits my needs but yours will probably differ.
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
// Get unbilled hours from Freshbooks and show them in Panic's Status Board | |
// This assumes A LOT and is built for my usage. YMMV. | |
var sys = require('sys'); | |
var fs = require('fs'); | |
var exec = require('child_process').exec; | |
var parseString = require('xml2js').parseString; | |
var projListChild, timeEntryListChild; | |
var apiToken = "yourkeyhere"; | |
var apiEndPoint = "https://yourendpointurl.freshbooks.com/api/2.1/xml-in"; | |
// Assuming that I won't have more than 25 active projects and 50 unbilled entries | |
var projectListXMLRequest = '<?xml version="1.0" encoding="utf-8"?><request method="project.list"></request>'; | |
var timeEntryListXMLRequest = '<?xml version="1.0" encoding="utf-8"?><request method="time_entry.list"><per_page>50</per_page></request>'; | |
var curlBaseCMD = 'curl -u ' + apiToken + ':X ' + apiEndPoint + ' -d '; | |
var statusBoardOutputFile = "/Path/To/Your/Dropbox/Public/StatusBoard/fb.csv" | |
projListChild = exec(curlBaseCMD + "'" + projectListXMLRequest + "'", function(error, stdout, stderr) { | |
var projects = new Array(); | |
// Grab all active projects and put them in the array | |
if(error === null) { | |
parseString(stdout, function (err, result) { | |
var response = result.response; | |
var allProjects = response.projects[0].project; | |
for(var i = 0 ; i < allProjects.length ; i++) { | |
var tmp = {}; | |
tmp.projectName = allProjects[i].name[0]; | |
tmp.projectID = allProjects[i].project_id[0]; | |
tmp.rate = allProjects[i].rate[0]; | |
projects.push(tmp); | |
} | |
}); | |
} | |
else { | |
console.log(error); | |
} | |
// This grabs the last 50 entries and includes active and inactive projects | |
// Could filter out inactive projects here, did it in generateStatusBoard() for some reason | |
timeEntryListChild = exec(curlBaseCMD + "'" + timeEntryListXMLRequest + "'", function(error, stdout, stderr) { | |
if(error === null) { | |
var totals = {}; | |
parseString(stdout, function (err, result) { | |
var response = result.response; | |
var allTimeEntries = response.time_entries[0].time_entry; | |
console.log(allTimeEntries); | |
for(var i = 0 ; i < allTimeEntries.length ; i++) { | |
if(allTimeEntries[i].billed[0] === '0') { | |
if(totals[allTimeEntries[i].project_id[0]] === undefined) { | |
totals[allTimeEntries[i].project_id[0]] = 0; | |
} | |
totals[allTimeEntries[i].project_id[0]] += parseFloat(allTimeEntries[i].hours[0]); | |
} | |
} | |
generateStatusBoard(totals, projects); | |
}); | |
} | |
else { | |
console.log(error); | |
} | |
}); | |
}); | |
// Only gets values for active projects, no limit | |
function generateStatusBoard(entryTotals, projects) { | |
//console.log("Generating Status board"); | |
// just uses CSV | |
var csv = "80%,20%\n"; | |
for(var i = 0 ; i < projects.length ; i++) { | |
csv += projects[i].projectName + ","; | |
var id = projects[i].projectID; | |
if(entryTotals[id] !== undefined) { | |
csv += entryTotals[id] + "\n"; | |
} | |
else { | |
csv += 0 + "\n"; | |
} | |
} | |
fs.writeFile(statusBoardOutputFile, csv, function(err) { | |
if(err) { | |
console.log(err); | |
} | |
}); | |
//console.log(csv); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment