mirror of
https://github.com/atlanticbiomedical/biomedjs.git
synced 2025-07-02 00:47:26 -04:00
more bits
This commit is contained in:
@ -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) {
|
||||||
|
@ -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
42
app/model/timeSheet.js
Normal 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);
|
@ -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();
|
||||||
|
@ -13,6 +13,7 @@ const models = [
|
|||||||
'TestRun',
|
'TestRun',
|
||||||
'TimeClockException',
|
'TimeClockException',
|
||||||
'TimeClockSpan',
|
'TimeClockSpan',
|
||||||
|
'TimeSheet',
|
||||||
'User',
|
'User',
|
||||||
'Workorder'
|
'Workorder'
|
||||||
];
|
];
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user