Skip to content

Instantly share code, notes, and snippets.

@samguergen
Created February 13, 2019 20:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samguergen/eeef5695adc8d1dc2f9fa6d72ffce32f to your computer and use it in GitHub Desktop.
Save samguergen/eeef5695adc8d1dc2f9fa6d72ffce32f to your computer and use it in GitHub Desktop.
Timesheets functionality files isolated from the widget repo
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:samanthics2504@ds119662.mlab.com: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);
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
}
};
}]);
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;
})
};
}]);
<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>
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)
};
}]);
<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