// ==UserScript==
// @name RFPhoenix v0.2.2
// @namespace bpchen@mit.edu
// @include https://adminappsts.mit.edu/*
// @include https://web.mit.edu/bpchen/Public/rfphoenix/rfphoenix.html
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js
// @version 1
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.deleteValue
// @grant GM.setClipboard
// ==/UserScript==
function rfphoenixKey(key) {
return 'RFPHOENIX:' + key;
}
async function rfphoenixQuery(key, promptMessage) {
console.log('query');
console.log(key);
let value = await GM.getValue(rfphoenixKey(key));
console.log(value);
if (value === undefined) {
value = prompt(promptMessage);
GM.setValue(rfphoenixKey(key), value);
}
return value;
}
function rfphoenixClear(key) {
GM.deleteValue(rfphoenixKey(key));
}
function rfphoenixSetClipboard(event, text) {
GM.setClipboard(text);
}
// rfphoenixQuery, rfphoenixClear should be defined
console.log('Loaded version ' + $.fn.jquery);
var $new_jQuery = $;
$.noConflict(true);
if ($ && $.fn && $.fn.jquery) {
console.log('Restored version ' + $.fn.jquery);
}
(async function ($) {
var GROUPS;
var groupJson = await rfphoenixQuery('GROUPS', 'Enter JSON of group data?');
try {
GROUPS = [].concat(JSON.parse(groupJson));
} catch (e) {
alert('Could not parse group data -- using a single empty group (' + groupJson + ';' + e + ')' );
GROUPS = [{}];
}
// Style buttons
var styleContent = '.rfphoenix-btn, button.rfphoenix-btn, a.rfphoenix-btn { \
display: inline-block; \
font-size: 125%; \
color: #000; \
padding: 0 0.3em; \
background-image: linear-gradient(to bottom, #FDA, #FA3); \
box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.5), 0 1px 2px rgba(0, 0, 0, 0.05); \
background-color: #E90; \
border: 1px solid #FA3; \
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); \
border-radius: 1337px; \
background-repeat: repeat-x; \
transition: background-position 0.1s ease; \
text-decoration: none; \
} \
.rfphighlight { background-color: #FDA; font-weight: bold; } \
.rfphoenix-btn:before, a.rfphoenix-btn:before { content: "\\1F525"; margin-right: 0.2em; } \
.rfphoenix-btn:hover, button.rfphoenix-btn:hover, a.rfphoenix-btn:hover { \
background-position: 0 -12px; \
box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.75), 0 1px 2px rgba(0, 0, 0, 0.5); \
text-decoration: none; \
} \
.rfphoenix-btn[disabled] { \
background-color: rgba(204, 204, 204, 0.5); \
border: 1px solid #aaa; \
background-image: none; \
box-shadow: none; \
cursor: not-allowed; \
} \
.rfphoenix-btn[disabled]:before { content: "\\1F6AB"; } \
.rfphoenix-btn[disabled]:hover { box-shadow: none; } \
.rfphoenix-btn:active, button.rfphoenix-btn:active, a.rfphoenix-btn:active { \
background-image: none; \
background-color: #E90; \
background-position: 0 0; \
box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.2); \
} \
kbd.rfphoenix { \
display: inline-block; \
border-radius: 3px; \
background-color: rgba(255, 255, 255, 0.5); \
border-bottom: 2px solid rgba(0, 0, 0, 0.5); \
margin: 0.1em 0.3em; padding: 0.1em; \
} \
em.rfphoenix-em { color: red; } \
.rfphoenix-glnum { font-weight: bold; } \
';
$('<style>' + styleContent + '</style>').appendTo('head');
$('#logo').append('<a href="https://adminappsts.mit.edu/rfp/SearchForPayeeStart.action?taxable=false" class="rfphoenix rfphoenix-btn">New RFP</a>');
$('#logo').append($makeBtn('Hide RFPhoenix').click(function () {
$('.rfphoenix').hide();
}));
$('#logo').append($makeBtn('Clear RFPhoenix data').click(function () {
if (confirm('Are you sure you want to clear data?')) {
rfphoenixClear('GROUPS');
}
}));
function $makeBtn() {
var $btn = $(document.createElement('button'));
$btn.prop('type', 'button');
$btn.prop('class', 'rfphoenix rfphoenix-btn');
$btn.append.apply($btn, arguments);
return $btn;
}
if (window.location.href.indexOf('SearchForPayee') !== -1) {
function doSkip() {
window.location = ('https://adminappsts.mit.edu/rfp/RequestRfp.action?taxable=false&mitNeedsTaxable=false&defaultPayee='
+ $('#payeeName').val());
}
var $skipKbd = $(document.createElement('kbd'));
$skipKbd.text('Ctrl-S');
$skipKbd.prop('class', 'rfphoenix');
var $skipMessage = $(document.createElement('span'));
var $skipButton = $makeBtn($skipKbd, $skipMessage);
$skipButton.click(function (event) {
doSkip();
event.preventDefault();
});
$('.portlet-section-body').eq(0).append($skipButton);
function updateSkipButton() {
var payee = $('#payeeName').val();
$skipMessage.text('Skip to payee "' + payee + '"');
$skipButton.prop('disabled', payee === '' ? 'disabled' : '');
}
updateSkipButton();
$('#payeeName').keyup(function (event) {
updateSkipButton();
if (event.ctrlKey || event.metaKey) {
switch (String.fromCharCode(event.which).toLowerCase()) {
case 's':
event.preventDefault();
doSkip();
}
}
});
}
if (window.location.href.indexOf('RequestRfp') !== -1
|| window.location.href.indexOf('InboxDrillDown') !== -1
|| window.location.href.indexOf('SaveRfp') !== -1) {
var $lineItemPortletSectionBody = $('#line-0').parent();
function addButton(group, label, glnum) {
var $b = $makeBtn(group.name, ' ', label, ' ',
'<code class="rfphoenix rfphoenix-glnum">(' + glnum + ')</code>');
$b.click(function (event) {
event.preventDefault();
$('.portlet-form-input-field.GL.mediumInput.ac_input').val(glnum);
if (group.costObject !== undefined) {
$('.portlet-form-input-field.mediumInput[maxlength=12]').val(group.costObject);
}
});
$lineItemPortletSectionBody.append($b, ' ');
}
GROUPS.forEach(function (group) {
console.log('adding buttons for');
console.log(group);
if (group.gls && group.gls.forEach) {
console.log(group.gls);
group.gls.forEach(function (gl) {
console.log('adding button for');
console.log(gl);
// gl[0] description, gl[1] G/L number
addButton(group, gl[0], gl[1]);
});
}
});
$('label[for="serviceDate-0"]').after('<br /><small class="rfphoenix">when you bought it</small>');
$('#line-0 th').eq(3).append('<br /><em class="rfphoenix rfphoenix-em">NO TAX!</em>');
var $rfpNameNote = $(document.createElement('span'));
$rfpNameNote.text(' Name it something descriptive e.g. event name or budget category');
$('#rfpName').after($rfpNameNote);
$('#rfpName').focus(function (){
$rfpNameNote.prop('class', 'rfphighlight');
});
$('#rfpName').blur(function (){
$rfpNameNote.prop('class', '');
});
GROUPS.forEach(function (group) {
var prefix = group.name ? group.name + " " : "";
if (group.labels && group.labels.forEach) {
group.labels.forEach(function (label) {
var $rfpNameQuick = $makeBtn(prefix + label);
$rfpNameQuick.click(function (event) {
event.preventDefault();
// In this order (.focus().val()) it moves the cursor to the end
// I don't know why whatever.
$('#rfpName').focus().val(prefix + label);
});
$('#rfpName').after($rfpNameQuick);
});
}
});
function setMassachusetts(city) {
// annoying hack to trigger the site's handler to show/update
// the region dropdown
$('#country2').val('').focus().val('US').blur();
$('#region2').val('MA');
if (city) {
$('#city2').val(city);
}
}
function makeMassButton(city) {
var $maButton = $makeBtn(city || 'Massachusetts');
$maButton.click(function(event) {
event.preventDefault();
setMassachusetts(city);
});
$('#mailContainer').append($maButton);
}
makeMassButton();
makeMassButton('Boston');
makeMassButton('Cambridge');
makeMassButton('Somerville');
}
function appendExpenseTextareaUI(targetSel, paymentDetailsIndex) {
try {
var paymentDetailsTds = $('.leftHeadersTable').eq(paymentDetailsIndex).find('td');
var rfpNumber = paymentDetailsTds.eq(0).text().trim();
var payee = paymentDetailsTds.eq(1).text().trim();
var expenseText = $('.lineItem').map(function () {
var dateOfService = $(this).find('.data.center').text().trim();
var amount = $(this).find('.data.right.amount').text().trim();
var year = dateOfService.split('/')[2];
var type = dateOfService.split('/')[2];
var glText = $(this).find('.data').not('.center').eq(0).text().trim().split('-')[0].trim();
var category = '';
if (glText === '420226') {
category = 'Class Supplies';
} else if (glText === '421000' || glText === '421200') {
category = 'Food';
}
return [dateOfService, rfpNumber, amount, payee, '', '', '', year, category].join('\t');
}).get().join('\n');
var $expenseTextarea = $(document.createElement('textarea'));
$expenseTextarea.val(expenseText);
$expenseTextarea.prop('class', 'rfphoenix');
$(targetSel).append($expenseTextarea);
$(targetSel).append($makeBtn('Copy to Clipboard').click(function (event){
rfphoenixSetClipboard(event, expenseText);
event.preventDefault();
}));
} finally {
$(targetSel).append($makeBtn('Hide RFPhoenix').click(function (){
$('.rfphoenix').hide();
}));
}
}
if (window.location.href.indexOf('SendRfp') !== -1) {
$('#successMsgBlock').append('<strong class="rfphoenix">ADD IT TO THE SPREADSHEET!</strong>');
appendExpenseTextareaUI('#successMsgBlock', 0);
}
if (window.location.href.indexOf('SearchForRfps.action') !== -1) {
// 0 is "Status: Sent to bank for payment"
appendExpenseTextareaUI('#nav2', 1);
}
if (window.location.href.indexOf('RequestReport') !== -1 ||
window.location.href.indexOf('RunReport') !== -1) {
var costObjectField = $('#PageForm_safoForm_co');
GROUPS.forEach(function (group) {
costObjectField.after($makeBtn(group.name).click(function (event){
event.preventDefault();
costObjectField.val(group.costObject);
}));
});
}
if (window.location.href.indexOf('ReqCreateNavAction') !== -1) {
GROUPS.forEach(function (group) {
if (group.recipient !== undefined || group.room !== undefined || group.phone !== undefined) {
$('#nav1').append($makeBtn(group.name).click(function(){
// Goods Recipient
if (group.recipient !== undefined) {
$('#goodsRecipient').val(group.recipient);
}
// Unloading Point: MIT Bldg-Rm
if (group.room !== undefined) {
$('#unloadPtBldng').val(group.room);
}
// Unloading Point: Phone
if (group.phone !== undefined) {
$('#unloadPtPhone').val(group.phone);
}
}));
}
});
}
if (window.location.href.indexOf('rfphoenix.html') !== -1) {
$('body').append('You have RFPhoenix installed!');
}
})($new_jQuery);