Skip to content

Commit

Permalink
feature/modify-db
Browse files Browse the repository at this point in the history
- add startTime column
- add endTime column to events database
- write controller to ensure booked times are not overlapping
- write tests for controller
  • Loading branch information
Billmike committed Apr 19, 2018
1 parent e17ce2b commit 13a9c5c
Show file tree
Hide file tree
Showing 14 changed files with 318 additions and 50 deletions.
70 changes: 64 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
"jsonwebtoken": "^8.2.1",
"libphonenumber-js": "^1.1.10",
"lodash": "^4.17.5",
"moment": "^2.22.1",
"moment-range": "^4.0.0",
"morgan": "^1.9.0",
"nexmo": "^2.2.0",
"nodemailer": "^4.6.4",
"pg": "^7.4.1",
"pg-hstore": "^2.3.2",
"sequelize": "^4.37.6"
"sequelize": "^4.37.6",
"timediff": "^1.1.1"
},
"devDependencies": {
"chai": "^4.1.2",
Expand Down
75 changes: 59 additions & 16 deletions server/controllers/event.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import Moment from 'moment';
import { extendMoment } from 'moment-range';
import timeDifference from 'timediff';
import db from '../models';
import mailer from './mailer';
import serverError from '../errorHandler/serverError';
Expand All @@ -21,23 +24,62 @@ class Events {
message: 'No center found with this name.'
});
}
Event.create({
name: request.body.name,
image: request.body.image,
date: request.body.date,
duration: request.body.duration,
organizer: request.userDetails.id,
venue: foundCenter.dataValues.id
}).then((event) => {
return response.status(201).json({
message: 'Event created successfully.',
eventDetails: {
name: event.name,
image: event.image,
date: event.date,
duration: event.duration,
venue: foundCenter.dataValues.name
const duration = timeDifference(
request.body.startTime,
request.body.endTime
);

const convertStartTime = new Date(request.body.startTime)
.toLocaleTimeString('en-US', { hour12: false });
const convertEndTime = new Date(request.body.endTime)
.toLocaleTimeString('en-US', { hour12: false });

const eventDuration =
`${duration.hours}hour(s), ${duration.minutes}minutes`;

return Event.findAll({
where: {
date: request.body.date,
venue: foundCenter.dataValues.id
}
}).then((foundEvent) => {
for (let index = 0; index < foundEvent.length; index += 1) {
const event = foundEvent[index];
if ((convertStartTime >= event.dataValues.startTime
&& convertStartTime <= event.dataValues.endTime) ||
(convertEndTime <= event.dataValues.endTime
&& convertEndTime >= event.dataValues.startTime)) {
return response.status(409).json({
message:
`Sorry, you cannot book an event at this
time because there will be an event
holding between ${event.dataValues.startTime} and ${event.dataValues.endTime}.`
});
}
}

return Event.create({
name: request.body.name,
image: request.body.image,
date: request.body.date,
startTime: request.body.startTime,
endTime: request.body.endTime,
duration: eventDuration,
organizer: request.userDetails.id,
venue: foundCenter.dataValues.id
}).then((event) => {
return response.status(201).json({
message: 'Event created successfully.',
eventDetails: {
name: event.name,
image: event.image,
date: event.date,
startTime: event.startTime,
endTime: event.endTime,
duration: event.duration,
venue: foundCenter.dataValues.name
}
});
});
});
}).catch((err) => {
Expand All @@ -46,6 +88,7 @@ class Events {
});
});
}

static getEvents(request, response) {
return Event.findAndCountAll()
.then((allEvents) => {
Expand Down
26 changes: 26 additions & 0 deletions server/migrations/20180418225056-startTime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

module.exports = {
up: (queryInterface, Sequelize) => {
/*
Add altering commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.createTable('users', { id: Sequelize.INTEGER });
*/
return queryInterface.addColumn('Events', 'startTime', {
type: Sequelize.TIME
});
},

down: (queryInterface, Sequelize) => {
/*
Add reverting commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.dropTable('users');
*/
}
};
26 changes: 26 additions & 0 deletions server/migrations/20180418225209-endTime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

module.exports = {
up: (queryInterface, Sequelize) => {
/*
Add altering commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.createTable('users', { id: Sequelize.INTEGER });
*/
return queryInterface.addColumn('Events', 'endTime', {
type: Sequelize.TIME
});
},

down: (queryInterface, Sequelize) => {
/*
Add reverting commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.dropTable('users');
*/
}
};
24 changes: 24 additions & 0 deletions server/migrations/20180418225803-dropDuration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

module.exports = {
up: (queryInterface, Sequelize) => {
/*
Add altering commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.createTable('users', { id: Sequelize.INTEGER });
*/
return queryInterface.removeColumn('Events', 'duration');
},

down: (queryInterface, Sequelize) => {
/*
Add reverting commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.dropTable('users');
*/
}
};
26 changes: 26 additions & 0 deletions server/migrations/20180418225851-addDuration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

module.exports = {
up: (queryInterface, Sequelize) => {
/*
Add altering commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.createTable('users', { id: Sequelize.INTEGER });
*/
return queryInterface.addColumn('Events', 'duration', {
type: Sequelize.TIME
});
},

down: (queryInterface, Sequelize) => {
/*
Add reverting commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.dropTable('users');
*/
}
};
24 changes: 24 additions & 0 deletions server/migrations/20180418230549-dropDuration2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

module.exports = {
up: (queryInterface, Sequelize) => {
/*
Add altering commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.createTable('users', { id: Sequelize.INTEGER });
*/
return queryInterface.removeColumn('Events', 'duration');
},

down: (queryInterface, Sequelize) => {
/*
Add reverting commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.dropTable('users');
*/
}
};
26 changes: 26 additions & 0 deletions server/migrations/20180418230619-addDuration2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

module.exports = {
up: (queryInterface, Sequelize) => {
/*
Add altering commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.createTable('users', { id: Sequelize.INTEGER });
*/
return queryInterface.addColumn('Events', 'duration', {
type: Sequelize.TEXT
});
},

down: (queryInterface, Sequelize) => {
/*
Add reverting commands here.
Return a promise to correctly handle asynchronicity.
Example:
return queryInterface.dropTable('users');
*/
}
};
Loading

0 comments on commit 13a9c5c

Please sign in to comment.