Skip to content

Commit

Permalink
Merge b5bee68 into a3bb8d0
Browse files Browse the repository at this point in the history
  • Loading branch information
higustave-ops committed Mar 23, 2020
2 parents a3bb8d0 + b5bee68 commit 4327b61
Show file tree
Hide file tree
Showing 14 changed files with 675 additions and 22 deletions.
130 changes: 130 additions & 0 deletions src/controllers/accommodation.controller.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import AccommodationService from '../services/accommodation.service';
import ResponseService from '../services/response.service';
import LikesService from '../services/likes.service';

/**
*
Expand Down Expand Up @@ -27,6 +28,11 @@ class AccommodationController {
{ accommodationId: req.params.accommodationId, id: req.params.roomId },
{ availableRooms: req.availableRooms - 1 }
);
await AccommodationService.createAccommodationReaction({
accommodationId: req.params.accommodationId,
roomId: req.params.roomId,
userId: req.userData.id
});
ResponseService.setSuccess(201, 'Accommodation is successfully booked', dataValues);
return ResponseService.send(res);
}
Expand Down Expand Up @@ -75,6 +81,130 @@ class AccommodationController {
ResponseService.setSuccess(201, 'Accommodation is successfully created', newAccommodation);
return ResponseService.send(res);
}

/**
*
* @static
* @param {req} req
* @param {res} res
* @returns {response} @memberof AccommodationController
*/
static async updateAccommodationReaction(req, res) {
let like = req.likeValue;
let unlike = req.unlikeValue;
if (like !== undefined && unlike !== undefined) {
const { accommodationId, roomId } = req.params;
const userId = req.userData.id;
const reactionRecord = await LikesService.findReactionRecordByProperty({
accommodationId, userId, roomId
});
const bookedRoom = await AccommodationService.findRoomByProperty(
{ id: roomId, accommodationId }
);
let bookedRoomLikesCounts;
let bookedRoomDisLikesCounts;
if (bookedRoom) {
bookedRoomLikesCounts = bookedRoom.likesCount;
bookedRoomDisLikesCounts = bookedRoom.dislikesCount;
}
if (like === true && (reactionRecord.like) === like) {
like = !reactionRecord.like;
await AccommodationService.updateRoom(
{
id: roomId,
accommodationId
},
{
likesCount: bookedRoomLikesCounts - 1
}
);
}

if (like === true && (reactionRecord.like) !== like) {
await AccommodationService.updateRoom(
{
id: roomId,
accommodationId
},
{
likesCount: bookedRoomLikesCounts + 1
}
);
}

if (like !== true && (reactionRecord.like) !== like) {
await AccommodationService.updateRoom(
{
id: roomId,
accommodationId
},
{
likesCount: bookedRoomLikesCounts - 1
}
);
}
if (unlike === true && (reactionRecord.unlike) === unlike) {
unlike = !reactionRecord.unlike;
await AccommodationService.updateRoom(
{
id: roomId,
accommodationId
},
{
dislikesCount: bookedRoomDisLikesCounts - 1
}
);
}

if (unlike === true && (reactionRecord.unlike) !== unlike) {
await AccommodationService.updateRoom(
{
id: roomId,
accommodationId
},
{
dislikesCount: bookedRoomDisLikesCounts + 1
}
);
}

if (unlike !== true && (reactionRecord.unlike) !== unlike) {
await AccommodationService.updateRoom(
{
id: roomId,
accommodationId
},
{
dislikesCount: bookedRoomDisLikesCounts - 1
}
);
}
const [, [{ dataValues }]] = await LikesService.updateALike({
accommodationId, userId, roomId
}, { like, unlike });
ResponseService.setSuccess(200, 'Reaction updated successfully', dataValues);
ResponseService.send(res);
}
}

/**
*
*
* @static
* @param {req} req
* @param {res} res
* @returns {response} @memberof AccommodationController
*/
static async countReactionsOnAccommodation(req, res) {
const likesCount = await AccommodationService.findAccommodationReactionRecordByProperty({
accommodationId: req.params.accommodationId, like: true
});
const unlikesCount = await AccommodationService.findAccommodationReactionRecordByProperty({
accommodationId: req.params.accommodationId, unlike: true
});
ResponseService.setSuccess(200, 'Reaction records successfully retrieved', { likes: likesCount.length, dislikes: unlikesCount.length });
ResponseService.send(res);
}
}

export default AccommodationController;
66 changes: 56 additions & 10 deletions src/middlewares/accommodation.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Op } from 'sequelize';
import LocationService from '../services/location.service';
import ResponseService from '../services/response.service';
import AccommodationService from '../services/accommodation.service';
import BookingService from '../services/booking.service';


export const checkIfAccommodationTypeExists = async (req, res, next) => {
Expand Down Expand Up @@ -41,17 +42,18 @@ export const checkAvailability = async (req, res, next) => {
const searchResult = await AccommodationService
.findAccommodationWithInclude(
req.params.accommodationId,
{ include: [
{
association: 'rooms',
where: {
id: req.params.roomId,
availableRooms: {
[Op.gt]: 0
{
include: [
{
association: 'rooms',
where: {
id: req.params.roomId,
availableRooms: {
[Op.gt]: 0
}
}
}
}
]
]
}
);

Expand All @@ -67,7 +69,8 @@ export const checkAvailability = async (req, res, next) => {

export const checkPermission = async (req, res, next) => {
const searchResult = await AccommodationService
.findBookingByProperty({ userId: req.userData.id,
.findBookingByProperty({
userId: req.userData.id,
roomId: req.params.roomId,
[Op.or]: [{
from: {
Expand All @@ -87,3 +90,46 @@ export const checkPermission = async (req, res, next) => {
ResponseService.send(res);
}
};

const accommodationMiddleware = {
checkBookingExist: async (req, res, next) => {
const bookingData = await BookingService.findBookingByProperty({
accommodationId: req.params.accommodationId,
roomId: req.params.roomId,
userId: req.userData.id
});
if (bookingData) {
req.bookingData = bookingData;
}
if (!bookingData) {
ResponseService.setError(404, 'Accommodation booking not found');
return ResponseService.send(res);
}
next();
},
checkIfLikeUnlikeAreSame: async (req, res, next) => {
let like;
let unlike;
if (req.body.like === 'yes') {
like = true;
} else {
like = false;
}
if (req.body.unlike === 'yes') {
unlike = true;
} else {
unlike = false;
}
if (like !== unlike) {
req.likeValue = like;
req.unlikeValue = unlike;
}
if ((like === true && unlike === true) || (like === false && unlike === false)) {
ResponseService.setError(400, 'Like and unlike must have different values');
ResponseService.send(res);
}
next();
},
};

export default accommodationMiddleware;
6 changes: 6 additions & 0 deletions src/migrations/20200115164146-create-rooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ export const up = (queryInterface, Sequelize) => queryInterface.createTable('Roo
roomPrice: {
type: Sequelize.DECIMAL(10, 2)
},
likesCount: {
type: Sequelize.INTEGER
},
dislikesCount: {
type: Sequelize.INTEGER
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
Expand Down
39 changes: 39 additions & 0 deletions src/migrations/20200119150631-create-likes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
export const up = (queryInterface, Sequelize) => queryInterface.createTable('likes', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
accommodationId: {
type: Sequelize.INTEGER
},
userId: {
type: Sequelize.INTEGER
},
roomId: {
type: Sequelize.INTEGER
},
like: {
type: Sequelize.BOOLEAN,
defaultValue: false
},
unlike: {
type: Sequelize.BOOLEAN,
defaultValue: false
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
/**
* @exports
* @class
* @param {object} queryInterface
*/
export function down(queryInterface) { return queryInterface.dropTable('likes'); }
10 changes: 10 additions & 0 deletions src/models/likes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default (sequelize, DataTypes) => {
const likes = sequelize.define('likes', {
accommodationId: DataTypes.INTEGER,
userId: DataTypes.INTEGER,
roomId: DataTypes.INTEGER,
like: DataTypes.BOOLEAN,
unlike: DataTypes.BOOLEAN
}, {});
return likes;
};
4 changes: 3 additions & 1 deletion src/models/rooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export default (sequelize, DataTypes) => {
numberOfPeople: DataTypes.INTEGER,
numberOfRooms: DataTypes.INTEGER,
availableRooms: DataTypes.INTEGER,
roomPrice: DataTypes.DECIMAL(10, 2)
roomPrice: DataTypes.DECIMAL(10, 2),
likesCount: DataTypes.INTEGER,
dislikesCount: DataTypes.INTEGER
}, {});
Rooms.associate = (models) => {
// associations can be defined here
Expand Down
24 changes: 20 additions & 4 deletions src/routes/accommodation.route.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import express from 'express';
import authMiddleware from '../middlewares/auth.middleware';
import AccommodationController from '../controllers/accommodation.controller';
import { bookAccommodationValidation, createAccommodationValidations } from '../validations/accommodation.validation';
import { checkIfAccommodationTypeExists,
import {
bookAccommodationValidation,
createAccommodationValidations,
validateAccommodationReaction
} from '../validations/accommodation.validation';
import accommodationMiddleware, { checkIfAccommodationTypeExists,
checkIfLocationExists,
avoidDuplicateAccommodation,
checkPermission,
Expand All @@ -26,6 +30,18 @@ router.post(
checkIfAccommodationTypeExists, checkIfLocationExists,
AccommodationController.createAccommodation
);


router.patch(
'/:accommodationId/rooms/:roomId/react',
authMiddleware.checkUserLoggedIn,
validateAccommodationReaction,
accommodationMiddleware.checkBookingExist,
accommodationMiddleware.checkIfLikeUnlikeAreSame,
AccommodationController.updateAccommodationReaction
);
router.get(
'/:accommodationId/rooms/:roomId/reactions-count',
authMiddleware.checkUserLoggedIn,
accommodationMiddleware.checkBookingExist,
AccommodationController.countReactionsOnAccommodation
);
export default router;
Loading

0 comments on commit 4327b61

Please sign in to comment.