Skip to content

Commit

Permalink
feat(Book Accommodation): implement accommodation booking
Browse files Browse the repository at this point in the history
- create a booking accommodation controller
- create booking accommodation route
- create a validation schema
- test accommodation booking endpoint
- update search route

[Maintains #167727754]
  • Loading branch information
tobslob committed Sep 6, 2019
1 parent 3f4d5d5 commit 2492985
Show file tree
Hide file tree
Showing 11 changed files with 462 additions and 18 deletions.
44 changes: 41 additions & 3 deletions src/controllers/accommodationController.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import response from '../utils/response';
import messages from '../utils/messages';
import DbServices from '../services/dbServices';

const { Accommodation } = models;
const { create } = DbServices;
const { Accommodation, BookAccomodation } = models;
const { create, getById } = DbServices;
const { serverError } = messages;

/**
Expand Down Expand Up @@ -42,4 +42,42 @@ const createAccommodation = async (req, res) => {
}
};

export default createAccommodation;

/**
* user can book accomodation facility
* @param {Object} req - server request
* @param {Object} res - server response
* @returns {Object} - custom response
*/
const bookAccommodation = async (req, res) => {
try {
const { id: userId } = req.decoded;
const {
roomType, numOfRooms, checkIn, checkOut, adults, children
} = req.body;

const { accommodationId } = req.params;
const accommodation = await getById(Accommodation, accommodationId, {});
if (!accommodation) return response(res, 404, 'error', { message: messages.notExistAccommodation });

const bookingDetails = {
userId,
accommodationId,
roomType,
numOfRooms,
checkIn,
checkOut,
adults,
children
};
const bookedAccommodation = await create(BookAccomodation, bookingDetails);

return response(res, 201, 'success', bookedAccommodation);
} catch (error) {
return response(res, 500, 'error', {
message: serverError,
});
}
};

export { createAccommodation, bookAccommodation };
58 changes: 58 additions & 0 deletions src/database/migrations/20190905112508-create-book-accomodation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('BookAccomodations', {
id: {
allowNull: false,
primaryKey: true,
type: Sequelize.UUID
},
userId: {
type: Sequelize.UUID,
allowNull: false
},
accommodationId: {
type: Sequelize.UUID,
allowNull: false
},
roomType: {
type: Sequelize.ARRAY(Sequelize.STRING),
allowNull: false
},
checkIn: {
type: Sequelize.DATE,
allowNull: false
},
checkOut: {
type: Sequelize.DATE,
allowNull: false
},
numOfRooms: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 1
},
adults: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 1
},
children: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: 0
},
createdAt: {
allowNull: true,
type: Sequelize.DATE
},
updatedAt: {
allowNull: true,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('BookAccomodations');
}
};
1 change: 0 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import db from './models';
import { cloudinaryConfig } from './config/cloudinaryConfig';



// Instance of express app
const app = express();

Expand Down
56 changes: 56 additions & 0 deletions src/models/bookaccomodation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
module.exports = (sequelize, DataTypes) => {
const BookAccomodation = sequelize.define('BookAccomodation', {
id: {
allowNull: false,
primaryKey: true,
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
},
userId: {
type: DataTypes.UUID,
allowNull: false,
},
accommodationId: {
type: DataTypes.UUID,
allowNull: false
},
roomType: {
type: DataTypes.ARRAY(DataTypes.STRING),
allowNull: false
},
checkIn: {
type: DataTypes.DATE,
allowNull: false
},
checkOut: {
type: DataTypes.DATE,
allowNull: false
},
numOfRooms: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 1
},
adults: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 1
},
children: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: 0
}
}, {});
BookAccomodation.associate = (models) => {
BookAccomodation.belongsTo(models.User, {
foreignKey: 'userId',
as: 'User',
});
BookAccomodation.belongsTo(models.Accommodation, {
foreignKey: 'accommodationId',
as: 'Accommodation',
});
};
return BookAccomodation;
};
114 changes: 108 additions & 6 deletions src/routes/api/accommodation.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/* eslint-disable max-len */
import creatAccommodation from '../../controllers/accommodationController';
import { createAccommodation, bookAccommodation } from '../../controllers/accommodationController';
import { checkToken } from '../../middlewares/userMiddlewares';
import validate from '../../middlewares/validator';
import accommodationSchema from '../../validation/accommodationSchema';
import { accommodationSchema, bookAccommodationSchema } from '../../validation/accommodationSchema';

const accommodationRoute = (router) => {
router.route('/accommodation')
Expand Down Expand Up @@ -55,7 +54,7 @@ const accommodationRoute = (router) => {
* /api/v1/accommodation:
* post:
* tags:
* - Acommodation
* - Accommodation
* description: Travel admin can create accommodation
* produces:
* - application/json
Expand Down Expand Up @@ -93,7 +92,110 @@ const accommodationRoute = (router) => {
* security:
* - bearerAuth: []
*/
.post(checkToken, validate(accommodationSchema), creatAccommodation);
.post(checkToken, validate(accommodationSchema), createAccommodation);
};

export default accommodationRoute;

const bookAccommodationRoute = (router) => {
router.route('/book/accommodation/:accommodationId')
/**
* @swagger
* components:
* schemas:
* bookAccommodation:
* properties:
* id:
* type: string
* readOnly: true
* userId:
* type: string
* readOnly: true
* roomType:
* type: array
* items:
* type: string
* numOfRooms:
* type: integer
* checkIn:
* type: string
* format: date
* checkOut:
* type: string
* format: date
* adults:
* type: integer
* children:
* type: integer
* createdAt:
* type: string
* format: date-time
* readOnly: true
* updateAt:
* type: string
* format: date-time
* readOnly: true
* ErrorResponse:
* properties:
* status:
* type: string
* example: error
* data:
* type: string
*/

/**
* @swagger
* /api/v1/book/accommodation/{accommodationId}:
* post:
* tags:
* - Accommodation
* description: Users can book an accommodation
* parameters:
* - in: path
* name: accommodationId
* schema:
* type: string
* required: true
* produces:
* - application/json
* requestBody:
* description: Accommodation
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/bookAccommodation'
* responses:
* 201:
* description: Acommodation successfully booked
* content:
* application/json:
* schema:
* type: object
* properties:
* status:
* type: object
* data:
* $ref: '#/components/schemas/bookAccommodation'
* 400:
* description: Input validation error
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* 500:
* description: Internal Server error
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* security:
* - bearerAuth: []
*/
.post(checkToken, validate(bookAccommodationSchema), bookAccommodation);
};

export {
accommodationRoute,
bookAccommodationRoute
};
69 changes: 68 additions & 1 deletion src/routes/api/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,73 @@ const requestRoute = (router) => {
*/
.get(checkToken, validate(getUserRequestSchema), checkUserId, getUserRequest);

router.route('/requests/reject/:requestId')
/**
* @swagger
* components:
* schemas:
* acceptOrRejectTrip:
* properties:
* message:
* type: string
* readOnly: true
* ErrorResponse:
* properties:
* status:
* type: string
* example: error
* data:
* type: string
*/

/**
* @swagger
* /api/v1/requests/reject/{requestId}:
* patch:
* tags:
* - Requests
* description: Reject a request for a trip
* parameters:
* - in: path
* name: requestId
* schema:
* type: string
* required: true
* produces:
* - application/json
* responses:
* 201:
* description: Trip request successfully rejected
* content:
* application/json:
* schema:
* type: object
* properties:
* status:
* type: string
* example: success
* data:
* allOf:
* - $ref: '#/components/schemas/acceptOrRejectTrip'
* 400:
* description: Input validation error
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* 500:
* description: Internal Server error
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* security:
* - bearerAuth: []
*/
.patch(checkToken, validate(requestIdSchema), verifyRequestLineManager, updateApprovalStatus);
};

const searchRequestRoute = (router) => {
router.route('/search/requests')
/**
* @swagger
Expand Down Expand Up @@ -419,4 +486,4 @@ const requestRoute = (router) => {
.patch(checkToken, validate(requestIdSchema), verifyRequestLineManager, updateApprovalStatus);
};

export default requestRoute;
export { requestRoute, searchRequestRoute };
Loading

0 comments on commit 2492985

Please sign in to comment.