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 TimeClockSpan = mongoose.model('TimeClockSpan');
var TimeClockException = mongoose.model('TimeClockException');
var TimeSheet = mongoose.model('TimeSheet');
var Workorder = mongoose.model('Workorder');
var email = require('../util/email');
var config = require('../../config/config')['prod'];
@ -33,6 +34,35 @@ function MultipleSpansError(spans) {
}
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) {
var startOfDay = day.clone().startOf('day').toDate();
var endOfDay = day.clone().endOf('day').toDate();
@ -523,6 +553,16 @@ function validateDate(req, field) {
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 () {
return {
index: function (req, res) {
@ -531,12 +571,20 @@ module.exports = function () {
var today = moment();
var spans = findUserSpans(req.user.id, today);
var workorders = findUserWorkorders(req.user, today);
hasTechApprovedPreviousWeek(req.user.id, today)
.then(approved => {
console.log('Approved? ', approved);
if (!approved) {
return sendApprovalRequiredResponse(res, today);
}
Promise.join(spans, workorders, handleStatusRequest)
.then(responseHandler(res))
.catch(errorHandler(res));
var spans = findUserSpans(req.user.id, today);
var workorders = findUserWorkorders(req.user, today);
Promise.join(spans, workorders, handleStatusRequest)
.then(responseHandler(res))
.catch(errorHandler(res));
});
},
clockIn: function (req, res) {
@ -545,34 +593,50 @@ module.exports = function () {
var today = moment();
var params = validateClockRequest(req);
var spans = findUserSpans(req.user.id, today);
var workorders = findUserWorkorders(req.user, today);
hasTechApprovedPreviousWeek(req.user.id, today)
.then(approved => {
Promise.join(params, req.user, spans, workorders, today, handleClockInRequest)
.then(responseHandler(res))
.catch(errorHandler(res));
if (!approved) {
return sendApprovalRequiredResponse(res, today);
}
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) {
//TODO: Check to make sure user has a valid timesheet.
Promise
.props({
id: req.body.id,
date: moment(),
notes: req.body.notes,
reason: req.body.reason,
type: req.body.type
})
.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));
hasTechApprovedPreviousWeek(req.user.id, today)
.then(approved => {
if (!approved) {
return sendApprovalRequiredResponse(res, today);
}
Promise
.props({
id: req.body.id,
date: moment(),
notes: req.body.notes,
reason: req.body.reason,
type: req.body.type
})
.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) {

View File

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

View File

@ -13,6 +13,7 @@ const models = [
'TestRun',
'TimeClockException',
'TimeClockSpan',
'TimeSheet',
'User',
'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/:user_id/daysWorked', timesheet.daysWorked);
app.get('/api/timesheet/:user_id/summary', timesheet.userSummary);
app.post('/api/timesheet/:user_id/approve', timesheet.approve);
var pms = require('../app/controllers/pms');
app.get('/api/pms', pms.index);