Skip to content
This repository has been archived by the owner on May 16, 2023. It is now read-only.

Commit

Permalink
tiny refactor: moved view preparing to common view builder, added com…
Browse files Browse the repository at this point in the history
…mand skeleton #14
  • Loading branch information
gacek85 committed Apr 27, 2016
1 parent 217c124 commit a587e30
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 101 deletions.
3 changes: 2 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ var
notifier = require('./app/services/notifier'),
reportNotifier = require('./app/services/report')(slack, harvest),
slackNotifier = require('./app/services/slack/notifier')(slack, harvest),
slackForecastNotifier = require('./app/services/slack/notifier/forecast')(slack, harvest),
forecastViewBuilder = require('./app/services/forecast/view.js'),
slackForecastNotifier = require('./app/services/slack/notifier/forecast')(slack, harvest, forecastViewBuilder),
slackReminder = require('./app/services/slack/notifier/remind')(slack, harvest),
i18n = require('i18n'),
forecast = require('./app/services/forecast')('default', config.forecast),
Expand Down
2 changes: 1 addition & 1 deletion app/services/cronjobs/jobs/forecast.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ var
*/
shouldRunNow : function (config)
{
return false;
return true;
},


Expand Down
97 changes: 97 additions & 0 deletions app/services/forecast/view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*jshint node: true*/
'use strict';

var _ = require('lodash'),
tools = require('./../tools.js'),
i18n = require('i18n'),
viewBuilder = {

/**
* Aggregates assignments by user
*
* @param {Object} assignments
* @returns {Object}
*/
aggregateByUser : function (assignments)
{
var results = {};
_.each(assignments, function (assignment) {
var person = assignment.person,
harvestUserId = person ? person.harvest_user_id : null
;

if (harvestUserId) {
results[harvestUserId] = results[harvestUserId] || {
person : person,
assignments : []
};

results[harvestUserId].assignments.push(assignment);
}
});

return results;
},

format : function (title, text)
{
return "\n" + [title, text].join("\n") + "\n";
},

/**
*
* @param {Object} userAssignments
* @returns {undefined}
*/
prepareTitle : function (userAssignments)
{

var name = userAssignments.person.first_name + ' ' + userAssignments.person.last_name;
return '*' + i18n.__('Projects assignments schedule for {{name}}:', {
name : name
}) + '*';

},


/**
* prepares the text and triggers propper event when ready
*
* @param {Object} userAssignments
* @returns {undefined}
*/
prepareText : function (userAssignments)
{
var results = [];

_.each(userAssignments.assignments, function (assignment) {
var text = [],
project = assignment.project,
client = project ? assignment.project.client : null,
timeSeconds = assignment.allocation,
timeText = tools.formatSeconds(Number(timeSeconds))
;

text.push(timeText);
if (client) {
text.push(client.name);
}
if (project) {
text.push(project.name);
}

if (!project && !client) {
text.push(i18n.__('N/A'));
}

results.push(text.join(' - '));
});

return results.join("\n");
}
}
;



module.exports = viewBuilder;
95 changes: 95 additions & 0 deletions app/services/interactive_session/lib/actions/schedule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*jshint node: true*/
'use strict';

var
scheduleProvider,
interactiveSession = require('./../user_session.js'),
tools = require('./../../../tools.js'),
_ = require('lodash'),
viewBuilder = require('./../../../forecast/view'),
forecast = require('./../../../forecast')('default'),
i18n = require('i18n'),
logger = require('./../../../logger.js')('default'),
StepProvider = require('./../step_provider.js'),
moment = require('moment')
;

scheduleProvider = new StepProvider('schedule');
scheduleProvider.addStep(1, {
execute : function (params, callback)
{
var that = this,
action = tools.validateGet(params, 'action'),
userId = params.userId,
assignmentsByUser,
userAssignments
;


if (forecast === null) {
return null;
}
var options = {
startDate : moment().startOf('day'),
endDate : moment().endOf('day')
};

forecast.assignments(options, function (error, assignments) {
if (error) {
logger.error(i18n.__('Failed loading forecast schedule.', {}));
callback(error, null);
return;
} else {
logger.info(i18n.__('Successfully loaded forecast schedule.'), {});

assignmentsByUser = viewBuilder.aggregateByUser(assignments);
userAssignments = !!assignmentsByUser[userId] ? assignmentsByUser[userId] : null;
if (!userAssignments) {
callback(that.getView(null), null);
return;
}

step = interactiveSession
.getDefault()
.createStep(userId, {}, action)
;
step.addParam('userAssignments', userAssignments);
callback(null, step);
}
});
},

postExecute: function (step, callback)
{
var userId = step.getParam('userId');
interactiveSession
.getDefault()
.clear(userId)
;
callback();
},
prepareStep: function (step)
{
return null;
},

getView: function (step)
{
var userAssignments,
view,
errorString = i18n.__('Currently you have no tasks scheduled.')
;

if (step === null) {
view = errorString;
} else {
userAssignments = step.getParam('userAssignments');
view = viewBuilder.getView(userAssignments);
}


return view;
}
});

module.exports = scheduleProvider;
110 changes: 11 additions & 99 deletions app/services/slack/notifier/forecast.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
var _ = require('lodash'),
events = require("events"),
logger = require('./../../logger.js')('default'),
tools = require('./../../tools.js'),
i18n = require('i18n'),
instance = null
;
Expand All @@ -30,59 +29,26 @@ function getUserName (users, harvestUserId)
}


/**
* Aggregates assignments by user
*
* @param {Object} assignments
* @returns {Object}
*/
function aggregateByUser (assignments)
{
var results = {};
_.each(assignments, function (assignment) {
var person = assignment.person,
harvestUserId = person ? person.harvest_user_id : null
;

if (harvestUserId) {
results[harvestUserId] = results[harvestUserId] || {
person : person,
assignments : []
};

results[harvestUserId].assignments.push(assignment);
}
});

return results;
}


function format (title, text)
{
return "\n" + [title, text].join("\n") + "\n";
}


/**
* Sends notifications via slack
*
* @author Maciej Garycki <maciej@neverbland.com>
*
* @param {Object} slack The slack object
* @param {Object} harvest The harvest object
* @param {Object} viewBuilder Forecast slack message view builder
* @constructor
*/
function SlackNotifier (slack, harvest)
function SlackNotifier (slack, harvest, viewBuilder)
{
this.slack = slack;
this.harvest = harvest;
this.viewBuilder = viewBuilder;
}


var SlackNotifierPrototype = function ()
{

/**
* Sends notification to slack
*
Expand All @@ -93,23 +59,23 @@ var SlackNotifierPrototype = function ()
{
var that = this,
assignments = slackContext.assignments,
assignmentsByUser = aggregateByUser(assignments)
assignmentsByUser = that.viewBuilder.aggregateByUser(assignments)
;
_.each(assignmentsByUser, function (userAssignments, harvestId) {
if (!userAssignments.assignments.length) {
return;
}
var text = that.prepareText(userAssignments),
title = that.prepareTitle(userAssignments),
slackId = getUserName(that.slack.users, harvestId),
fullText = format(title, text)


var slackId = getUserName(that.slack.users, harvestId),
view = that.viewBuilder.getView(userAssignments)
;

if (!slackId) {
return;
}

that.slack.sendMessage(fullText, {
that.slack.sendMessage(view, {
channel : '@' + slackId
}, function (err, httpResponse, body) {
if (err === null) {
Expand All @@ -120,60 +86,6 @@ var SlackNotifierPrototype = function ()
});
});
};



/**
*
* @param {Object} userAssignments
* @returns {undefined}
*/
this.prepareTitle = function (userAssignments)
{

var name = userAssignments.person.first_name + ' ' + userAssignments.person.last_name;
return '*' + i18n.__('Projects assignments schedule for {{name}}:', {
name : name
}) + '*';

}


/**
* prepares the text and triggers propper event when ready
*
* @param {Object} userAssignments
* @returns {undefined}
*/
this.prepareText = function (userAssignments)
{
var results = [];

_.each(userAssignments.assignments, function (assignment) {
var text = [],
project = assignment.project,
client = project ? assignment.project.client : null,
timeSeconds = assignment.allocation,
timeText = tools.formatSeconds(Number(timeSeconds))
;

text.push(timeText);
if (client) {
text.push(client.name);
}
if (project) {
text.push(project.name);
}

if (!project && !client) {
text.push(i18n.__('N/A'));
}

results.push(text.join(' - '));
});

return results.join("\n");
};
};

SlackNotifierPrototype.prototype = new events.EventEmitter();
Expand All @@ -182,8 +94,8 @@ SlackNotifierPrototype.prototype = new events.EventEmitter();
SlackNotifier.prototype = new SlackNotifierPrototype();
SlackNotifier.prototype.constructor = SlackNotifier;

module.exports = function (slack, harvest) {
instance = new SlackNotifier(slack, harvest);
module.exports = function (slack, harvest, viewBuilder) {
instance = new SlackNotifier(slack, harvest, viewBuilder);
module.exports.instance = instance;

return instance;
Expand Down

0 comments on commit a587e30

Please sign in to comment.