Skip to content

Commit

Permalink
ft(multi city trip request):
Browse files Browse the repository at this point in the history
create route for multi-city trip request
add validations
create a table model and trips
create routew for posting locations
[Finishes 169258638]
  • Loading branch information
hezzie committed Nov 21, 2019
1 parent 950dfd6 commit 52625ee
Show file tree
Hide file tree
Showing 39 changed files with 869 additions and 133 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
"build": "babel src -d dist ",
"eslint": "eslint --ignore-path .gitignore .",
"db-seed": "NODE_ENV=testing sequelize db:seed:all",
"test": "NODE_ENV=testing npm run dropTables && NODE_ENV=testing npm run db-migrate && npm run db-seed && NODE_ENV=testing nyc --reporter=text --reporter=html --require @babel/polyfill --require @babel/register mocha ./src/tests/* --timeout 200000 --exit",
"coverage": "nyc npm test && npm run coveralls-coverage",
"db-seed-dev": "npx sequelize-cli db:seed:undo:all && sequelize db:seed:all",
"dev-start": "nodemon --exec babel-node ./src/index.js",
"db-migrate": "sequelize db:migrate",
"dropTables": "sequelize db:migrate:undo:all"
"test": "NODE_ENV=testing npm run dropTables && NODE_ENV=testing npm run db-migrate && npm run db-seed && NODE_ENV=testing nyc --reporter=text --reporter=html --require @babel/polyfill --require @babel/register mocha ./src/tests/* --timeout 200000 --exit",
"db-migrate": "sequelize db:migrate && npx sequelize-cli db:seed:all",
"dropTables": "sequelize db:migrate:undo:all",
"coverage": "nyc report --reporter=text-lcov | coveralls"
},
"author": "Andela Simulations Programme",
"license": "MIT",
Expand Down
35 changes: 35 additions & 0 deletions src/controllers/LocationController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import dotenv from 'dotenv';
import Customize from '../helpers/Customize';
import { cities } from '../database/models';
import DataEngine from '../middlewares/DataEngine';

dotenv.config();
/**
* @export
* @class LocationController
*/
class LocationController {
/**
* An admin should be able to add locations
* @static
* @param {object} req request object
* @param {object} res response object
* @memberof LocationController
* @returns {object} data
*/
static async saveLocation(req, res) {
try {
const { name } = req.body;

const newLocation = await cities.create({
city: name
});


return Customize.successMessage(req, res, 'Location posted successfully', newLocation, 201);
} catch (err) {
return Customize.errorMessage(req, res, err.message, 500);
}
}
}
export default LocationController;
65 changes: 63 additions & 2 deletions src/controllers/TripController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import dotenv from 'dotenv';
import Customize from '../helpers/Customize';
import emailHelper from '../helpers/EmailHelper';
import { tripRequest, tripRequestCities } from '../database/models';
import DataEngine from '../middlewares/DataEngine';


dotenv.config();
/**
Expand All @@ -10,6 +13,7 @@ dotenv.config();
class TripController {
/**
* User can be able to request one-way trip
* User can be able to request multi-city trip
* @static
* @param {object} req request object
* @param {object} res response object
Expand All @@ -21,18 +25,75 @@ class TripController {
const userId = req.user.id;
const { reason, city, startDate } = req.body;
const newTrip = await tripRequest.create({
reason, tripTypeId: 1, userId, startDate
tripTypeId: 1, userId
});

const requestId = await tripRequest.findOne({ where: { userId } });
const cityId = parseInt(city, 10);
await tripRequestCities.create({
tripRequestId: requestId.dataValues.id, cityId
tripRequestId: requestId.dataValues.id, cityId, reason, startDate
});
return Customize.successMessage(req, res, 'Trip requested successfully', newTrip, 201);
} catch (err) {
return Customize.successMessage(req, res, 'Server error', err.message, 500);
}
}

/**
* User can be able to request one-way trip
* User can be able to request multi-city trip
* @static
* @param {object} req request object
* @param {object} res response object
* @memberof TripController
* @returns {object} data
*/
static async requestTrip(req, res) {
try {
const { itinerary } = req.body;
const userId = req.user.id;
const newTrip = await tripRequest.create({
userId, status: 'pending', tripTypeId: 1
});
const request = await tripRequest.findOne({ where: { userId } });
itinerary.forEach(async (item) => {
await tripRequestCities.create({
tripRequestId: request.dataValues.id,
cityId: item.city,
reason: item.reason,
startDate: item.startDate,
returnDate: item.returnDate
});
});


emailHelper.approveEmailHelper(req, process.env.MANAGER_EMAIL);
return Customize.successMessage(req, res, 'Trip requested successfully', newTrip, 201);
} catch (err) {
return Customize.errorMessage(req, res, err.message, 500);
}
}

/**
* Manager should be able to approve a trip
* @static
* @param {object} req request object
* @param {object} res response object
* @memberof UserController
* @returns {object} data
*/
static async approveTrip(req, res) {
try {
emailHelper.approvedEmailHelper(req.row);
await tripRequest.update({ status: 'approved' }, {
where: {
id: req.params.id
}
});
return Customize.successMessage(req, res, 'Your request has been approved', '', 201);
} catch (err) {
return Customize.errorMessage(req, res, err.message, 500);
}
}
}
export default TripController;
12 changes: 6 additions & 6 deletions src/controllers/UserController.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class UserController {
/**
* User can be able to sign up
* @static
* @param {object} req request object
* @param {object} req request object
* @param {object} res response object
* @memberof UserController
* @returns {object} data
Expand Down Expand Up @@ -77,12 +77,12 @@ class UserController {
* @returns {Object} response
*/
static async resendEmailController(req, res) {
const user = await users.findOne({ where: { id: req.params.id } });
if (!user) {
return Customize.errorMessage(req, res, 'Invalid ID', 400);
try {
emailHelper.verifyEmailHelper(req, req.row);
return Customize.successMessage(req, res, 'An email has been sent to you.', '', 200);
} catch (err) {
return Customize.errorMessage(req, res, err.message, 500);
}
emailHelper.verifyEmailHelper(req, user.dataValues);
return Customize.successMessage(req, res, 'An email has been sent to you.', '', 200);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports = {
type: Sequelize.STRING
},
isVerified: {
type: Sequelize.STRING
type: Sequelize.BOOLEAN
},
signupType: {
type: Sequelize.STRING
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = {
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
city: {
type: Sequelize.STRING
},
createdAt: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,21 @@ module.exports = {
},
userId: {
type: Sequelize.INTEGER,
references: {
model: 'users',
key: 'id'
references:{
model:'users',
key:'id'
}
},
reason: {
type: Sequelize.STRING
},
tripTypeId: {
type: Sequelize.INTEGER,
references: {
model: 'tripTypes',
key: 'id'
references:{
model:'tripTypes',
key:'id'
}
},
status: {
type: Sequelize.STRING,
defaultValue: 'pending'
},
startDate: {
type: Sequelize.STRING
},
returnDate: {
type: Sequelize.STRING
defaultValue: 'pending'
},
createdAt: {
allowNull: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,27 @@ module.exports = {
},
tripRequestId: {
type: Sequelize.INTEGER,
references: {
model: 'tripRequests',
key: 'id'
references:{
model:'tripRequests',
key:'id'
}
},
cityId: {
type: Sequelize.INTEGER,
references: {
model: 'cities',
key: 'id'
references:{
model:'cities',
key:'id'
}
},
reason: {
type: Sequelize.STRING
},
startDate: {
type: Sequelize.STRING
},
returnDate: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
Expand Down
2 changes: 1 addition & 1 deletion src/database/models/cities.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
module.exports = (sequelize, DataTypes) => {
const cities = sequelize.define('cities', {
name: DataTypes.STRING
city: DataTypes.STRING
}, {});
cities.associate = function(models) {
cities.hasMany(models.tripRequestCities, {foreignKey: 'id'});
Expand Down
15 changes: 15 additions & 0 deletions src/database/models/tripRequest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';
module.exports = (sequelize, DataTypes) => {
const tripRequest = sequelize.define('tripRequest', {
userId: DataTypes.INTEGER,
tripTypeId: DataTypes.INTEGER,
status: DataTypes.STRING,
}, {});
tripRequest.associate = function(models) {
// associations can be defined here
tripRequest.belongsTo(models.users, {foreignKey: 'userId'});
tripRequest.belongsTo(models.tripType, {foreignKey: 'tripTypeId'});
tripRequest.hasMany(models.tripRequestCities, {foreignKey: 'id'});
};
return tripRequest;
};
5 changes: 4 additions & 1 deletion src/database/models/tripRequestCities.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
module.exports = (sequelize, DataTypes) => {
const tripRequestCities = sequelize.define('tripRequestCities', {
tripRequestId: DataTypes.INTEGER,
cityId: DataTypes.INTEGER
cityId: DataTypes.INTEGER,
reason: DataTypes.STRING,
startDate: DataTypes.STRING,
returnDate: DataTypes.STRING
}, {});
tripRequestCities.associate = function(models) {
tripRequestCities.belongsTo(models.tripRequest, {foreignKey: 'tripRequestId'});
Expand Down
3 changes: 0 additions & 3 deletions src/database/models/tripRequests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
module.exports = (sequelize, DataTypes) => {
const tripRequest = sequelize.define('tripRequest', {
userId: DataTypes.INTEGER,
reason: DataTypes.INTEGER,
tripTypeId: DataTypes.INTEGER,
status: DataTypes.STRING,
startDate: DataTypes.DATE,
returnDate: DataTypes.STRING
}, {});
tripRequest.associate = function(models) {
tripRequest.belongsTo(models.users, {foreignKey: 'userId'});
Expand Down
2 changes: 1 addition & 1 deletion src/database/models/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module.exports = (sequelize, DataTypes) => {
lastName: DataTypes.STRING,
email: DataTypes.STRING,
password: DataTypes.STRING,
isVerified: DataTypes.STRING,
isVerified: DataTypes.BOOLEAN,
signupType: DataTypes.STRING
}, {});
users.associate = function(models) {
Expand Down
2 changes: 1 addition & 1 deletion src/database/seeders/20191115100759-locations-demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.bulkInsert('cities', [{
name: 'kigali',
city: 'kigali',
createdAt: new Date(),
updatedAt: new Date()
}], {});
Expand Down
23 changes: 23 additions & 0 deletions src/database/seeders/20191119051629-tripTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';

module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.bulkInsert('tripTypes', [{
tripType: 'one-way',
createdAt: new Date(),
updatedAt: new Date()
},{
tripType: 'return',
createdAt: new Date(),
updatedAt: new Date()
},{
tripType: 'multi-city',
createdAt: new Date(),
updatedAt: new Date()
}], {});
},

down: (queryInterface, Sequelize) => {
return queryInterface.bulkDelete('tripTypes', null, {});
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ module.exports = {
return queryInterface.bulkInsert('users', [{
firstName: 'John',
lastName: 'Doe',
email: 'demo@demo.com',
email: 'demo@gmail.com',
isVerified:false,
signupType:'Barefoot',
createdAt: new Date(),
updatedAt: new Date()
}], {});
Expand Down
Loading

0 comments on commit 52625ee

Please sign in to comment.