more bits

This commit is contained in:
Dobie Wollert
2015-12-20 23:44:49 -08:00
parent a680042374
commit 977ea41cef
6 changed files with 198 additions and 31 deletions

View File

@ -6,6 +6,7 @@ var _ = require('lodash');
var Promise = require('bluebird'); var Promise = require('bluebird');
var TimeClockSpan = mongoose.model('TimeClockSpan'); var TimeClockSpan = mongoose.model('TimeClockSpan');
var TimeClockException = mongoose.model('TimeClockException'); var TimeClockException = mongoose.model('TimeClockException');
var TimeSheet = mongoose.model('TimeSheet');
var Workorder = mongoose.model('Workorder'); var Workorder = mongoose.model('Workorder');
var email = require('../util/email'); var email = require('../util/email');
var config = require('../../config/config')['prod']; var config = require('../../config/config')['prod'];
@ -33,6 +34,35 @@ function MultipleSpansError(spans) {
} }
MultipleSpansError.prototype = Object.create(Error.prototype); MultipleSpansError.prototype = Object.create(Error.prototype);
function hasTechApprovedPreviousWeek(user, day) {
var startOfWeek = day.clone().startOf('week').subtract(1, 'week').toDate();
var endOfWeek = day.clone().endOf('week').subtract(1, 'week').toDate();
return Promise
.props({
spans: TimeClockSpan.count({
start: {
'$gte': startOfWeek,
'$lte': endOfWeek
},
user: user
}),
timesheet: TimeSheet.findOne({
week: startOfWeek,
user: user
})
})
.then((props) => {
console.log('Spans last week: ', props.spans);
console.log('Previous timesheet', props.timesheet);
var approved = props.spans == 0 || (props.timesheet && props.timesheet.approved);
console.log('Status: ', approved);
return approved;
});
}
function findUserSpans(user, day) { function findUserSpans(user, day) {
var startOfDay = day.clone().startOf('day').toDate(); var startOfDay = day.clone().startOf('day').toDate();
var endOfDay = day.clone().endOf('day').toDate(); var endOfDay = day.clone().endOf('day').toDate();
@ -523,6 +553,16 @@ function validateDate(req, field) {
return Promise.resolve(date); return Promise.resolve(date);
} }
function sendApprovalRequiredResponse(res, date) {
date = moment().startOf('week').subtract(1, 'week');
res.json({
tasks: [{
type: 'approveTimesheet',
week: date.format('YYYY-MM-DD')
}]
});
}
module.exports = function () { module.exports = function () {
return { return {
index: function (req, res) { index: function (req, res) {
@ -531,12 +571,20 @@ module.exports = function () {
var today = moment(); var today = moment();
var spans = findUserSpans(req.user.id, today); hasTechApprovedPreviousWeek(req.user.id, today)
var workorders = findUserWorkorders(req.user, today); .then(approved => {
console.log('Approved? ', approved);
if (!approved) {
return sendApprovalRequiredResponse(res, today);
}
Promise.join(spans, workorders, handleStatusRequest) var spans = findUserSpans(req.user.id, today);
.then(responseHandler(res)) var workorders = findUserWorkorders(req.user, today);
.catch(errorHandler(res));
Promise.join(spans, workorders, handleStatusRequest)
.then(responseHandler(res))
.catch(errorHandler(res));
});
}, },
clockIn: function (req, res) { clockIn: function (req, res) {
@ -545,34 +593,50 @@ module.exports = function () {
var today = moment(); var today = moment();
var params = validateClockRequest(req); hasTechApprovedPreviousWeek(req.user.id, today)
var spans = findUserSpans(req.user.id, today); .then(approved => {
var workorders = findUserWorkorders(req.user, today);
Promise.join(params, req.user, spans, workorders, today, handleClockInRequest) if (!approved) {
.then(responseHandler(res)) return sendApprovalRequiredResponse(res, today);
.catch(errorHandler(res)); }
var params = validateClockRequest(req);
var spans = findUserSpans(req.user.id, today);
var workorders = findUserWorkorders(req.user, today);
Promise.join(params, req.user, spans, workorders, today, handleClockInRequest)
.then(responseHandler(res))
.catch(errorHandler(res));
});
}, },
clockOut: function (req, res) { clockOut: function (req, res) {
//TODO: Check to make sure user has a valid timesheet. //TODO: Check to make sure user has a valid timesheet.
Promise hasTechApprovedPreviousWeek(req.user.id, today)
.props({ .then(approved => {
id: req.body.id,
date: moment(), if (!approved) {
notes: req.body.notes, return sendApprovalRequiredResponse(res, today);
reason: req.body.reason, }
type: req.body.type
}) Promise
.then((params) => { .props({
var spans = findUserSpans(req.user.id, params.date); id: req.body.id,
var workorders = findUserWorkorders(req.user, params.date); date: moment(),
return Promise.join(params, req.user, spans, workorders, params.date, handleClockOutRequest); notes: req.body.notes,
}) reason: req.body.reason,
.then(responseHandler(res)) type: req.body.type
.catch(errorHandler(res)); })
.then((params) => {
var spans = findUserSpans(req.user.id, params.date);
var workorders = findUserWorkorders(req.user, params.date);
return Promise.join(params, req.user, spans, workorders, params.date, handleClockOutRequest);
})
.then(responseHandler(res))
.catch(errorHandler(res));
});
}, },
spansForUser: function (req, res) { spansForUser: function (req, res) {

View File

@ -6,6 +6,7 @@ var _ = require('lodash');
var Promise = require('bluebird'); var Promise = require('bluebird');
var TimeClockSpan = mongoose.model('TimeClockSpan'); var TimeClockSpan = mongoose.model('TimeClockSpan');
var Workorder = mongoose.model('Workorder'); var Workorder = mongoose.model('Workorder');
var TimeSheet = mongoose.model('TimeSheet');
var User = mongoose.model('User'); var User = mongoose.model('User');
var db = require('./db'); var db = require('./db');
@ -140,21 +141,28 @@ function buildReport(spans) {
.then(findWorkordersById) .then(findWorkordersById)
.then(indexById); .then(indexById);
const usersById = spans const userIds = spans
.then(extractIds('user')) .then(extractIds('user'));
const usersById = userIds
.then(findUsersById) .then(findUsersById)
.then(indexById); .then(indexById);
return Promise.join(spans, workordersById, usersById, generateSummary); const timesheetsByUser = userIds
.then(findTimesheetsByUser)
.then(indexByUser);
return Promise.join(spans, workordersById, usersById, timesheetsByUser, generateSummary);
} }
function generateSummary(spans, workordersById, usersById) { function generateSummary(spans, workordersById, usersById, timesheetsByUser) {
var results = {}; var results = {};
function fetchOrCreateUserRecord(userId) { function fetchOrCreateUserRecord(userId) {
var record = results[userId]; var record = results[userId];
if (!record) { if (!record) {
var user = usersById[userId]; var user = usersById[userId];
var timesheet = timesheetsByUser[userId];
record = results[userId] = { record = results[userId] = {
user: { user: {
@ -162,6 +170,7 @@ function generateSummary(spans, workordersById, usersById) {
name: user.name name: user.name
}, },
hasOpenSpans: false, hasOpenSpans: false,
approved: !!(timesheet && timesheet.approved),
workorders: {}, workorders: {},
spans: {}, spans: {},
clockedTime: 0, clockedTime: 0,
@ -264,6 +273,10 @@ function indexById(data) {
return _.indexBy(data, 'id') return _.indexBy(data, 'id')
} }
function indexByUser(data) {
return _.indexBy(data, 'user')
}
function findWorkordersById(ids) { function findWorkordersById(ids) {
const query = { const query = {
_id: { _id: {
@ -287,6 +300,16 @@ function findUsersById(ids) {
return User.find(query).exec(); return User.find(query).exec();
} }
function findTimesheetsByUser(ids) {
const query = {
user: {
$in: ids
}
};
return TimeSheet.find(query).exec();
}
function findAllSpansForWeek(week) { function findAllSpansForWeek(week) {
var startOfWeek = week.clone().startOf('week'); var startOfWeek = week.clone().startOf('week');
var endOfWeek = week.clone().endOf('week'); var endOfWeek = week.clone().endOf('week');
@ -320,6 +343,33 @@ function findUserSpansForWeek(id, week) {
return TimeClockSpan.find(query).exec(); return TimeClockSpan.find(query).exec();
} }
function approvalHandler(req, res) {
return (params) => {
params.week = params.week.toDate();
var query = {
user: params.id,
week: params.week
};
req.db.TimeSheet.findOne(query)
.then(timesheet => {
if (!timesheet) {
timesheet = new req.db.TimeSheet({
user: params.id,
week: params.week
});
}
timesheet.approved = true;
timesheet.approvedOn = new Date();
res.promise(timesheet.save());
});
};
}
module.exports = function () { module.exports = function () {
return { return {
daysWorked: function (req, res) { daysWorked: function (req, res) {
@ -365,6 +415,15 @@ module.exports = function () {
.then(userSummaryHandler) .then(userSummaryHandler)
.then(responseHandler(res)) .then(responseHandler(res))
.catch(errorHandler(res)); .catch(errorHandler(res));
},
approve: function(req, res) {
Promise
.props({
id: validateUserId(req),
week: validateWeek(req)
})
.then(approvalHandler(req, res))
.catch(errorHandler(res));
} }
} }
}; };

42
app/model/timeSheet.js Normal file
View File

@ -0,0 +1,42 @@
"use strict";
var moment = require('moment');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var schema = new Schema({
user: {
type: ObjectId,
ref: 'User',
required: true
},
week: {
type: Date,
required: true
},
approved: {
type: Boolean,
default: false,
required: true
},
approvedOn: {
type: Date,
required: function() {
return this.approved === true;
}
}
});
schema.pre('save', function (next) {
if (!this.approved) {
this.approvedOn = undefined;
}
next();
});
module.exports = mongoose.model('TimeSheet', schema);

View File

@ -71,7 +71,7 @@ function index(req, res) {
} }
/** /**
* POST /api/spans/:user_id * POST /api/spans/:span_id
*/ */
function update(req, res) { function update(req, res) {
req.check('id').isMongoId(); req.check('id').isMongoId();

View File

@ -13,6 +13,7 @@ const models = [
'TestRun', 'TestRun',
'TimeClockException', 'TimeClockException',
'TimeClockSpan', 'TimeClockSpan',
'TimeSheet',
'User', 'User',
'Workorder' 'Workorder'
]; ];

View File

@ -107,6 +107,7 @@ module.exports = function (app, auth, piler, calendar, directory, config) {
app.get('/api/timesheet/summary', timesheet.summary); app.get('/api/timesheet/summary', timesheet.summary);
app.get('/api/timesheet/:user_id/daysWorked', timesheet.daysWorked); app.get('/api/timesheet/:user_id/daysWorked', timesheet.daysWorked);
app.get('/api/timesheet/:user_id/summary', timesheet.userSummary); app.get('/api/timesheet/:user_id/summary', timesheet.userSummary);
app.post('/api/timesheet/:user_id/approve', timesheet.approve);
var pms = require('../app/controllers/pms'); var pms = require('../app/controllers/pms');
app.get('/api/pms', pms.index); app.get('/api/pms', pms.index);