Skip to content

Commit

Permalink
chore(refactor-order-flag):refactor order and flag controllers functi…
Browse files Browse the repository at this point in the history
…ons to enhance modularity

- refactor order and flag controllers functions to enhance modularity and make the codes neater
- integrate the queryText, validators and sendEmails into the controllers files

[Finishes #167434946]
  • Loading branch information
chuksjoe committed Jul 23, 2019
1 parent ef6c567 commit c64377e
Show file tree
Hide file tree
Showing 12 changed files with 322 additions and 304 deletions.
16 changes: 9 additions & 7 deletions api/v1/controllers/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default {

const { rows } = await db.query(queryText.createUser, values);
const token = utils.encodeToken(rows[0].email, rows[0].id, rows[0].is_admin);
const data = rows[0];
const [data] = rows;

delete data.password;
data.token = token;
Expand Down Expand Up @@ -71,7 +71,7 @@ export default {
validator.validateResourceId(user_id, 'User');
const { rows } = await db.query(queryText.getUserById, [user_id]);
validator.validateResource(rows[0], 'User');
const data = rows[0];
const [data] = rows;
delete data.password;
res.status(200).send({ status: 200, data });
} catch (err) {
Expand Down Expand Up @@ -110,16 +110,17 @@ export default {
validator.validateOwnerOrAdmin(req.token.isAdmin || req.token.email === email);
validator.validatePhoneNo(req.body.phone);
response = await db.query(queryText.getUserByEmail, [email]);
validator.validateResource(response.rows[0], 'User');
const [user] = response.rows;
validator.validateResource(user, 'User');
const {
street, city, state, country, phone, zip, is_admin,
} = response.rows[0];
} = user;
const values = [req.body.street || street, req.body.city || city, req.body.state || state,
req.body.country || country, req.body.phone || phone, req.body.zip || zip,
req.body.is_admin || is_admin, moment(), email];

response = await db.query(queryText.updateUserInfo, values);
const data = response.rows[0];
const [data] = response.rows;
delete data.password;
res.status(200).send({ status: 200, data });
} catch (err) {
Expand All @@ -132,8 +133,9 @@ export default {
const { email } = req.params;
validator.validateOwnerOrAdmin(req.token.isAdmin || req.token.email === email);
const { rows } = await db.query(queryText.getUserByEmail, [email]);
validator.validateResource(rows[0], 'User');
const { first_name, last_name } = rows[0];
const [user] = rows;
validator.validateResource(user, 'User');
const { first_name, last_name } = user;
await db.query(queryText.deleteUser, [email]);
res.status(200).json({
status: 200,
Expand Down
17 changes: 10 additions & 7 deletions api/v1/controllers/cars.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default {
.catch((err) => {
if (err) {
debug(err);
return res.status(599).send({ status: 599, error: 'Seems like your network connection is down.' });
return res.status(501).send({ status: 501, error: 'Seems like your network connection is down.' });
}
return 0;
});
Expand Down Expand Up @@ -138,8 +138,9 @@ export default {
const { car_id } = req.params;
validator.validateResourceId(car_id, 'Car');
const { rows } = await db.query(queryText.getCar, [car_id]);
validator.validateResource(rows[0], 'Car');
res.status(200).send({ status: 200, data: rows[0] });
const [car] = rows;
validator.validateResource(car, 'Car');
res.status(200).send({ status: 200, data: car });
} catch (err) {
res.status(err.statusCode || 500)
.send({ status: err.statusCode, error: err.message });
Expand Down Expand Up @@ -175,8 +176,9 @@ export default {
const { price } = req.body;
validator.validatePrice(price);
const { rows } = await db.query(queryText.getCar, [car_id]);
validator.validateResource(rows[0], 'Car');
validator.validateOwner(req.token.id === rows[0].owner_id);
const [car] = rows;
validator.validateResource(car, 'Car');
validator.validateOwner(req.token.id === car.owner_id);
const values = [parseFloat(price), moment(), car_id];
const response = await db.query(queryText.updateCarPrice, values);
const [data] = response.rows;
Expand All @@ -193,8 +195,9 @@ export default {
validator.validateResourceId(car_id, 'Car');
const { id, isAdmin } = req.token;
const { rows } = await db.query(queryText.getCar, [car_id]);
validator.validateResource(rows[0], 'Car');
const { owner_id, name, image_url } = rows[0];
const [car] = rows;
validator.validateResource(car, 'Car');
const { owner_id, name, image_url } = car;
validator.validateOwnerOrAdmin(id === owner_id || isAdmin);

await db.query(queryText.deleteCar, [car_id]); // delete the car ad from database
Expand Down
142 changes: 44 additions & 98 deletions api/v1/controllers/flags.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,36 @@
import moment from 'moment';

import db from '../db/index';
import ApiError from '../helpers/ApiError';
import utils from '../helpers/utils';
import validator from '../helpers/validators';
import sendEmails from '../helpers/sendEmails';
import db from '../db/index';
import queryText from '../db/queryText';


export default {
// create new purchase order by valid user
async createNewFlag(req, res) {
const queryText1 = 'SELECT * FROM cars WHERE id = $1';
const queryText2 = 'SELECT id, first_name, last_name FROM users WHERE id = $1';
const queryText3 = 'SELECT * FROM flags WHERE car_id = $1 AND reporter_id = $2 AND status = $3';
const queryText4 = `INSERT INTO
flags (car_id, car_name, owner_id, owner, owner_email,
reporter_id, reason, description, status, created_on)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *`;
try {
if (req.body.car_id === undefined || req.body.car_id === '') {
throw new ApiError(206, 'The car ID is required');
}
const { reason, description } = req.body;
if (reason === '' || description === '' || reason === undefined || description === undefined) {
throw new ApiError(206, 'Reason and Description cannot be null.');
}
let response = await db.query(queryText1, [req.body.car_id]);
const car = response.rows[0];
if (!car) {
throw new ApiError(404, 'Car does not exist!');
}
response = await db.query(queryText2, [req.token.id]);
const reporter = response.rows[0];
if (!reporter || car.status === 'Sold') {
throw new ApiError(401, 'Unauthorized Access!');
}
const { rows } = await db.query(queryText3, [car.id, reporter.id, 'Pending']);
if (rows[0]) {
throw new ApiError(400, 'You have a Pending flag on this car Ad.');
}
if (reporter.id === car.owner_id) {
throw new ApiError(400, 'You can\'t place a flag on your car ad.');
}
const { reason, description, car_id } = req.body;
validator.validateResourceId(car_id, 'Car');
let response = await db.query(queryText.getCar, [car_id]);
const [car] = response.rows;
validator.validateResource(car, 'Car');
validator.validateCarStatus(car.status === 'Sold');

response = await db.query(queryText.getUserById, [req.token.id]);
const [reporter] = response.rows;
validator.validateResource(reporter, 'User');
validator.validateOwnership(reporter.id === car.owner_id, 'flag');

const { rows } = await db.query(queryText.getPendingFlag, [car.id, reporter.id, 'Pending']);
validator.validateStatus(rows[0], 'flag');
const values = [car.id, car.name, car.owner_id, car.owner, car.email, reporter.id,
reason, description, 'Pending', moment()];

const data = await db.query(queryText4, values);
const mailOption = {
from: '"AutoMart Help" <[email protected]>',
to: car.email,
subject: `AutoMart - Your AD (${car.name}) has been flagged`,
html: `<h3>Your AD (${car.name}) has been flagged</h3>
<p>Hi ${car.owner},</p>
<p>your car ad posted on ${car.created_on} has been flagged for reason bothering on ${reason}.</p>
<p>Details of the flag is as follow:</p><hr>
<h4>Reason: ${reason}</h4>
<p>Description:</br>
${description}</p><hr><hr>
<p>Kindly review the affected ad and address the issue, then notify us to mark the report as addressed.</p>`,
};
utils.sendMail(mailOption);
const data = await db.query(queryText.createFlag, values);
sendEmails.sendFlagMessage({ car, reason, description });

res.status(201).send({
status: 201,
data: data.rows[0],
Expand All @@ -69,20 +43,16 @@ export default {
},
// return the list of flags if the user is the car owner or an admin.
async getAllFlags(req, res) {
const queryText1 = 'SELECT name, owner_id FROM cars WHERE id = $1';
const queryText2 = 'SELECT * FROM flags WHERE car_id = $1 ORDER BY created_on DESC';
try {
const { id, isAdmin } = req.token;
const { car_id } = req.params;
const response = await db.query(queryText1, [car_id]);
const car = response.rows[0];
if (!car) {
throw new ApiError(404, 'Car does not exist!');
}
if (car.owner_id !== id && !isAdmin) {
throw new ApiError(401, 'Unauthorized Access!');
}
const { rows } = await db.query(queryText2, [car_id]);
validator.validateResourceId(car_id, 'Car');
const response = await db.query(queryText.getCar, [car_id]);
const [car] = response.rows;
validator.validateResource(car, 'Car');
validator.validateOwnerOrAdmin(car.owner_id === id || isAdmin);

const { rows } = await db.query(queryText.getAllFlags, [car_id]);
res.status(200).send({ status: 200, data: rows });
} catch (err) {
res.status(err.statusCode || 500)
Expand All @@ -91,39 +61,21 @@ export default {
},
// accept a purchase order as a seller
async addressFlag(req, res) {
const queryText1 = 'SELECT status, owner, car_name, reason, description owner_email FROM flags WHERE id = $1';
const queryText2 = 'UPDATE flags SET status = $1, last_modified = $2 WHERE id = $3 RETURNING *';
try {
const { flag_id } = req.params;
const response = await db.query(queryText1, [flag_id]);
let flag = response.rows[0];
if (!req.token.isAdmin) {
throw new ApiError(401, 'Unauthorized Access!');
}
if (!flag) {
throw new ApiError(404, 'Flag not found in database.');
}
const response = await db.query(queryText.getFlag, [flag_id]);
let [flag] = response.rows;
validator.validateResource(flag, 'Flag');
if (flag.status !== 'Pending') {
throw new ApiError(400, 'This Flag has been Addressed before.');
}
const { rows } = await db.query(queryText2, ['Addressed', moment(), flag_id]);
const { rows } = await db.query(queryText.updateFlagStatus, ['Addressed', moment(), flag_id]);
[flag] = rows;
const {
car_name, owner_email, owner, reason, description,
car_name, owner, reason, description,
} = flag;
const mailOption = {
from: '"AutoMart Help" <[email protected]>',
to: owner_email,
subject: `AutoMart - Flag on ${car_name} has been Addressed`,
html: `<h3>Flag on ${car_name} has been Addressed</h3>
<p>Hi ${owner},</p>
<p>be notified that the flag placed on your above named car ad on AutoMart has been addressed.</p>
<p>Details of the flag is as follow:</p><hr>
<h4>Reason: ${reason}</h4>
<p>Description:</br>
${description}</p><hr><hr>`,
};
utils.sendMail(mailOption);
sendEmails.sendAddressedFlagMessage({ flag, reason, description });

res.status(200).send({
status: 200,
data: rows[0],
Expand All @@ -135,21 +87,15 @@ export default {
}
},
// cancel/delete a flag
async deleteOrder(req, res) {
const queryText1 = 'SELECT car_name, owner FROM flags WHERE id = $1';
const queryText2 = 'DELETE FROM flags WHERE id = $1';
const { flag_id } = req.params;
const { isAdmin } = req.token;
async deleteFlag(req, res) {
try {
if (!isAdmin) {
throw new ApiError(401, 'Unauthorized Access!');
}
const { rows } = await db.query(queryText1, [flag_id]);
if (!rows[0]) {
throw new ApiError(404, 'Flag not found in database.');
}
const { car_name, owner } = rows[0];
await db.query(queryText2, [flag_id]);
const { flag_id } = req.params;
validator.validateResourceId(flag_id, 'Flag');
const { rows } = await db.query(queryText.getFlag, [flag_id]);
const [flag] = rows;
validator.validateResource(flag, 'Flag');
const { car_name, owner } = flag;
await db.query(queryText.deleteFlag, [flag_id]);
res.status(200).json({
status: 200,
data: `Flag on ${car_name} successfully deleted.`,
Expand Down
Loading

0 comments on commit c64377e

Please sign in to comment.