Skip to content

Commit

Permalink
ft(flight):user-flight-details
Browse files Browse the repository at this point in the history
  • Loading branch information
stepheng323 committed Sep 13, 2019
1 parent fca3377 commit 3ff4701
Show file tree
Hide file tree
Showing 19 changed files with 359 additions and 15 deletions.
22 changes: 22 additions & 0 deletions src/controllers/flightController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { postFlightDetails } from '../services/flightServices';
import statusCode from '../helpers/statusCode';
import { respondWithSuccess, respondWithWarning } from '../helpers/responseHandler';

export const addFlightDetails = async (req, res) => {
const {
departureDate, userId, returnDate, origin, destinationId
} = req.trip;
if (!returnDate) {
if (!req.body.returnDate) { return respondWithWarning(res, statusCode.badRequest, 'return date is required'); }
const data = {
...req.body, departureDate, userId, origin, destinationId
};

try {
const flightDetails = await postFlightDetails(data);
return respondWithSuccess(res, statusCode.created, 'flight details created successful', flightDetails.dataValues);
} catch (error) {
return respondWithWarning(res, statusCode.internalServerError, 'internal server error', error);
}
}
};
5 changes: 1 addition & 4 deletions src/controllers/tripController.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,7 @@ export const returnTripRequest = async (req, res) => {
return respondWithWarning(res, statusCode.badRequest, 'return date cannot be before departure date');
}
const data = {
...req.body,
status: 'pending',
type: 'return',
userId: id
...req.body, status: 'pending', type: 'return', userId: id
};
try {
const returnTrip = await postTrip(data);
Expand Down
4 changes: 2 additions & 2 deletions src/database/migrations/20190829084157-create-trip-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export default {
allowNull: false,
},
departureDate: {
type: Sequelize.STRING,
type: Sequelize.DATE,
allowNull: false,
},
returnDate: {
type: Sequelize.STRING
type: Sequelize.DATE
},
type: {
type: Sequelize.STRING,
Expand Down
48 changes: 48 additions & 0 deletions src/database/migrations/20190910230142-create-flight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
export default {
up: (queryInterface, Sequelize) => queryInterface.createTable('Flights', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
departureDate: {
type: Sequelize.DATE,
allowNull: false
},
userId: {
type: Sequelize.INTEGER,
allowNull: false
},
returnDate: {
type: Sequelize.DATE
},
airline: {
type: Sequelize.STRING,
allowNull: false
},
ticketNumber: {
type: Sequelize.STRING,
allowNull: false
},
origin: {
type: Sequelize.STRING,
allowNull: false
},
destinationId: {
type: Sequelize.STRING,
allowNull: false
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: new Date()
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: new Date()
}
}),
down: (queryInterface, Sequelize) => queryInterface.dropTable('Flights')
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default {
origin: 'Lagos',
destinationId: 2,
reason: 'Trade Fair',
departureDate: '2019-19-09T00:09:31.812Z',
departureDate: '9/9/2019',
type: 'one-way',
userId: 3,
status: 'pending'
Expand All @@ -15,7 +15,7 @@ export default {
destinationId: 1,
reason: 'Vacation with my family',
type: 'multi-city',
departureDate: '2019-19-09T00:09:31.812Z',
departureDate: '9/9/2019',
status: 'approved',
userId: 2
},
Expand All @@ -24,7 +24,7 @@ export default {
destinationId: 5,
reason: 'Vacation with my family',
type: 'one-way',
departureDate: '2019-19-09T00:09:31.812Z',
departureDate: '9/9/2019',
status: 'pending',
userId: 2
},
Expand Down
21 changes: 21 additions & 0 deletions src/docs/swagger/definitions/flight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export const FlightCreate = {
type: 'object',
properties: {
airline: {
type: 'string',
example: 'British Airways'
},
ticketNumber: {
type: 'string',
example: 'BRAW16829033',
},
departureDate: {
type: 'date',
example: '08-08-2019',
},
returnDate: {
type: 'date',
example: '09-09-2019',
},
}
};
8 changes: 8 additions & 0 deletions src/docs/swagger/paths/Untitled-1
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#### What this PR Does
This PR creates an endpoint for user to add their travel flight ticket

#### how it works
- clone this repo and cd into the folder
- run `npm install` in the terminal to install all packages
- run
#### Relevant Pivotal Tracker
63 changes: 63 additions & 0 deletions src/docs/swagger/paths/flight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
export const flightPath = {
post: {
tags: [
'flights'
],
security: [
{
BearerToken: []
}
],
summary: 'User can enter flight details',
description: 'user can enter flight details after trip request has been approved ',
parameters: [
{
name: 'tripId',
in: 'path',
description: 'tripId',
required: true,
},
{
name: 'body',
in: 'body',
description: 'Flight details object',
required: true,
schema: {
$ref: '#/definitions/FlightCreate'
}
}
],
responses: {
201: {
description: 'request successfully sent',
schema: {
$ref: '#/definitions/created'
}
},
400: {
description: 'Invalid request details',
schema: {
$ref: '#/definitions/badRequest'
}
},
401: {
description: 'Unauthorized',
schema: {
$ref: '#/definitions/notAuthorized'
}
},
422: {
description: 'Unprocessable entity',
schema: {
$ref: '#/definitions/accessForbidden'
}
},
500: {
description: 'Server error',
schema: {
$ref: '#/definitions/serverError'
}
}
}
}
};
11 changes: 9 additions & 2 deletions src/docs/swagger/swagger.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ import { createComment } from './definitions/createComment';
import { createCommentPath, deleteCommentPath, getTripCommentsPath } from './paths/commentPath';
import { postChatPath, getChatsPath } from './paths/chat';
import { createChat } from './definitions/chat';
import { flightPath } from './paths/flight';
import { FlightCreate } from './definitions/flight';

const swaggerDocument = {
swagger: '2.0',
Expand Down Expand Up @@ -107,7 +109,10 @@ const swaggerDocument = {
{
name: 'chats',
description: 'Chat related endpoints'
}
}, {
name: 'flights',
description: 'Flight related endpoints'
},
],
paths: {
'/auth/signin': signInPath,
Expand Down Expand Up @@ -146,6 +151,7 @@ const swaggerDocument = {
'/bookings/{bookingId}': getSingleBookingPath,
'/chat': postChatPath,
'/chats/?sender={sender}&recipient={recipient}': getChatsPath,
'/flights/add/{tripId}': flightPath
},
definitions: {
createMultiCityTrip,
Expand Down Expand Up @@ -196,7 +202,8 @@ const swaggerDocument = {
createChat,
checkAccommodationLikeRes,
likeUnlikeAccommodationRes,
createReview
createReview,
FlightCreate,
}
};

Expand Down
25 changes: 25 additions & 0 deletions src/middlewares/flightMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import BaseJoi from '@hapi/joi';
import Extension from '@hapi/joi-date';
import statusCode from '../helpers/statusCode';
import { respondWithWarning } from '../helpers/responseHandler';
import { joiValidator } from '../helpers/joiValidator';

const Joi = BaseJoi.extend(Extension);

export const flightValidator = (req, res, next) => {
const flightSchema = {
airline: Joi.string().required(),
ticketNumber: Joi.string().required(),
returnDate: Joi.date().format('DD-MM-YYYY')
};
const errors = joiValidator(req.body, flightSchema);
if (!errors) return next();
return respondWithWarning(res, statusCode.badRequest, 'Bad request', errors);
};


export const checkTripStatus = async (req, res, next) => {
const { status } = req.trip;
if (status === 'approved') { return next(); }
return respondWithWarning(res, statusCode.unprocessableEntity, 'Not allowed');
};
2 changes: 1 addition & 1 deletion src/middlewares/validateTripRequest.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

import BaseJoi from '@hapi/joi';
import Extension from '@hapi/joi-date';
import { joiValidator } from '../helpers/joiValidator';
Expand Down Expand Up @@ -91,7 +92,6 @@ export const validateDeleteParams = (req, res, next) => {
}
return respondWithWarning(res, statusCode.badRequest, resMessage.badInputRequest, errors);
};
export default validateRequestTripForm;

/**
* function to validate return trip request form
Expand Down
1 change: 1 addition & 0 deletions src/models/destination.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default (sequelize, DataTypes) => {
Destination.associate = (models) => {
Destination.hasMany(models.TripRequest, { foreignKey: 'destinationId', as: 'tripRequests', timestamps: false });
Destination.hasMany(models.SubTripRequest, { foreignKey: 'subDestinationId', as: 'subTripRequests', timestamps: false });
Destination.hasMany(models.Flight, { foreignKey: 'destinationId', timestamps: false });
};
return Destination;
};
37 changes: 37 additions & 0 deletions src/models/flight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

export default (sequelize, DataTypes) => {
const Flight = sequelize.define('Flight', {
userId: {
type: DataTypes.INTEGER,
allowNull: false
},
departureDate: {
type: DataTypes.DATE,
allowNull: false
},
returnDate: {
type: DataTypes.DATE
},
origin: {
type: DataTypes.STRING,
allowNull: false
},
destinationId: {
type: DataTypes.STRING,
allowNull: false
},
airline: {
type: DataTypes.STRING,
allowNull: false
},
ticketNumber: {
type: DataTypes.STRING,
allowNull: false
},
}, {});
Flight.associate = (models) => {
Flight.hasMany(models.TripRequest, { foreignKey: 'returnDate' });
Flight.hasMany(models.TripRequest, { foreignKey: 'departureDate' });
};
return Flight;
};
8 changes: 5 additions & 3 deletions src/models/triprequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ export default (sequelize, DataTypes) => {
allowNull: false,
},
departureDate: {
type: DataTypes.STRING,
type: DataTypes.DATE,
allowNull: false,
},
returnDate: {
type: DataTypes.STRING
type: DataTypes.DATE
},
userId: {
type: DataTypes.INTEGER,
allowNull: false,
allowNull: false
}
}, {});
TripRequest.associate = models => {
Expand All @@ -41,6 +41,8 @@ export default (sequelize, DataTypes) => {
as: 'subTrips',
timestamps: false
});
TripRequest.belongsTo(models.Flight, { foreignKey: 'returnDate', onDelete: 'CASCADE' });
TripRequest.belongsTo(models.Flight, { foreignKey: 'departureDate', onDelete: 'CASCADE' });
};
return TripRequest;
};
1 change: 1 addition & 0 deletions src/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export default (sequelize, DataTypes) => {
User.hasMany(models.Comment, { foreignKey: 'userId', onDelete: 'CASCADE' });
User.hasMany(models.Like, { foreignKey: 'userId', as: 'accommodationLikes', onDelete: 'CASCADE' });
User.hasMany(models.AccommodationReview, { foreignKey: 'userId', onDelete: 'CASCADE' });
User.hasMany(models.Flight, { foreignKey: 'userId', onDelete: 'CASCADE' });
};
User.beforeCreate(async (user) => {
const error = new Error();
Expand Down
13 changes: 13 additions & 0 deletions src/routes/api/flight.routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Router } from 'express';
import { addFlightDetails } from '../../controllers/flightController';
import { authenticateUserToken } from '../../middlewares/authentication';
import { validateTripId } from '../../middlewares/validateTripRequest';
import { verifyTrip } from '../../middlewares/tripMiddleware';
import { flightValidator, checkTripStatus } from '../../middlewares/flightMiddleware';


const flight = Router();

flight.post('/add/:tripId', authenticateUserToken, validateTripId, flightValidator, verifyTrip, checkTripStatus, addFlightDetails);

export default flight;
Loading

0 comments on commit 3ff4701

Please sign in to comment.