Skip to content

Commit

Permalink
Merge ca56e1b into 0ba91e1
Browse files Browse the repository at this point in the history
  • Loading branch information
Qausim committed Sep 12, 2019
2 parents 0ba91e1 + ca56e1b commit 935bd6f
Show file tree
Hide file tree
Showing 13 changed files with 674 additions and 8 deletions.
38 changes: 37 additions & 1 deletion src/controllers/facilities.controller.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import models from '../db/models';
import Response from '../utils/response.utils';
import FacilityUtils from '../utils/facility.utils';

const { Facility, Room, Like } = models;
const {
Facility, Room, Like, Booking
} = models;

/**
* This class creates the facilities controllers
Expand Down Expand Up @@ -107,4 +110,37 @@ export default class FacilitiesController {
return Response.InternalServerError(res, 'Could not like facility');
}
}

/**
* Books a room in an accomodation facility
* @param {object} req
* @param {object} res
* @param {object} next
* @return {object|function} ServerResponse or next
*/
static async bookFacility(req, res, next) {
const { room_id } = req.params, { id: user_id } = req.currentUser;
try {
// Confirm the specified room exists, else return a 404
const room = await Room.findByPk(room_id, { attributes: [] });
if (!room) return Response.NotFoundError(res, 'Room not found');
// Check if an existing booking conflicts with the one to be made and return a 409
const { departure_date, return_date } = req.body;
const conflictingBooking = await Booking.findOne(FacilityUtils
.getConflictingBookingQuery(room_id, departure_date, return_date));

if (conflictingBooking) {
return Response.ConflictError(res, {
message: `This accomodation is already book from ${conflictingBooking.departure_date} to ${
conflictingBooking.return_date}`
});
}
// If all checks out so far, create a new booking and return its details
const newBooking = await Booking.create({
room_id, user_id, departure_date, return_date
}, { returning: true });

return Response.Success(res, newBooking.dataValues, 201);
} catch (error) { next(new Error('Internal server error')); }
}
}
5 changes: 3 additions & 2 deletions src/db/migrations/20190821153031-create-booking.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ module.exports = {
onDelete: 'CASCADE'
},
departure_date: {
type: Sequelize.DATE,
type: Sequelize.DATEONLY,
allowNull: false
},
return_date: {
type: Sequelize.DATE,
type: Sequelize.DATEONLY,
allowNull: false
},
checked_in: {
type: Sequelize.BOOLEAN,
Expand Down
5 changes: 3 additions & 2 deletions src/db/models/booking.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
module.exports = (sequelize, DataTypes) => {
const Booking = sequelize.define('Booking', {
departure_date: {
type: DataTypes.DATE,
type: DataTypes.DATEONLY,
allowNull: false
},
return_date: {
type: DataTypes.DATE,
type: DataTypes.DATEONLY,
allowNull: false
},
checked_in: {
type: DataTypes.BOOLEAN,
Expand Down
5 changes: 3 additions & 2 deletions src/db/seeders/20190828065846-bookings-seeder.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ module.exports = {
user_id: 1,
room_id: 1,
departure_date: new Date(),
return_date: new Date(new Date().getTime() + 14 * 24 * 3600000),
created_at: new Date(),
updated_at: new Date()
},
{
user_id: 2,
room_id: 2,
departure_date: new Date(),
return_date: new Date(),
departure_date: new Date(new Date().getTime() + 7 * 24 * 3600000),
return_date: new Date(new Date().getTime() + 24 * 24 * 3600000),
created_at: new Date(),
updated_at: new Date()
}], {}),
Expand Down
2 changes: 2 additions & 0 deletions src/middlewares/auth.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import jwt from 'jsonwebtoken';
import models from '../db/models';
import Response from '../utils/response.utils';

const { User } = models;

Expand Down Expand Up @@ -40,6 +41,7 @@ const auth = {
}

const user = await User.findOne({ where: { id: decoded.payload.id } });
if (!user) return Response.UnauthorizedError(res, 'Failed to authenticate token', 401);
req.currentUser = user;
const { payload } = decoded;
req.body.user = user;
Expand Down
30 changes: 30 additions & 0 deletions src/middlewares/facilities.middleware.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import FacilityUtils from '../utils/facility.utils';
import Response from '../utils/response.utils';
import HelperUtils from '../utils/helpers.utils';

const { getFacilitiesDetails } = FacilityUtils;
const { getRoomsDetails } = FacilityUtils;
const dateIntervalError = 'The return date must be ahead of the departure date';

const FacilitiesChecks = {
async getFacilitiesValues(req, res, next) {
Expand Down Expand Up @@ -39,6 +42,33 @@ const FacilitiesChecks = {
status: 'error',
error: 'You have not entered any room details'
});
},

/**
* Ensures the date fields supplied in the booking request are valid
* @param {object} req
* @param {object} res
* @param {object} next
* @returns {undefined|object} nothing or ServerResponse object
*/
validateBookingDates(req, res, next) {
const errors = {};
const { departure_date, return_date } = req.body;
// If any invalid date value exists populate an error on "errors"
HelperUtils.validateDatesFieldFormat({ departure_date, return_date }, errors);
// If departure date is same as or ahead of return date populate an error on "errors"
if ((new Date(return_date) - new Date(departure_date)) <= 0) {
errors.intervalError = dateIntervalError;
}
// If departure date is lesser than today populate an error on "errors"
const today = new Date().toISOString().split('T')[0];
if ((new Date(departure_date) - new Date(today)) < 0) {
errors.departureDateError = 'Departure date cannot be lesser than today';
}
// If any error has occured return a bad request error, else proceed to the controller
if (Object.keys(errors).length) return Response.BadRequestError(res, errors);

next();
}
};

Expand Down
4 changes: 4 additions & 0 deletions src/routes/api/facilities.router.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import validateFacilities from '../../validation/facilities/facilities.validatio
import validateRooms from '../../validation/facilities/rooms.validation';
import FacilitiesChecks from '../../middlewares/facilities.middleware';


const router = express.Router();

/* Requests Routes Here */
Expand All @@ -29,4 +30,7 @@ router.post('/facilities/rooms',
router.get('/facilities',
facilitiesController.getAllFacilities);

router.post('/facilities/rooms/:room_id/book', auth.verifyUserToken,
FacilitiesChecks.validateBookingDates, facilitiesController.bookFacility);

export default router;
Loading

0 comments on commit 935bd6f

Please sign in to comment.