Skip to content

Instantly share code, notes, and snippets.

@lackac
Created March 8, 2010 13:47
Show Gist options
  • Save lackac/325171 to your computer and use it in GitHub Desktop.
Save lackac/325171 to your computer and use it in GitHub Desktop.
GM script for Pivotal Tracker to calculate payment for each release by accumulating points and hours above it.
// ==UserScript==
// @name Release payment
// @namespace http://lackac.hu
// @description Calculates payment for each release by accumulating points and hours above it.
// @include https://www.pivotaltracker.com/projects/*
// ==/UserScript==
var POINT_RATE = 12000, HOURLY_RATE = 6000, CURRENCY = '% Ft';
var GM_JQ = document.createElement('script');
GM_JQ.src = 'http://jquery.com/src/jquery-latest.js';
GM_JQ.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(GM_JQ);
(function() {
if (typeof unsafeWindow.jQuery == 'undefined') {
window.setTimeout(arguments.callee, 100);
} else {
unsafeWindow.jQuery.noConflict();
ReleasePayment(unsafeWindow.jQuery);
}
})();
function ReleasePayment($, app) {
function calculatePayment(panel) {
var devs = {nobody: {points: 0, hours: 0}};
var lastItemType = $('#'+panel.id+' .storyItem:last .storyTypeIcon').attr('alt');
if (lastItemType != "Release") {
var tempRelease = $('<div class="item"><div class="storyItem unstarted notUnderEdit releaseMarkerNotAccepted"><div class="storyPreviewHeader"><div class="icons"><div class="left"><img src="/images/v3/icons/stories_view/release_icon.png" class="storyTypeIcon" alt="Release"><img width="6" src="/images/v3/icons/stories_view/estimate_0pt_powers_of_2.gif" class="estimateIcon"></div></div><div class="storyPreviewText"></div></div></div></div>');
$('#'+panel.id+' .items .endOfList').before(tempRelease);
}
$('#'+panel.id+' .storyItem').each(function() {
var type = $('.storyTypeIcon', this).attr('alt'), dev, pair,
initials = $('.storyPreviewText', this).text().match(/\(([A-Z][A-Z])([A-Z][A-Z])?\)/);
if (initials) {
if (!devs[initials[1]]) {
devs[initials[1]] = {points: 0, hours: 0};
}
dev = devs[initials[1]];
if (initials[2]) {
if (!devs[initials[2]]) {
devs[initials[2]] = {points: 0, hours: 0};
}
pair = devs[initials[2]];
}
} else {
dev = devs.nobody;
}
if (type == 'Feature') {
var estimate = $('.estimateIcon', this).attr('alt'), m;
if (m = estimate.match(/(\d+) points/)) {
if (!pair) {
dev.points += parseInt(m[1]);
} else {
dev.points += parseInt(m[1])/2;
pair.points += parseInt(m[1])/2;
}
}
} else if (type == 'Chore') {
var text = $('.storyPreviewText', this).text(), m;
if (m = text.match(/\[(\d+)h\]/)) {
if (!pair) {
dev.hours += parseInt(m[1]);
} else {
dev.hours += parseInt(m[1])/2;
pair.hours += parseInt(m[1])/2;
}
}
} else if (type == 'Release') {
for (var initial in devs) {
var dev = devs[initial];
if (dev.points == 0 && dev.hours == 0) continue;
var total = CURRENCY.replace('%', dev.points * POINT_RATE + dev.hours * HOURLY_RATE);
var previewText = $('.storyPreviewText', this);
var calculationText = initial+': Pts: '+dev.points+', Hrs: '+dev.hours+', Total: '+total;
var div = $('.calculation.'+initial, previewText);
if (div.length > 0) {
div.text(calculationText);
} else {
var div = $('<div/>', {
'class': 'calculation '+initial,
css: {},
text: calculationText
});
previewText.append(div);
}
dev.points = dev.hours = 0;
}
}
});
}
function linkForPanel(panelName) {
var link = $('<a/>', {
text: "Calculate "+panelName,
'class': 'button',
css: {
position: 'relative', height: '19px',
'margin-left': '10px',
'background-repeat': 'repeat-x',
cursor: 'pointer'
},
click: function(e) {
e.preventDefault();
var app = unsafeWindow.app, panel, withTimeout = false;
for (var p in app.layout.panels) {
if (app.layout.panels[p].type == panelName) {
panel = app.layout.panels[p];
break;
}
}
if (!panel) {
panel = app.layout.openPanel(panelName);
withTimeout = true;
}
if (panelName == "done") {
panel.expandAll();
}
setTimeout(function() {calculatePayment(panel);}, withTimeout ? 500 : 0);
}
}).insertBefore('#buttonPanel .spacer:last')
.append($('<span/>', {'class': 'top_left'}))
.append($('<span/>', {'class': 'top_right'}))
.append($('<span/>', {'class': 'bottom_left'}))
.append($('<span/>', {'class': 'bottom_right'}));
}
linkForPanel("done");
linkForPanel("current");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment