Created
February 13, 2019 20:35
-
-
Save samguergen/eeef5695adc8d1dc2f9fa6d72ffce32f to your computer and use it in GitHub Desktop.
Timesheets functionality files isolated from the widget repo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var express = require('express'); | |
var nodemailer = require('nodemailer'); | |
var smtpTransport = require('nodemailer-smtp-transport'); | |
var app = express(); | |
const MongoClient = require('mongodb').MongoClient; | |
var mongo = require('mongodb'); | |
var session = require('express-session'); | |
var cookieParser = require('cookie-parser'); | |
var bodyParser = require('body-parser'); | |
var env = require(__dirname + '/env-vars.js'); | |
var gmail_login = env.gmail_login; | |
var gmail_pass = env.gmail_pass; | |
var db; | |
var http = require('http'); | |
var request=require('request'); | |
var _ =require('lodash'); | |
var multer = require('multer'); | |
var upload = multer({ dest: 'uploads/' }) | |
var multipart = require('connect-multiparty'); | |
var formidable = require('express-formidable'); | |
var fs = require('fs'); | |
app.use(function(req, res, next) { | |
res.header("Access-Control-Allow-Origin", "*"); | |
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); | |
next(); | |
}); | |
app.use(express.json()); //convert req to json | |
app.use(express.static(__dirname + '/app')); | |
app.use(session({secret: "Sam is awesome"})); | |
// app.use(formidable()); | |
app.use(bodyParser.json()); // Configures bodyParser to accept JSON | |
app.use(bodyParser.urlencoded({ | |
extended: false | |
})); | |
var allPages = ['/home','/portfolio', '/timesheets', '/timesheet', '/documents','/shift-scheduler','/comments','/blog-thumbnail']; | |
MongoClient.connect('mongodb://samguergen:[email protected]:19662/widgets', function(err, client) { | |
if (err) { | |
console.log('db not connecting, but inside mongo block - 1', err); | |
}; | |
db = client.db('widgets'); | |
console.log('inside first mongo block'); | |
app.get('/getTimesheets', function (req,res) { | |
db.collection('timesheets').find().toArray(function (err, result) { | |
res.send(result); | |
}) | |
}); | |
app.post('/addTimesheet', function (req,res) { | |
console.log('inside timesheet add') | |
var timesheet = req.body.timesheet; | |
console.log('ts to be saved, received from backend is ', timesheet); | |
db.collection('timesheets').save(timesheet, function(err, result){ | |
if (err) { return console.log('connecting to db, but not saving obj', err);} | |
console.log('ts saved to database'); | |
res.send(result); | |
}) | |
}); | |
app.delete('/deleteTimesheet', function (req,res) { | |
var timesheetId = req.query.timesheetId; | |
console.log('ts to be deleted, received from backend is ', timesheetId) | |
db.collection('timesheets').deleteOne({_id: new mongo.ObjectId(timesheetId)}, function(err, result){ | |
if (err) { throw new Error('No record found. ', err) }; | |
console.log('timesheet has been removed, i think'); | |
res.send(result); | |
}); | |
}); // end of deleteagendaevent request | |
app.get('/getDocuments', formidable(), function (req,res) { | |
db.collection('documents').find().toArray(function (err, result) { | |
res.send(result); | |
}) | |
}); // end of /getRidesData get request | |
app.post('/uploadFiles', formidable(), function(req, res) { | |
console.log('uploadFiles from backend is ', req.files); | |
var binaryLocation = req.files.file.path; | |
var fileName = req.files.file.name; | |
console.log('file name is ', fileName); | |
var binaryData = fs.readFileSync(binaryLocation); | |
var theFile = {}; | |
theFile.data = binaryData | |
theFile.name = fileName; | |
theFile.category = 'all'; | |
theFile.categoryGeneral = 'all'; | |
var tableName = req.query.tableName; | |
console.log('theFile is ', theFile); | |
db.collection('documents').save(theFile, function(err, result){ | |
if (err) { return console.log('connecting to db, but not saving obj', err);} | |
console.log('doc saved to database'); | |
res.send(result); | |
}) | |
}); | |
app.delete('/removeFile', formidable(), function (req,res) { | |
console.log('inside removeFile, queries are ', req.query.fileId); | |
var fileId = req.query.fileId; | |
db.collection('documents').deleteOne({_id: new mongo.ObjectId(fileId)}, function(err, result){ | |
if (err) { throw new Error('No record found. ', err) }; | |
console.log('file has been removed, i think'); | |
res.send(result); | |
}); | |
}); // end of /removeFile delete request | |
app.put('/updateCategory', function (req,res) { | |
var fileName = req.body.fileName; | |
var categoryDbName = req.body.categoryDbName; | |
var fileId = req.body.fileId; | |
console.log('file name is ', fileName, 'categoryDbName ', categoryDbName, 'fileId ', fileId); | |
var myQuery = {_id: new mongo.ObjectId(fileId)}; | |
var newValues = { | |
$set: { | |
category: categoryDbName | |
} | |
}; | |
db.collection('documents').findAndModify(myQuery, [['_id','asc']], newValues, {}, function(err, result){ | |
if (err) { throw new Error('No record found. ', err) }; | |
console.log('record has been updated, i think'); | |
res.send(result); | |
}); | |
}); // end of /updateCategory put request | |
app.get('/viewWeeklyCalendarEvents', function (req,res) { | |
db.collection('weekly-calendar').find().toArray(function (err, result) { | |
res.send(result); | |
}) | |
}); // end of /viewRISCalendarEvents get request | |
app.post('/addWeeklyCalendarEvent', function (req,res) { | |
var newEvent = req.body.newEvent; | |
console.log('event to be saved, received from backend is ', newEvent); | |
db.collection('weekly-calendar').save(newEvent, function(err, result){ | |
if (err) { return console.log('connecting to db, but not saving obj', err);} | |
console.log('event saved to database', result); | |
res.send(result); | |
}) | |
}); | |
app.delete('/deleteWeeklyCalendarEvent', function (req,res) { | |
var eventId = req.query.eventId; | |
console.log('event to be deleted, received from backend is ', eventId) | |
db.collection('weekly-calendar').deleteOne({_id: new mongo.ObjectId(eventId)}, function(err, result){ | |
if (err) { throw new Error('No record found. ', err) }; | |
console.log('event has been removed'); | |
res.send(result); | |
}); | |
}); // end of deleteagendaevent request | |
app.get('/getComments', function (req,res) { | |
db.collection('comments').find().toArray(function (err, result) { | |
res.send(result); | |
}) | |
}); // end of /getComments get request | |
app.post('/addComment', function (req,res) { | |
var comment = req.body.comment; | |
console.log('comment to be saved, received from backend is ', comment); | |
db.collection('comments').save(comment, function(err, result){ | |
if (err) { return console.log('connecting to db, but not saving obj', err);} | |
console.log('comment saved to database'); | |
res.send(result); | |
}) | |
}); | |
app.delete('/deleteComment', function (req,res) { | |
var commentId = req.query.commentId; | |
console.log('comment to be deleted, received from backend is ', commentId) | |
db.collection('comments').deleteOne({_id: new mongo.ObjectId(commentId)}, function(err, result){ | |
if (err) { throw new Error('No record found. ', err) }; | |
console.log('comment has been removed'); | |
res.send(result); | |
}); | |
}); // end of deleteagendaevent request | |
app.post('/sendmail', function(req, res){ | |
console.log('inside sendmail, post req', req.body); | |
let mailOptions = {}; | |
if (req.body){ //private contact form from ITN staff to ITN staff | |
console.log('sending email without pdf'); | |
mailOptions = { | |
from: req.body.from, // sender address | |
to: req.body.to, // list of receivers | |
subject: req.body.subject, // Subject line | |
html: req.body.html // html body | |
}; | |
} | |
let transporter = nodemailer.createTransport(smtpTransport({ | |
service: "Gmail", // sets automatically host, port and connection security settings | |
auth: { | |
user: gmail_login, | |
pass: gmail_pass | |
} | |
}) | |
) | |
// send mail with defined transport object | |
transporter.sendMail(mailOptions, function(error, info) { | |
if (error) { | |
return console.log(error); | |
} | |
console.log('Message sent: %s', info.messageId); | |
transporter.close(); | |
}); | |
console.log('after mongo block'); | |
res.end(); | |
}); | |
app.get('/getBlogContent', function(req, res) { | |
console.log('params are ', req.query) | |
request.get(req.query.blogURL, function(err,result,body) { | |
console.log('result is ', result) | |
res.send(result.body) | |
}); | |
}); | |
}); //end of main mongodb block | |
app.use(allPages, function(req, res){ | |
res.sendFile(__dirname + '/app/index.html'); | |
}); | |
app.listen(process.env.PORT || 13270); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var myApp = angular.module('myApp'); | |
myApp.service('CalendarService', ['$http','$q', function($http, $q){ | |
this.adjustTimeForCalendar = function(theTime) { | |
var time = theTime.replace(" ", ""); | |
time = time.toUpperCase(); | |
var adjustedTime = { | |
hour: 0, | |
min: 0 | |
}; | |
if (time.includes("AM") && time.includes(":")){ | |
adjustedTime.hour = time.substr(0,time.indexOf(':')); | |
adjustedTime.min = time.substr(time.indexOf(':')+1,time.indexOf('AM')-2); | |
} else if (time.includes("AM")){ | |
adjustedTime.hour = time.substr(0,time.indexOf('AM')); | |
adjustedTime.min = 0; | |
} else if (time.includes("PM") && time.includes(":")){ | |
adjustedTime.hour = parseInt(time.substr(0,time.indexOf(':'))); | |
if (adjustedTime.hour < 12){ | |
adjustedTime.hour = adjustedTime.hour + 12; | |
} | |
adjustedTime.min = time.substr(time.indexOf(':')+1,time.indexOf('PM')-2); | |
} else if (time.includes("PM")){ | |
adjustedTime.hour = parseInt(time.substr(0,time.indexOf('PM'))); | |
if (adjustedTime.hour < 12){ | |
adjustedTime.hour = adjustedTime.hour + 12; | |
} | |
adjustedTime.min = 0; | |
} | |
adjustedTime.hour = parseInt(adjustedTime.hour); | |
adjustedTime.min = parseInt(adjustedTime.min); | |
return adjustedTime; | |
}; | |
this.convertMinsToHoursMinsObj = function(data) { | |
return { | |
mins: data % 60, | |
hours: (data - (data % 60))/ 60 | |
} | |
}; | |
}]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var myApp = angular.module('myApp'); | |
myApp.service('DataService', ['$http','$q', function($http, $q){ | |
this.getTimesheets = function(affiliateName){ | |
console.log('in service, getting ts'); | |
return $http.get('/getTimesheets') | |
.then(function(data){ | |
console.log('log from post is ', data); | |
if (data.status === 200){ | |
return data | |
} else { | |
return error | |
} | |
}).catch(function(error) { | |
return error | |
}) | |
}; | |
this.addTimesheet = function(timesheet){ | |
console.log('ts to be saved is ', timesheet); | |
return $http.post('/addTimesheet', {timesheet: timesheet}) | |
.then(function(data){ | |
console.log('log from post is ', data); | |
if (data.status === 200){ | |
return data | |
} else { | |
return error | |
} | |
}).catch(function(error) { | |
return error | |
}) | |
}; | |
this.deleteTimesheet = function(timesheet){ | |
console.log('timesheet to delete in service is ', timesheet._id); | |
// return $http.delete('/deleteTimesheet', {timesheetId: timesheet._id}) | |
return $http.delete('/deleteTimesheet', { | |
params: { | |
timesheetId: timesheet._id | |
} | |
}) | |
.then(function(data){ | |
console.log('log from post is ', data); | |
if (data.status === 200){ | |
return data | |
} else { | |
return error | |
} | |
}).catch(function(error) { | |
return error | |
}) | |
}; | |
this.editTimesheet = function(timesheet){ | |
return $http.put('/editTimesheet') | |
.then(function(data){ | |
console.log('log from post is ', data); | |
if (data.status === 200){ | |
return data | |
} else { | |
return error | |
} | |
}).catch(function(error) { | |
return error | |
}) | |
}; | |
this.getDocuments = function(){ | |
return $http.get('/getDocuments') | |
.then(function(data){ | |
return data; | |
}) | |
}; | |
this.getComments = function(){ | |
return $http.get('/getComments') | |
.then(function(data){ | |
console.log('log from post is ', data); | |
if (data.status === 200){ | |
return data | |
} else { | |
return error | |
} | |
}).catch(function(error) { | |
return error | |
}) | |
}; | |
this.addComment = function(comment){ | |
return $http.post('/addComment', {comment: comment}) | |
.then(function(data){ | |
console.log('data returned from add comment service is ', data); | |
return data; | |
}) | |
}; | |
this.deleteComment = function(comment){ | |
console.log('comment id is is ', comment, 'id is ', comment._id) | |
return $http.delete('/deleteComment', { | |
params: { | |
commentId: comment._id | |
} | |
}) | |
.then(function(data){ | |
console.log('data returned is ', data); | |
return data; | |
}).catch(function(error){ | |
console.log('error is ', error); | |
return error; | |
}) | |
}; | |
// this.editCommentDraft = function(content, affiliate){ | |
// console.log('inside delete comment service, content is ', content, 'affiliate is ', affiliate); | |
// var payload = {content: content, affiliate: affiliate, operation: 'delete'}; | |
// return $http.delete('/deleteComment', {params: payload}) | |
// .then(function(data){ | |
// console.log('return from update comments', data); | |
// return data; | |
// }) | |
// }; | |
this.viewWeeklyCalendarEvents = function(){ | |
return $http.get('/viewWeeklyCalendarEvents') | |
.then(function(data){ | |
return data; | |
}).catch(function(error){ | |
return error | |
}) | |
}; | |
this.addWeeklyCalendarEvent = function(newEvent){ | |
console.log('event in add calendar event is ', newEvent); | |
return $http.post('/addWeeklyCalendarEvent', {newEvent: newEvent}) | |
.then(function(data){ | |
console.log('data returned from add calendar event service is ', data); | |
return data; | |
}).catch(function(error){ | |
return error | |
}) | |
}; | |
this.deleteWeeklyCalendarEvent = function(agendaEvent){ | |
console.log('agenda event is ', agendaEvent, 'id is ', agendaEvent._id) | |
return $http.delete('/deleteWeeklyCalendarEvent', { | |
params: { | |
eventId: agendaEvent._id | |
} | |
}) | |
.then(function(data){ | |
console.log('data returned is ', data); | |
return data; | |
}).catch(function(error){ | |
console.log('error is ', error); | |
return error; | |
}) | |
}; | |
}]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="timesheet portal" ng-init="parseDayAndAffiliateParams();parseParamsIfTimesheet();isNewTimesheet()"> | |
<a ui-sref="timesheets({filter: tsData.affiliate})" | |
ng-show="backToTimesheet" | |
class="btn btn-lg">Timesheets Index</a> | |
<div class="current-timesheet container-fluid" style="width:95%" ng-hide="viewNewTimesheet" ng-show="!backToTimesheet"> | |
<h2>Timesheet - Day {{existingTimesheetDay}}</h2> | |
<div class="timesheet-card card"> | |
<p class="title">Driver Information<p> | |
<div class="mileage-rates"> | |
Mileage rate: ${{tsData.rates.mileageRate}}<br /> | |
After-hours daily rate: ${{tsData.rates.dailyRate}}<br /> | |
Weekly: ${{tsData.rates.weeklyRate}} | |
</div> | |
<div class="row semi-white-bg" style="padding: 20px 0;"> | |
<div class="col-sm-5"> | |
<label for="driver name">Name: {{existingTimesheet.name}}</label><br> | |
</div> | |
<div class="col-sm-3"> | |
<label for="date">Date: {{existingTimesheet.date | date}}</label><br> | |
</div> | |
<div class="col-sm-4"> | |
<label for="lunchtime taken">Lunch taken during shift? {{existingTimesheet.tookLunch}}</label> | |
</div> | |
</div> | |
<div class="shifts"> | |
<p class="title"> | |
Start/Stop Shifts <i class="fa fa-plus-circle" ng-click="addShift()"></i> | |
</p> | |
<p class="mileage-data"><em style="text-align:left"> | |
Total Mileage Refund: ${{tsData.totalMileageRefund | number: 3}} <br /> | |
Total daily work time: {{tsData.dailyWorkTimeMins}}mins<br /> | |
Total daily Overtime: {{tsData.dailyOvertimeMins | isAbs}}mins - tabs highlighted | |
</em></p> | |
<div class="each-shift" style="padding:5px"> | |
<table class="table table-responsive"> | |
<thead style="background:#595656"> | |
<th style="15%">Shift #</th> | |
<th>Start</th> | |
<th>Stop</th> | |
<th>Miles Driven</th> | |
<th>Notes</th> | |
<th>Delete</th> | |
<th style="color:#afcace">Save Shift</th> | |
</thead> | |
<tbody style="background:grey"> | |
<tr ng-repeat="shift in existingTimesheet.shifts" | |
ng-class="{highlighted: ($index + 1) >= shiftIdxTrigger}"> | |
<td style="width:15%;font-size:35px"> | |
{{$index + 1}} <br /> | |
</td> | |
<td>{{shift.startTimeMeridian}}</td> | |
<td>{{shift.endTimeMeridian}}</td> | |
<td>{{shift.milesPerShift}}</td> | |
<td class="show-note"> | |
{{shift.note}} | |
</td> | |
<td> | |
<i class="fa fa-trash" ng-click="removeShift(shift, $index)"></i> | |
</td> | |
<td> | |
<i class="fa fa-check" ng-click="recordShift($index)"></i><br> | |
<em style="font-size:16px"> | |
Mileage refund: ${{shift.mileageRefund | number: 3}} <br> | |
Shift duration: {{shift.timeDiffMins}}mins | |
</em> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</div><!--shifts--> | |
<p class="warning-msg"><strong>{{warningMsg}}</strong></p> | |
<div class="formBtns" style="margin-top:20px"> | |
<button type="button" ng-click="editTimesheet()" class="btn btn-lg btn-primary pull-left itn-green-bg" style="margin-left:2%">Edit Timesheet</button> | |
<button type="button" ng-click="deleteTimesheet()" class="btn btn-lg btn-primary pull-left itn-green-bg" style="margin-left:2%;background:#e05944 !important">Delete Timesheet</button> | |
<button type="submit" ng-disabled="itnForm.$invalid || loading" class="btn btn-lg pull-right btn-danger" style="margin-left:2%">Submit</button> | |
</div> | |
</div><!--timesheet-card--> | |
</div><!--container-fluid--> | |
<div class="new-timesheet container-fluid" style="width:95%" ng-show="viewNewTimesheet"> | |
<h2>New ITN<em>{{tsData.affiliate}}</em> Timesheet</h2> | |
<div class="timesheet-card card"> | |
<form name="tsForm" novalidate ng-submit="submitTimesheet()" role="timesheet form" ng-model="tsData" ng-hide="submitted"> | |
<p class="title">Driver Information<p> | |
<div class="mileage-rates"> | |
Mileage rate: ${{tsData.rates.mileageRate}}<br /> | |
After-hours daily rate: ${{tsData.rates.dailyRate}}<br /> | |
Weekly: ${{tsData.rates.weeklyRate}} | |
</div> | |
<div class="row semi-white-bg"> | |
<div class="col-sm-5 form-group"> | |
<label for="driver name">Enter name: </label><br> | |
<input type="text" class="form-control" name="driverName" ng-model="tsData.name" ng-minlength="minlength" ng-maxlength="maxlength" style="text-align:center"> | |
</div> | |
<div class="col-sm-3 form-group"> | |
<label for="date">Date: </label><br> | |
<input type="date" class="form-control" name="date" ng-model="tsData.date" style="display:inline-block;text-align:center"> | |
</div> | |
<!-- answer: {{tsData.date | date : "dd-MM-y" }} --> | |
<div class="col-sm-4 form-group" style="margin-top:80px"> | |
<label for="lunchtime taken">Lunch taken during shift? </label> | |
<input type="checkbox" name="tookLunch" value="true" ng-model="tsData.tookLunch" ng-change="deductLunch()" style="width:20px;height:20px"> | |
</div> | |
</div> | |
<div class="shifts"> | |
<p class="title"> | |
Start/Stop Shifts <i class="fa fa-plus-circle" ng-click="addShift()"></i> | |
</p> | |
<p class="mileage-data"><em style="text-align:left"> | |
Total Mileage Refund: ${{tsData.totalMileageRefund | number: 3}} <br /> | |
Total daily work time: {{tsData.dailyWorkTimeMins}}mins<br /> | |
Total daily Overtime: {{tsData.dailyOvertimeMins | isAbs}}mins - tabs highlighted | |
</em></p> | |
<div class="each-shift" style="padding:5px"> | |
<table class="table table-responsive"> | |
<thead style="background:#595656"> | |
<th style="15%">Shift #</th> | |
<th>Start</th> | |
<th>Stop</th> | |
<th>Miles Driven</th> | |
<th>Add note</th> | |
<th>Delete</th> | |
<th style="color:#afcace">Save Shift</th> | |
</thead> | |
<tbody style="background:grey"> | |
<tr ng-repeat="shift in tsData.shifts" | |
ng-class="{highlighted: ($index + 1) >= shiftIdxTrigger}"> | |
<td style="width:15%;font-size:35px"> | |
{{$index + 1}} <br /> | |
</td> | |
<td> | |
<select ng-model="selectedStartTime" | |
ng-change="updateStartTime(selectedStartTime, shift, $index)" | |
ng-options="time as time for time in timesForPicker"> | |
</select> | |
</td> | |
<td> | |
<select ng-model="selectedEndTime" | |
ng-change="updateEndTime(selectedEndTime, shift, $index)" | |
ng-options="time as time for time in timesForPicker"> | |
</select> | |
</td> | |
<td> | |
<input style="text-align:center;border-radius:5px" type="number" min="0" max="100" ng-model="shift.milesPerShift"> | |
</td> | |
<td class="show-note"> | |
<i class="fa fa-pencil" style="padding-top:15px" ng-click="toggleNote($index)" ng-show="!showNote[$index]"></i> | |
<div ng-show="showNote[$index]"> | |
<textarea class="form-control" type="textarea" name="note" id="note" placeholder="Message" maxlength="2000" rows="3" ng-minlength="minlength" ng-maxlength="maxMsgLength" ng-model="shift.note"></textarea> | |
<i class="fa fa-minus-circle" ng-click="toggleNote($index)"></i> | |
</div> | |
</td> | |
<td> | |
<i class="fa fa-trash" ng-click="removeShift(shift, $index)"></i> | |
</td> | |
<td> | |
<i class="fa fa-check" ng-click="recordShift($index)"></i><br> | |
<em style="font-size:16px"> | |
Mileage refund: ${{shift.mileageRefund | number: 3}} <br> | |
Shift duration: {{shift.timeDiffMins}}mins | |
</em> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</div><!--shifts--> | |
<p class="warning-msg"><strong>{{warningMsg}}</strong></p> | |
<div class="formBtns" style="margin-top:20px"> | |
<button type="submit" ng-disabled="itnForm.$invalid || loading" class="btn btn-lg pull-right btn-danger" style="margin-left:2%">Submit</button> | |
</div> | |
</div><!--timesheet-card--> | |
</div><!--container-fluid--> | |
</div><!--timesheets--> | |
<div class="back-btn-wrap"> | |
<a ui-sref="portal" class="back-btn"> | |
<h3>Back to Portal</h3> | |
</a> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var myApp = angular.module('myApp'); | |
myApp.controller('TimesheetCtrl', ['$scope', '$transitions', '$http', '$location', '$stateParams', '$timeout', '$state', '$rootScope', '$window','DataService', 'LongVariablesService', 'CalendarService', '$q', 'DataService', '$window', function($scope, $transitions, $http, $location, $stateParams, $timeout, $state, $rootScope, $window, DataService, LongVariablesService, CalendarService, $q, DataService, $window) { | |
$scope.timesForPicker = ['-Select time-','5:00AM','5:15AM','5:30AM','5:45AM','6:00AM','6:15AM','6:30AM','6:45AM','7:00AM','7:15AM','7:30AM','7:45AM','8:00AM','8:15AM','8:30AM','8:45AM','9:00AM','9:15AM','9:30AM','9:45AM','10:00AM','10:15AM','10:30AM','10:45AM','11:00AM','11:15AM','11:30AM','11:45AM','12:00PM','12:15PM','12:30PM','12:45PM','1:00PM','1:15PM','1:30PM','1:45PM','2:00PM','2:15PM','2:30PM','2:45PM','3:00PM','3:15PM','3:30PM','3:45PM','4:00PM','4:15PM','4:30PM','4:45PM','5:00PM','5:15PM','5:30PM','5:45PM','6:00PM','6:15PM','6:30PM','6:45PM','7:00PM','7:15PM','7:30PM','7:45PM','8:00PM','8:15PM','8:30PM','8:45PM','9:00PM','9:15PM','9:30PM','9:45PM','10:00PM','10:15PM','10:30PM','10:45PM','11:00PM','11:15PM','11:30PM','11:45PM','12:00AM' | |
]; | |
$scope.adjustTimeForCalendar = CalendarService.adjustTimeForCalendar; //function | |
$scope.convertMinsToHoursMinsObj = CalendarService.convertMinsToHoursMinsObj; //function | |
$scope.showNote = {}; | |
$scope.selectedStartTime = $scope.timesForPicker[0]; | |
$scope.selectedEndTime = $scope.timesForPicker[0]; | |
$scope.backToTimesheet = false; | |
$scope.shiftsAdded = 0; | |
$scope.tsData = { | |
name: null, | |
date: new Date(), | |
tookLunch: false, | |
dayOfPeriod: 0, //calculate | |
shiftSelecteIdx: 0, | |
affiliate: null, | |
rates: { | |
mileageRate: 0.555, | |
dailyRate: 7.14, | |
weeklyRate: 50, | |
otBenchmark: 8 //overtime benchmark in hours | |
}, | |
shifts: [], | |
totalMileageRefund: 0, | |
dailyWorkTimeMins: 0, | |
dailyOvertimeMins: 0 | |
}; | |
var newShift = { | |
startTimeObj: null, | |
endTimeObj: null, | |
startTimeMeridian: null, | |
endTimeMeridian: null, | |
milesPerShift: 0, | |
note: "", | |
isSelected: true, | |
idx: 0, | |
mileageRefund: 0, | |
timeDiffHoursMins: 0, | |
timeDiffMins: 0, | |
saved: false, | |
overtime: false | |
}; | |
$scope.tsData.shifts.push(newShift); | |
$scope.overtimeFlag = false; | |
$scope.checkIfPreviousShiftSaved = function(){ | |
var shiftsNumber = $scope.tsData.shifts.length; | |
var lastShift = $scope.tsData.shifts[shiftsNumber-1]; | |
if (lastShift.saved){ | |
return true | |
} else { | |
return false | |
} | |
}; | |
$scope.highlightOvertimeShift = function(shiftIdxTrigger){ | |
if ($scope.tsData.dailyOvertimeMins === Math.abs($scope.tsData.dailyOvertimeMins)){ //if overtime mins | |
if ($scope.overtimeFlag === false){ | |
$scope.overtimeFlag = true; | |
$scope.shiftIdxTrigger = shiftIdxTrigger; | |
} | |
} | |
}; | |
$scope.addShift = function(){ | |
var previousShiftSaved = $scope.checkIfPreviousShiftSaved(); | |
if (!previousShiftSaved) { | |
swal("Oops","Please save your previous shift before adding a new one.","error"); | |
return; | |
} | |
if ($scope.tsData.shifts.length < 5) { //add max 5 shifts per day | |
var newShift2 = { | |
startTimeObj: null, | |
endTimeObj: null, | |
startTimeMeridian: null, | |
endTimeMeridian: null, | |
milesPerShift: 0, | |
note: "", | |
isSelected: true, | |
idx: 0, | |
mileageRefund: 0, | |
timeDiffHoursMins: 0, | |
timeDiffMins: 0, | |
saved: false, | |
overtime: false | |
}; | |
$scope.tsData.shifts.push(newShift2); | |
} else { | |
swal("Oops","You cannot work on more than 5 shifts per day.","error"); | |
} | |
console.log('after add, shifts are ', $scope.tsData.shifts); | |
$scope.highlightOvertimeShift($scope.tsData.shifts.length); | |
}; | |
$scope.removeShift = function(shiftSelected, shiftIdx){ | |
$scope.tsData.shifts.splice(shiftIdx, 1); | |
console.log('after remove, shifts are ', $scope.tsData.shifts); | |
}; | |
$scope.checkIfShiftLaterThanPrevious = function(shiftIdx, startTimeObj){ | |
var previousShiftEndTimeObj = $scope.tsData.shifts[shiftIdx-1].endTimeObj; | |
var previousShiftEndTimeMins = $scope.convertTimeObjToMins(previousShiftEndTimeObj); | |
var thisShiftStartTimeMins = $scope.convertTimeObjToMins(startTimeObj); | |
var timeDiff = thisShiftStartTimeMins - previousShiftEndTimeMins; | |
if (timeDiff === Math.abs(timeDiff)){ //if nxt start time later than prev end time | |
return true; | |
} else { | |
return false; | |
} | |
}; | |
$scope.updateStartTime = function(timeSelected, shiftSelected, shiftIdx){ | |
console.log('shift idx is ', 0, 'selected and time ', shiftSelected, timeSelected); | |
var startTimeObj = $scope.adjustTimeForCalendar(timeSelected); | |
if (shiftIdx > 0){ //check for all, except first shift | |
var laterThanPrevious = $scope.checkIfShiftLaterThanPrevious(shiftIdx, startTimeObj); | |
if (!laterThanPrevious){ | |
swal("Create a later shift","Your shifts must be submitted chronologically.","error"); | |
} | |
} | |
shiftSelected.startTimeMeridian = timeSelected; | |
shiftSelected.startTimeObj = startTimeObj; | |
shiftSelected.idx = shiftIdx; | |
$scope.tsData.shifts[shiftIdx] = shiftSelected; | |
console.log('updated shift times after update start is ', $scope.tsData.shifts[shiftIdx]); | |
}; | |
$scope.updateEndTime = function(timeSelected, shiftSelected, shiftIdx){ | |
console.log('shift idx is ', 0, 'selected and time ', shiftSelected, timeSelected); | |
var endTimeObj = $scope.adjustTimeForCalendar(timeSelected); | |
//before assigning new end time to shift obj, need to check that endtime is later than startTime | |
var timeSelectedIsOK = $scope.lockCellIfEarlierThanStartTime(shiftSelected, shiftIdx, endTimeObj); | |
if (!timeSelectedIsOK){ | |
swal("Wrong time selected","You cannot select an end time earlier than a start time.","error"); | |
return; | |
} | |
shiftSelected.endTimeMeridian = timeSelected; | |
shiftSelected.endTimeObj = endTimeObj; | |
shiftSelected.idx = shiftIdx; | |
$scope.tsData.shifts[shiftIdx] = shiftSelected; | |
console.log('updated shift times after update end is ', $scope.tsData.shifts[shiftIdx]); | |
}; | |
$scope.lockCellIfEarlierThanStartTime = function(shiftSelected, shiftIdx, endTimeObj){ | |
var timeDiffMins = $scope.calculateTimeDiffMins(shiftSelected.startTimeObj, endTimeObj); | |
console.log('time diff mins is ', timeDiffMins); | |
if (timeDiffMins === Math.abs(timeDiffMins)){ //if val negative, endTime is earlier so alert user | |
return true | |
} else { | |
return false | |
} | |
}; | |
$scope.toggleNote = function(shiftIdx){ | |
$scope.showNote[shiftIdx] = !$scope.showNote[shiftIdx]; | |
}; | |
$scope.recordShift = function(shiftIdx){ | |
$scope.tsData.shifts[shiftIdx].saved = true; | |
$scope.tsData.shiftSelectedIdx = $scope.tsData.shifts[shiftIdx].idx = shiftIdx; | |
$scope.tsData.shifts[shiftIdx].mileageRefund = $scope.calculateMileageRefund(shiftIdx); //calculate mileage refund | |
$scope.tsData.totalMileageRefund += $scope.tsData.shifts[shiftIdx].mileageRefund; //add to total daily mileage refund | |
$scope.calculateTotalWorkTime(shiftIdx); //calculates work time and work overtime | |
$scope.calculateOvertime(); | |
console.log('new shift saved is ', $scope.tsData.shifts[shiftIdx]); | |
console.log('after record, shifts are ', $scope.tsData.shifts) | |
}; | |
$scope.calculateMileageRefund = function(shiftIdx){ | |
var mileageRefund = $scope.tsData.rates.mileageRate * $scope.tsData.shifts[shiftIdx].milesPerShift; | |
return mileageRefund; | |
}; | |
$scope.calculateTotalWorkTime = function(shiftIdx){ | |
var startTimeObj; var endTimeObj; var startTimeMins; var endTimeMins; var timeDiffMins; var overtime; var timeDiffHoursMins; | |
for (var i in $scope.tsData.shifts) { | |
startTimeObj = $scope.tsData.shifts[i].startTimeObj; | |
endTimeObj = $scope.tsData.shifts[i].endTimeObj; | |
timeDiffMins = $scope.calculateTimeDiffMins(startTimeObj, endTimeObj); | |
timeDiffHoursMins = $scope.convertMinsToHoursMinsObj(timeDiffMins); | |
$scope.tsData.shifts[shiftIdx].timeDiffMins = timeDiffMins; | |
$scope.tsData.shifts[shiftIdx].timeDiffHoursMins = timeDiffHoursMins; | |
$scope.tsData.dailyWorkTimeMins += timeDiffMins; | |
} | |
}; | |
$scope.calculateTimeDiffMins = function(startTimeObj, endTimeObj){ | |
var startTimeMins = $scope.convertTimeObjToMins(startTimeObj); | |
var endTimeMins = $scope.convertTimeObjToMins(endTimeObj); | |
var timeDiffMins = endTimeMins - startTimeMins; | |
return timeDiffMins | |
}; | |
$scope.convertTimeObjToMins = function(timeObj){ | |
var timeMins = (timeObj.hour * 60) + timeObj.min; | |
return timeMins; | |
}; | |
$scope.deductLunch = function(){ | |
if ($scope.tsData.tookLunch){ // if lunch selected, deduct 30mins | |
$scope.tsData.dailyWorkTimeMins = $scope.tsData.dailyWorkTimeMins - 30 | |
} else { | |
$scope.tsData.dailyWorkTimeMins = $scope.tsData.dailyWorkTimeMins + 30 | |
} | |
console.log('updated deduct lunch time is ', $scope.tsData.dailyWorkTimeMins); | |
}; | |
$scope.calculateOvertime = function(){ | |
var otBenchmarkMins = $scope.tsData.rates.otBenchmark * 60; | |
$scope.tsData.dailyOvertimeMins = $scope.tsData.dailyWorkTimeMins - otBenchmarkMins | |
}; | |
$scope.submitTimesheet = function(){ | |
$scope.calculateDayOfPeriod(); | |
console.log('timesheet to be saved in ', $scope.tsData); | |
DataService.addTimesheet($scope.tsData) | |
.then(function(data){ | |
console.log('returned from save ', data); | |
swal("Timesheet added","Your timesheet was succesfully saved to the database.","success"); | |
var domain = window.location.host; | |
var pathname = '/timesheets'; | |
var url = domain + pathname; | |
console.log('url is ', url); | |
$scope.backToTimesheet = true | |
}).catch(function(error){ | |
swal("Error","There was an error saving your timesheet. Please try again or contact Customer Support","error"); | |
}) | |
}; | |
$scope.parseAffiliateNameToList = function(affiliate){ | |
if ($stateParams.filter){ //if comments page loaded directly from browser with filter params | |
console.log('affiliate param in parseAffiliate is ', affiliate); | |
// $scope.getCommentsPerAffiliate(affiliate); | |
var affiliate = {}; | |
affiliate.name = $stateParams.filter; | |
for (var eachAffiliate in $scope.affiliateList){ | |
var theAffiliate = $scope.affiliateList[eachAffiliate] | |
if (theAffiliate.name === affiliate.name){ | |
$scope.itnAffiliate = theAffiliate; | |
} | |
} | |
} else if (affiliate){ //if comments loaded from affiliate section | |
for (var eachAffiliate in $scope.affiliateList){ | |
var theAffiliate = $scope.affiliateList[eachAffiliate] | |
if (theAffiliate.name === affiliate.name){ | |
$scope.itnAffiliate = theAffiliate; | |
} | |
} | |
} | |
console.log('$scope.itnAffiliate in parseAffiliate is ', $scope.itnAffiliate); | |
}; | |
$scope.parseAffiliateNameToList = function(affiliate){ | |
if ($stateParams.filter){ //if comments page loaded directly from browser with filter params | |
console.log('affiliate param in parseAffiliate is ', affiliate); | |
// $scope.getCommentsPerAffiliate(affiliate); | |
var affiliate = {}; | |
affiliate.name = $stateParams.filter; | |
for (var eachAffiliate in $scope.affiliateList){ | |
var theAffiliate = $scope.affiliateList[eachAffiliate] | |
if (theAffiliate.name === affiliate.name){ | |
$scope.itnAffiliate = theAffiliate; | |
} | |
} | |
} else if (affiliate){ //if comments loaded from affiliate section | |
for (var eachAffiliate in $scope.affiliateList){ | |
var theAffiliate = $scope.affiliateList[eachAffiliate] | |
if (theAffiliate.name === affiliate.name){ | |
$scope.itnAffiliate = theAffiliate; | |
} | |
} | |
} | |
console.log('$scope.itnAffiliate in parseAffiliate is ', $scope.itnAffiliate); | |
}; | |
$scope.parseDayAndAffiliateParams = function(){ | |
console.log('stateparams are ', $stateParams); | |
var params = $stateParams.filter; | |
if ($stateParams.filter && ($stateParams.filter.indexOf('?day=') !== -1)){ | |
console.log('filter is ', params); | |
$scope.tsData.day = params.substr(params.indexOf('=') + 1); | |
console.log('day is ', $scope.tsData.day); | |
$scope.tsData.affiliate = params.substr(0, params.indexOf('?')); | |
console.log('affiliate is ', $scope.tsData.affiliate); | |
} else if ($stateParams.filter){ | |
console.log('filter, only aff is ', params); | |
$scope.tsData.affiliate = $stateParams.filter; | |
} | |
console.log('just created affiliate var is ', $scope.tsData.affiliate); | |
}; | |
$scope.parseParamsIfTimesheet = function(){ | |
if ($stateParams.day && $stateParams.timesheet){ | |
$scope.existingTimesheetDay = $stateParams.day; | |
$scope.existingTimesheet = $stateParams.timesheet; | |
} | |
} | |
$scope.getTimesheets = function(){ | |
console.log('in ctrl, getting ts from affiliate ', $scope.tsData.affiliate); | |
var affiliateName = $scope.tsData.affiliate; | |
DataService.getTimesheets() | |
.then(function(data){ | |
console.log('data from ctrl is ', data.data); | |
$scope.timesheets = data.data; | |
console.log('timesheets are', $scope.timesheets); | |
}) | |
}; | |
$scope.deleteTimesheet = function(){ | |
console.log('timesheet to delete is ', $scope.tsData); | |
DataService.deleteTimesheet($scope.tsData) | |
.then(function(data){ | |
console.log('returned from delete ', data); | |
swal("Timesheet deleted","Your timesheet was succesfully deleted from the database.","success"); | |
$scope.backToTimesheet = true | |
}).catch(function(error){ | |
swal("Error","There was an error deleting your timesheet. Please try again or contact Customer Support","error"); | |
}) | |
}; | |
$scope.deleteTimesheetFromIndex = function(timesheet){ | |
console.log('timesheet to delete is ', timesheet); | |
DataService.deleteTimesheet(timesheet) | |
.then(function(data){ | |
console.log('returned from delete ', data); | |
swal("Timesheet deleted","Your timesheet was succesfully deleted from the database.","success"); | |
$scope.getTimesheets(); | |
}).catch(function(error){ | |
swal("Error","There was an error deleting your timesheet. Please try again or contact Customer Support","error"); | |
}) | |
}; | |
$scope.editTimesheet = function(){ | |
DataService.editTimesheet($scope.tsData) | |
.then(function(data){ | |
console.log('returned from edit ', data); | |
swal("Timesheet deleted","Your timesheet was succesfully updated.","success"); | |
}).catch(function(error){ | |
swal("Error","There was an error updating your timesheet. Please try again or contact Customer Support","error"); | |
}) | |
}; | |
$scope.isNewTimesheet = function(){ | |
$scope.viewNewTimesheet = $stateParams.viewNewTimesheet; | |
console.log('viewNewTimesheet is ', $scope.viewNewTimesheet); | |
}; | |
$scope.calculateDayOfPeriod = function(){ | |
var day = $scope.tsData.date.getDate(); | |
console.log('day of month is ', day); | |
var range1 = 15; var range2 = 31; | |
var period1 = []; var period2 = []; | |
for (var i = 1; i <= range1; i++) { period1.push(i)} | |
for (var i = range1; i <= range2; i++) { period2.push(i)} | |
if (day < range1){ | |
//if day contains number in period1, assign the index of array as day of object | |
if (period1.indexOf(day) !== - 1){ | |
var idx = period1.indexOf(day); | |
$scope.tsData.day = idx + 1; | |
} | |
} else { | |
if (period2.indexOf(day) !== - 1){ | |
var idx = period2.indexOf(day); | |
$scope.tsData.day = idx + 1; | |
} | |
} | |
console.log('day of period is ', $scope.tsData.day) | |
}; | |
}]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="timesheet portal" ng-init="parseDayAndAffiliateParams();getTimesheets();parseParamsIfTimesheet()"> | |
<div class="container-fluid recorded-timesheets"> | |
<h2>Timesheets</h2> | |
<a ui-sref="timesheet({viewNewTimesheet: true})" | |
class="btn btn-lg" | |
style="margin-left:60%;"> | |
Create New Timesheet | |
</a> | |
<div class="row" ng-repeat="timesheet in timesheets | orderBy:true " style="width:70%"> | |
<div class="col-sm-6"> | |
<a ui-sref="timesheet({day: timesheet.day, timesheet: timesheet})" | |
style="display:block"> | |
Day {{timesheet.day}} | {{timesheet.date | date}} | |
</a> | |
</div> | |
<div class="col-sm-6"> | |
<button type="button" | |
ng-click="deleteTimesheetFromIndex(timesheet)" | |
class="btn btn-lg btn-primary pull-left itn-green-bg" | |
style="margin-left:2%;background:#e05944 !important"> | |
Delete Timesheet | |
</button> | |
</div> | |
</div> | |
</div><!--container--> | |
</div><!--timesheet--> | |
<div class="back-btn-wrap"> | |
<a ui-sref="affiliate({filter: itnAffiliate.name})" class="back-btn"> | |
<h3>Back to Previous Page</h3> | |
</a> | |
<a ui-sref="portal" class="back-btn"> | |
<h3>Back to Portal</h3> | |
</a> | |
</div> | |
<!-- <ul class="nav nav-tabs"> | |
<li ng-repeat="timesheet in timesheets"><a ui-sref="timesheet({filter: tsData.affiliate + '?day=' + timesheet.day})">Day {{timesheet.day}}</a></li> | |
</ul> --> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment