Skip to content

Commit

Permalink
feat(requests): avail requests for approval- add controller to get re…
Browse files Browse the repository at this point in the history
…quests assigned to a manager- add route/endpoint to get requests assigned to a manager[Finishes (#167727739)]
  • Loading branch information
Mcdavid95 committed Sep 5, 2019
1 parent 23e2622 commit 6c71de3
Show file tree
Hide file tree
Showing 19 changed files with 314 additions and 83 deletions.
50 changes: 41 additions & 9 deletions src/controllers/requestController.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import models from '../models';
import response from '../utils/response';
import roles from '../utils/roles';
import DbServices from '../services/dbServices';
import { calculateLimitAndOffset, paginate } from '../utils/pagination';
import findRequest from '../services/requestServices';
import messages from '../utils/messages';
import { findById } from '../services/userServices';
import { createNotification } from '../services/notificationServices';

const { Request, Subrequest } = models;
const { Request, Subrequest, User } = models;
const {
serverError, unauthorizedUserRequest, noRequests, rejectedTripRequest
} = messages;
Expand Down Expand Up @@ -81,21 +82,19 @@ const requestTrip = async (req, res) => {
};

/**
* request trip controller
* @function getUserRequest
* @param {Object} req - server request
* @param {Object} res - server response
* @returns {Object} - custom response
*/
const getUserRequest = async (req, res) => {
try {
const { params, decoded, query } = req;
const { userId } = params;
if (userId !== decoded.id) {
const { decoded: { id, roleId }, query: { page, perPage, userId } } = req;
if (userId && (userId !== id && roleId !== roles.SUPER_ADMIN)) {
return response(res, 403, 'error', { message: unauthorizedUserRequest });
}
const { page, perPage } = query;
const { limit, offset } = calculateLimitAndOffset(page, perPage);
const options = { where: { userId }, limit, offset };
const options = { where: { userId: userId || id }, limit, offset };
const { rows, count } = await getAll(Request, options);
if (rows.length === 0) return response(res, 200, 'success', { message: noRequests });
const meta = paginate(page, perPage, count, rows);
Expand All @@ -122,6 +121,38 @@ const searchRequest = async (req, res) => {
return response(res, 400, 'error', { message: messages.error });
}
};
/**
* @function getManagerRequest
* @param {Object} req - server request
* @param {Object} res - server response
* @returns {Object} - custom response
*/
const getManagerRequest = async (req, res) => {
try {
const { decoded: { id, roleId }, query: { page, perPage, userId } } = req;
if (userId && (userId !== id && roleId !== roles.SUPER_ADMIN)) {
return response(res, 403, 'error', { message: unauthorizedUserRequest });
}
const { limit, offset } = calculateLimitAndOffset(page, perPage);
const options = {
where: { approvalStatus: 'rejected' },
include: [{
model: User,
as: 'User',
where: { lineManager: userId || id },
attributes: ['id', 'lineManager'],
}],
limit,
offset
};
const { rows, count } = await getAll(Request, options);
if (rows.length === 0) return response(res, 200, 'success', { message: noRequests });
const meta = paginate(page, perPage, count, rows);
return response(res, 200, 'success', { requests: rows, meta });
} catch (error) {
return response(res, 500, 'error', serverError);
}
};

/**
* reject request controller
Expand All @@ -146,7 +177,7 @@ const updateApprovalStatus = async (req, res) => {
});
} catch (error) {
return response(res, 500, 'error', {
message: serverError,
message: error,
});
}
};
Expand All @@ -155,5 +186,6 @@ export default {
requestTrip,
getUserRequest,
searchRequest,
updateApprovalStatus
updateApprovalStatus,
getManagerRequest
};
20 changes: 11 additions & 9 deletions src/controllers/userController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Op } from 'sequelize';
import models from '../models';
import authHelper from '../utils/authHelper';
import roles from '../utils/roles';
import response from '../utils/response';
import messages from '../utils/messages';
import {
Expand All @@ -16,7 +17,7 @@ import redis from '../config/redis';
const { User, Role } = models;
const { getById, update, getByOptions } = DbServices;
const {
unauthorizedUserProfile, serverError, phoneExists, roleChanged,
unauthorizedUserProfile, serverError, phoneExists, roleChanged, unauthorizedUserRequest
} = messages;
const { FRONTEND_BASE_URL } = process.env;

Expand Down Expand Up @@ -47,7 +48,7 @@ const signUp = async (req, res) => {
user: {
id: createdUser.id,
email: createdUser.email,
token: authHelper.generateToken({ id: createdUser.id }),
token: authHelper.generateToken({ id: createdUser.id, roleId: createdUser.roleId }),
}
};
const link = `${process.env.BACKEND_BASE_URL}/api/v1/user/verify/${userData.user.token}`;
Expand All @@ -73,11 +74,8 @@ const signIn = async (req, res) => {
const { password: hash, ...data } = user.dataValues;
const passwordsMatch = await comparePasswords(password, hash);
if (!passwordsMatch) return response(res, 400, 'error', { message: messages.incorrectPassword });
const token = authHelper.generateToken({ id: data.id });
return response(res, 200, 'success', {
...data,
token
});
const token = authHelper.generateToken({ id: data.id, roleId: data.roleId });
return response(res, 200, 'success', { ...data, token });
} catch (error) {
response(res, 500, 'error', { error: error.message });
}
Expand Down Expand Up @@ -112,9 +110,13 @@ const logout = async (req, res) => {
*/
const getUserDetailsById = async (req, res) => {
try {
const { userId } = req.params;
const { MANAGER, SUPER_ADMIN } = roles;
const { query: { userId }, decoded: { id, roleId } } = req;
if (userId && (userId !== id && ![MANAGER, SUPER_ADMIN].includes(roleId))) {
return response(res, 403, 'error', { message: unauthorizedUserRequest });
}
const options = { attributes: { exclude: ['password'] } };
const user = await getById(User, userId, options);
const user = await getById(User, userId || id, options);
return response(res, 200, 'success', { user });
} catch (error) {
return response(res, 500, 'error', { message: serverError });
Expand Down
16 changes: 14 additions & 2 deletions src/database/seeders/20190819153902-user.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default {
phoneNo: '2347032123304',
password: hashPassword('jammy11167'),
verified: true,
roleId: roles.SUPER_ADMIN,
roleId: roles.SUPER_ADMIN
},
{
id: 'fb94de4d-47ff-4079-89e8-b0186c0a3be8',
Expand All @@ -32,6 +32,7 @@ export default {
phoneNo: null,
verified: false,
roleId: roles.MANAGER,
lineManager: '0ce36391-2c08-4703-bddb-a4ea8cccbbc5'
}, {
id: '0ce36391-2c08-4703-bddb-a4ea8cccbbc5',
firstName: 'Police',
Expand All @@ -40,7 +41,7 @@ export default {
password: hashPassword('polly11167'),
phoneNo: '2347032123404',
verified: true,
roleId: roles.REQUESTER,
roleId: roles.MANAGER,
}, {
id: '83b2a3e7-9ba4-4d3f-b3a3-d31940ee2edc',
firstName: 'Mr',
Expand All @@ -60,7 +61,18 @@ export default {
password: hashPassword('requestman'),
phoneNo: '2347032746854',
lineManager: '38eb202c-3f67-4eed-b7ac-9c31bc226e0c',
roleId: roles.REQUESTER,
verified: true
}, {
id: '3e747d71-4fa1-4934-af9d-13926eb2d063',
firstName: 'Mrs',
lastName: 'Somebody',
email: 'freewoman@gmail.com',
password: hashPassword('polly123456'),
phoneNo: '2347032123509',
verified: true,
lineManager: '0ce36391-2c08-4703-bddb-a4ea8cccbbc5',
roleId: roles.REQUESTER,
}
], {});
},
Expand Down
27 changes: 25 additions & 2 deletions src/database/seeders/20190826210429-demo-requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default {
type: 'return',
originCity: 'Lagos',
destinationCity: 'Istanbul',
userId: '122a0d86-8b78-4bb8-b28f-8e5f7811c456',
userId: '3e747d71-4fa1-4934-af9d-13926eb2d063',
departureDate: '01-07-2017',
returnDate: '02-08-2017',
reason: 'Check stocks',
Expand Down Expand Up @@ -39,14 +39,37 @@ export default {
},
{
id: 'b2092fb0-502a-4105-961f-2d310d340168',
userId: '2999c776-0f6f-471d-bced-b661d6e75586',
type: 'return',
originCity: 'lagos',
destinationCity: 'bahamas',
departureDate: '2019-09-21 17:59:04.305+00',
returnDate: '2020-08-21 17:59:04.305+00',
reason: 'vacation',
accommodation: 'Hotel Transylvania',
userId: '3e747d71-4fa1-4934-af9d-13926eb2d063',
approvalStatus: 'accepted'
}, {
id: 'd2b80fd4-e9f2-4c2d-b56c-fabc41821f7d',
type: 'return',
originCity: 'Abuja',
destinationCity: 'Lagos',
departureDate: '01-07-2018',
userId: '83b2a3e7-9ba4-4d3f-b3a3-d31940ee2edc',
returnDate: '02-08-2018',
reason: 'Annual meeting',
accommodation: 'Eko Hotels & Suites',
approvalStatus: 'accepted'
}, {
id: '3e747d71-4fa1-4934-af9d-13926eb2d063',
type: 'return',
originCity: 'Abuja',
destinationCity: 'Lagos',
departureDate: '01-07-2018',
userId: 'fb94de4d-47ff-4079-89e8-b0186c0a3be8',
returnDate: '02-08-2018',
reason: 'Annual meeting',
accommodation: 'Eko Hotels & Suites',
approvalStatus: 'rejected'
}
], {});
},
Expand Down
13 changes: 4 additions & 9 deletions src/middlewares/authorizer.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import DbServices from '../services/dbServices';
import models from '../models';
import response from '../utils/response';
import messages from '../utils/messages';
import roles from '../utils/roles';

const { getById } = DbServices;
const { User } = models;
const { serverError, forbidden } = messages;

/**
Expand All @@ -16,14 +12,13 @@ const { serverError, forbidden } = messages;
*/
const authorize = (permitedRoles) => async (req, res, next) => {
try {
const { id: userId } = req.decoded;
const { roleId } = await getById(User, userId, { attributes: ['roleId'] });
const { roleId } = req.decoded;

if (!permitedRoles.includes(roleId) || roleId !== roles.SUPER_ADMIN) {
return response(res, 403, 'error', { message: forbidden });
if (permitedRoles.includes(roleId) || roleId === roles.SUPER_ADMIN) {
return next();
}

return next();
return response(res, 403, 'error', { message: forbidden });
} catch (error) {
return response(res, 500, 'error', { message: serverError });
}
Expand Down
26 changes: 25 additions & 1 deletion src/middlewares/requestMiddlewares.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import DbServices from '../services/dbServices';
import models from '../models';

const { User, Request } = models;
const { findOneIncludeModel } = DbServices;
const { findOneIncludeModel, getById } = DbServices;

const verifyRequestLineManager = async (req, res, next) => {
try {
Expand Down Expand Up @@ -32,4 +32,28 @@ const verifyRequestLineManager = async (req, res, next) => {
}
};

/**
* @method checkUserId
* @param {object} req request object
* @param {object} res request object
* @param {function} next next function
* @returns {object} custom response
* @description checks if userId passed to params is valid
*/
export const checkRequestId = async (req, res, next) => {
try {
const { requestId } = req.params;
if (requestId) {
const request = await getById(Request, requestId, {});
if (!request) {
return response(res, 404, 'error', { message: messages.requestNotFoundId });
}
return next();
}
return next();
} catch (error) {
return response(res, 500, 'error', { message: messages.serverError });
}
};

export default verifyRequestLineManager;
11 changes: 7 additions & 4 deletions src/middlewares/userMiddlewares.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@ const {
*/
export const checkUserId = async (req, res, next) => {
try {
const { userId } = req.params;
const user = await getById(User, userId, {});
if (!user) {
return response(res, 404, 'error', { message: userNotFoundId });
const userId = req.params.userId || req.query.userId;
if (userId) {
const user = await getById(User, userId, {});
if (!user) {
return response(res, 404, 'error', { message: userNotFoundId });
}
return next();
}
return next();
} catch (error) {
Expand Down
Loading

0 comments on commit 6c71de3

Please sign in to comment.