condensing the controllers for accessing each model separately

This commit is contained in:
Arjun Patel
2019-03-17 00:13:40 -07:00
parent 5587c296e4
commit 6306d3b1a7
27 changed files with 360 additions and 402 deletions
-3
View File
@@ -1,3 +0,0 @@
module.exports = {
organization: require('./organization.controller')
};
@@ -1,16 +0,0 @@
const db = require('../../../models'),
errorMaker = require('../../helpers/error.maker');
const { Grant, Cause, Region, Organization } = db;
// Verify charity
exports.verifyOrg = async (req, res, next) => {
const charity_id = req.params.charity_id;
await db.sequelize.query(
'UPDATE organizations SET verified = 1 WHERE id = :charity_id',
{ replacements: { charity_id } }
);
return res.status(200).json({ message: 'Successfully verified charity' });
};
+36
View File
@@ -0,0 +1,36 @@
const db = require('../../models'),
errorMaker = require('../helpers/error.maker'),
textCleaner = require('../helpers/text_cleaner');
const { Grant, Cause, Region, Organization } = db;
// ADD a cause into the database
exports.createCause = (req, res, next) => {
const { name } = req.body;
Cause.create({ name })
.then(cause => {
res.status(200).json({
message: 'Cause created',
cause
});
})
.catch(error => next(error));
};
// FETCH all causes
exports.getAllCauses = (req, res, next) => {
Cause.findAll()
.then(causes => {
causes = causes.map(cause => {
cause.name = textCleaner.titleCase(cause.name);
return cause;
});
res.status(200).json({
causes,
number_items: causes.length
});
})
.catch(error => next(error));
};
@@ -1,12 +1,12 @@
const db = require('../../../models'),
const db = require('../../models'),
bcrypt = require('bcrypt-nodejs'),
errorMaker = require('../../helpers/error.maker'),
errorMaker = require('../helpers/error.maker'),
uuidv4 = require('uuid/v4');
const Donor = db.Donor;
// Create/post a Donor
exports.create = (req, res, next) => {
exports.createDonor = (req, res, next) => {
// see if user already in db
Donor.findAll({
where: {
@@ -53,7 +53,7 @@ exports.create = (req, res, next) => {
};
// FETCH all Donor
exports.findAll = (req, res, next) => {
exports.getAllDonors = (req, res, next) => {
Donor.findAll().then(donors => {
// Send all donors to Client
res.status(200).json({
@@ -64,14 +64,14 @@ exports.findAll = (req, res, next) => {
};
// Find a Donor by Id
exports.findById = (req, res) => {
exports.findDonorById = (req, res) => {
Donor.findById(req.params.donor_id).then(donor => {
res.send(donor);
});
};
// Delete a Donor by Id
exports.delete = (req, res) => {
exports.deleteDonor = (req, res) => {
const id = req.params.donor_id;
Donor.destroy({
where: { id: id }
-6
View File
@@ -1,6 +0,0 @@
module.exports = {
donor: require('./donor.controller'),
grant: require('./grant.controller'),
organization: require('./organization.controller'),
stripe: require('./stripe.controller')
};
@@ -1,57 +0,0 @@
const db = require('../../../models'),
errorMaker = require('../../helpers/error.maker');
const { Grant, Cause, Region, Organization } = db;
const log10 = val => {
return Math.log(val) / Math.log(10);
};
// POST to get suggested organizations based on chosen causes + regions
exports.findSuggested = (req, res, next) => {
const { amount, causes, regions } = req.body;
if (amount == 0 || causes.length == 0 || regions.length == 0) {
return next(errorMaker(400, 'Invalid options for grant suggestions'));
}
// formula for max amount of organizations to choose
const max_orgs = Math.floor(1.5 * log10(amount));
const QUERY =
'SELECT * from organizations ' +
'WHERE primary_cause IN (:causes) or primary_region IN (:regions) ' +
'LIMIT :max_orgs';
db.sequelize
.query(QUERY, {
replacements: { causes, regions, max_orgs },
type: db.Sequelize.QueryTypes.SELECT
})
.then(organizations => {
res.status(200).json({
organizations,
num_items: organizations.length,
max_orgs,
distribution: amount / organizations.length
});
})
.catch(error => next(error));
};
// GET min and optimal amounts for the chosen causes + regions
exports.findAmounts = (req, res, next) => {
const { num_causes, num_regions } = req.body;
const feature_factor = parseInt(num_causes) + parseFloat(num_regions / 2);
// calculate min amount for chosen causes and regions
const min_amount = Math.ceil(feature_factor * 15);
// calculate optimal for chosen causes and regions
const optimal_amount = Math.ceil(Math.pow(5, feature_factor));
res.status(200).json({
min_amount,
optimal_amount
});
};
@@ -1,13 +1,20 @@
const db = require('../../../models'),
errorMaker = require('../../helpers/error.maker');
const db = require('../../models'),
errorMaker = require('../helpers/error.maker');
const stripe = require('./stripe.controller');
const sendgrid = require('../sendgrid.controller');
const sendgrid = require('./sendgrid.controller');
const { Grant, Cause, Region, Organization, GrantOrganization, sequelize } = db;
console.log(db);
const {
Grant,
Cause,
Region,
Organization,
GrantOrganization,
Project,
sequelize
} = db;
// Create a grant for certain donor
exports.create = async (req, res, next) => {
exports.createGrant = async (req, res, next) => {
const user = req.user;
var { name, monthly, organizations, amount, stripeToken } = req.body;
@@ -49,10 +56,12 @@ exports.create = async (req, res, next) => {
};
});
// mapping between bundle and orgs
await GrantOrganization.bulkCreate(grantsOrgs, {
transaction
});
// one time charge
await stripe.grantCharge({
grant,
stripeToken,
@@ -63,6 +72,7 @@ exports.create = async (req, res, next) => {
user
});
// send email
await sendgrid.paymentReceipt({
organizations,
total_amount: actual_total,
@@ -83,7 +93,7 @@ exports.create = async (req, res, next) => {
};
// Find grants with causes, regions, and organizations by donor_id
exports.findByDonorId = (req, res, next) => {
exports.findGrantsByDonorId = (req, res, next) => {
const donor_id = req.user.id;
Grant.findAll({
@@ -101,7 +111,7 @@ exports.findByDonorId = (req, res, next) => {
.catch(error => next(error));
};
exports.delete = (req, res, next) => {
exports.deleteGrant = (req, res, next) => {
const { grant_id } = req.body;
const user = req.user;
+11
View File
@@ -0,0 +1,11 @@
module.exports = {
donor: require('./donor.controller'),
grant: require('./grant.controller'),
organization: require('./organization.controller'),
stripe: require('./stripe.controller'),
sendgrid: require('./sendgrid.controller'),
region: require('./region.controller'),
cause: require('./cause.controller'),
user: require('./user.controller'),
auth: require('./auth.controller')
};
+218
View File
@@ -0,0 +1,218 @@
const db = require('../../models'),
bcrypt = require('bcrypt-nodejs'),
errorMaker = require('../helpers/error.maker'),
uuidv4 = require('uuid/v4');
const { Grant, Cause, Region, Organization } = db;
// Verify charity
exports.verifyCharity = async (req, res, next) => {
const charity_id = req.params.charity_id;
await db.sequelize.query(
'UPDATE organizations SET verified = 1 WHERE id = :charity_id',
{ replacements: { charity_id } }
);
return res.status(200).json({ message: 'Successfully verified charity' });
};
const log10 = val => {
return Math.log(val) / Math.log(10);
};
// POST to get suggested organizations based on chosen causes + regions
exports.findSuggestedCharities = (req, res, next) => {
const { amount, causes, regions } = req.body;
if (amount == 0 || causes.length == 0 || regions.length == 0) {
return next(errorMaker(400, 'Invalid options for grant suggestions'));
}
// formula for max amount of organizations to choose
const max_orgs = Math.floor(1.5 * log10(amount));
const QUERY =
'SELECT * from organizations ' +
'WHERE primary_cause IN (:causes) or primary_region IN (:regions) ' +
'LIMIT :max_orgs';
db.sequelize
.query(QUERY, {
replacements: { causes, regions, max_orgs },
type: db.Sequelize.QueryTypes.SELECT
})
.then(organizations => {
res.status(200).json({
organizations,
num_items: organizations.length,
max_orgs,
distribution: amount / organizations.length
});
})
.catch(error => next(error));
};
// GET min and optimal amounts for the chosen causes + regions
exports.findOptimalBundleAmounts = (req, res, next) => {
const { num_causes, num_regions } = req.body;
const feature_factor = parseInt(num_causes) + parseFloat(num_regions / 2);
// calculate min amount for chosen causes and regions
const min_amount = Math.ceil(feature_factor * 15);
// calculate optimal for chosen causes and regions
const optimal_amount = Math.ceil(Math.pow(5, feature_factor));
res.status(200).json({
min_amount,
optimal_amount
});
};
// POST create an organization
exports.createOrganization = async (req, res, next) => {
let {
name,
short_description,
primary_contact_email,
password,
address,
city,
country,
state,
zip,
primary_cause,
primary_region,
ein,
estimate_asset_value,
estimate_yearly_operating_cost,
is_nonprofit,
primary_contact_phone,
primary_contact_first_name,
primary_contact_last_name
} = req.body;
// primary_cause = primary_cause.trim().toLowerCase();
// primary_region = primary_region.trim().toLowerCase();
let transaction;
try {
transaction = await db.sequelize.transaction();
const orgs = await Organization.findAll({
where: { primary_contact_email }
});
if (orgs.length >= 1) {
return next(errorMaker(409, `Email Exists: ${primary_contact_email}`));
}
const CAUSE_QUERY = `SELECT name FROM causes
WHERE name = :primary_cause`;
const causes = await db.sequelize.query(CAUSE_QUERY, {
replacements: { primary_cause },
type: db.Sequelize.QueryTypes.SELECT
});
const REGION_QUERY = `SELECT name FROM regions
WHERE name = :primary_region`;
const regions = await db.sequelize.query(REGION_QUERY, {
replacements: { primary_region },
type: db.Sequelize.QueryTypes.SELECT
});
// cause or region not found
if (!causes.length || !regions.length) {
throw errorMaker(400, `No valid cause or region`);
}
const saltRounds = await bcrypt.genSaltSync(10);
// hash with salt rounds
const hashedPass = await bcrypt.hashSync(password, saltRounds);
// Store hash in DB
const org = await Organization.create({
id: uuidv4(),
name,
short_description,
primary_contact_email,
password: hashedPass,
address,
city,
country,
state,
zip,
primary_cause,
primary_region,
ein,
estimate_asset_value,
estimate_yearly_operating_cost,
is_nonprofit,
primary_contact_phone,
primary_contact_first_name,
primary_contact_last_name
});
await transaction.commit();
return res.status(201).json({
message: 'Organization created',
org
});
} catch (error) {
console.log(error);
await transaction.rollback();
next(error);
}
};
// FETCH all organizations
exports.getAllOrganizations = (req, res, next) => {
Organization.findAll()
.then(organizations => {
res.status(200).json({
organizations,
number_items: organizations.length
});
})
.catch(error => next(error));
};
// FETCH depending on the given search
exports.searchOrganizations = (req, res, next) => {
let { search } = req.params;
search = '%' + search + '%';
const limit = 10;
const QUERY = `SELECT * from organizations
WHERE name LIKE :search or
primary_cause LIKE :search or
primary_region LIKE :search
LIMIT :limit`;
db.sequelize
.query(QUERY, {
replacements: { search, limit },
type: db.Sequelize.QueryTypes.SELECT
})
.then(organizations => {
res.status(200).json({
organizations,
number_items: organizations.length
});
})
.catch(error => next(error));
};
@@ -1,18 +0,0 @@
const db = require('../../../models'),
errorMaker = require('../../helpers/error.maker');
const { Grant, Cause, Region, Organization } = db;
// ADD a cause into the database
exports.create = (req, res, next) => {
const { name } = req.body;
Cause.create({ name })
.then(cause => {
res.status(200).json({
message: 'Cause created',
cause
});
})
.catch(error => next(error));
};
-5
View File
@@ -1,5 +0,0 @@
module.exports = {
organization: require('./organization.controller'),
cause: require('./cause.controller'),
region: require('./region.controller')
};
@@ -1,116 +0,0 @@
const db = require('../../../models'),
bcrypt = require('bcrypt-nodejs'),
errorMaker = require('../../helpers/error.maker'),
uuidv4 = require('uuid/v4');
const { Grant, Cause, Region, Organization } = db;
// POST create an organization
exports.create = async (req, res, next) => {
let {
name,
short_description,
primary_contact_email,
password,
address,
city,
country,
state,
zip,
primary_cause,
primary_region,
ein,
estimate_asset_value,
estimate_yearly_operating_cost,
is_nonprofit,
primary_contact_phone,
primary_contact_first_name,
primary_contact_last_name
} = req.body;
// primary_cause = primary_cause.trim().toLowerCase();
// primary_region = primary_region.trim().toLowerCase();
let transaction;
try {
transaction = await db.sequelize.transaction();
const orgs = await Organization.findAll({
where: { primary_contact_email }
});
if (orgs.length >= 1) {
return next(errorMaker(409, `Email Exists: ${primary_contact_email}`));
}
const CAUSE_QUERY = `SELECT name FROM causes
WHERE name = :primary_cause`;
const causes = await db.sequelize.query(CAUSE_QUERY, {
replacements: { primary_cause },
type: db.Sequelize.QueryTypes.SELECT
});
const REGION_QUERY = `SELECT name FROM regions
WHERE name = :primary_region`;
const regions = await db.sequelize.query(REGION_QUERY, {
replacements: { primary_region },
type: db.Sequelize.QueryTypes.SELECT
});
// cause or region not found
if (!causes.length || !regions.length) {
throw errorMaker(400, `No valid cause or region`);
}
const saltRounds = await bcrypt.genSaltSync(10);
// hash with salt rounds
const hashedPass = await bcrypt.hashSync(password, saltRounds);
// Store hash in DB
const org = await Organization.create({
id: uuidv4(),
name,
short_description,
primary_contact_email,
password: hashedPass,
address,
city,
country,
state,
zip,
primary_cause,
primary_region,
ein,
estimate_asset_value,
estimate_yearly_operating_cost,
is_nonprofit,
primary_contact_phone,
primary_contact_first_name,
primary_contact_last_name
});
await transaction.commit();
return res.status(201).json({
message: 'Organization created',
org
});
} catch (error) {
console.log(error);
await transaction.rollback();
next(error);
}
};
@@ -1,18 +0,0 @@
const db = require('../../../models'),
errorMaker = require('../../helpers/error.maker');
const { Grant, Cause, Region, Organization } = db;
// ADD a region into the database
exports.create = (req, res, next) => {
const { name } = req.body;
Region.create({ name })
.then(region => {
res.status(200).json({
message: 'Region created',
region
});
})
.catch(error => next(error));
};
@@ -1,22 +0,0 @@
const db = require('../../../models'),
errorMaker = require('../../helpers/error.maker'),
textCleaner = require('../../helpers/text_cleaner');
const { Grant, Cause, Region, Organization } = db;
// FETCH all causes
exports.findAll = (req, res, next) => {
Cause.findAll()
.then(causes => {
causes = causes.map(cause => {
cause.name = textCleaner.titleCase(cause.name);
return cause;
});
res.status(200).json({
causes,
number_items: causes.length
});
})
.catch(error => next(error));
};
-6
View File
@@ -1,6 +0,0 @@
module.exports = {
cause: require('./cause.controller'),
region: require('./region.controller'),
organization: require('./organization.controller'),
user: require('./user.controller')
};
@@ -1,41 +0,0 @@
const db = require('../../../models'),
errorMaker = require('../../helpers/error.maker');
const { Grant, Cause, Region, Organization } = db;
// FETCH all organizations
exports.findAll = (req, res, next) => {
Organization.findAll()
.then(organizations => {
res.status(200).json({
organizations,
number_items: organizations.length
});
})
.catch(error => next(error));
};
// FETCH depending on the given search
exports.searchOrgs = (req, res, next) => {
let { search } = req.params;
search = '%' + search + '%';
const limit = 10;
const QUERY = `SELECT * from organizations
WHERE name LIKE :search or
primary_cause LIKE :search or
primary_region LIKE :search
LIMIT :limit`;
db.sequelize
.query(QUERY, {
replacements: { search, limit },
type: db.Sequelize.QueryTypes.SELECT
})
.then(organizations => {
res.status(200).json({
organizations,
number_items: organizations.length
});
})
.catch(error => next(error));
};
@@ -1,22 +0,0 @@
const db = require('../../../models'),
errorMaker = require('../../helpers/error.maker'),
textCleaner = require('../../helpers/text_cleaner');
const { Grant, Cause, Region, Organization } = db;
// FETCH all regions
exports.findAll = (req, res, next) => {
Region.findAll()
.then(regions => {
regions = regions.map(region => {
region.name = textCleaner.titleCase(region.name);
return region;
});
res.status(200).json({
regions,
number_items: regions.length
});
})
.catch(error => next(error));
};
+36
View File
@@ -0,0 +1,36 @@
const db = require('../../models'),
errorMaker = require('../helpers/error.maker'),
textCleaner = require('../helpers/text_cleaner');
const { Grant, Cause, Region, Organization } = db;
// ADD a region into the database
exports.createRegion = (req, res, next) => {
const { name } = req.body;
Region.create({ name })
.then(region => {
res.status(200).json({
message: 'Region created',
region
});
})
.catch(error => next(error));
};
// FETCH all regions
exports.getAllRegions = (req, res, next) => {
Region.findAll()
.then(regions => {
regions = regions.map(region => {
region.name = textCleaner.titleCase(region.name);
return region;
});
res.status(200).json({
regions,
number_items: regions.length
});
})
.catch(error => next(error));
};
@@ -1,5 +1,5 @@
const db = require('../../../models'),
errorMaker = require('../../helpers/error.maker');
const db = require('../../models'),
errorMaker = require('../helpers/error.maker');
const stripe = require('stripe')(process.env.STRIPE_KEY);
@@ -1,5 +1,5 @@
const db = require('../../../models'),
errorMaker = require('../../helpers/error.maker');
const db = require('../../models'),
errorMaker = require('../helpers/error.maker');
const { Grant, Cause, Region, Organization, User } = db;
+2 -5
View File
@@ -3,13 +3,10 @@ const express = require('express'),
checkAuth = require('../middleware/check-auth'),
roles = require('../helpers/roles');
const controllers = require('../controllers/admin');
const { organization } = require('../controllers');
// Manual verification of a charity
// TODO: Add checkAuth(roles.ADMIN) back into middleware
router.put(
'/org/:charity_id',
controllers.organization.verifyOrg
);
router.put('/org/:charity_id', organization.verifyCharity);
module.exports = router;
+1 -1
View File
@@ -2,7 +2,7 @@ const express = require('express'),
router = express.Router(),
checkAuth = require('../middleware/check-auth');
const auth = require('../controllers/auth.controller.js');
const { auth } = require('../controllers');
// Check database for donor and get token with donor role
router.post('/donor/login', auth.donorLogin);
+9 -13
View File
@@ -3,34 +3,30 @@ const express = require('express'),
checkAuth = require('../middleware/check-auth'),
roles = require('../helpers/roles');
const controllers = require('../controllers/donor');
const { donor, grant, stripe, organization } = require('../controllers');
// POST donor signup
router.post('/', controllers.donor.create);
router.post('/', donor.createDonor);
// GET all Donors
router.get('/', checkAuth(roles.ADMIN), controllers.donor.findAll);
router.get('/', checkAuth(roles.ADMIN), donor.getAllDonors);
// GET grants with causes, regions, charities by donor_id
router.get('/grants/', checkAuth(roles.DONOR), controllers.grant.findByDonorId);
router.get('/grants/', checkAuth(roles.DONOR), grant.findGrantsByDonorId);
/** POST Create grants with following body:
* - List of id's of selected causes, regions, charities
* - Monthly: true or false
* - donor_id
* */
router.post(
'/grants/',
checkAuth(roles.DONOR),
controllers.grant.create
);
router.post('/grants/', checkAuth(roles.DONOR), grant.createGrant);
// DELETE a grant of a donor
router.delete(
'/grants/',
checkAuth(roles.DONOR),
controllers.stripe.deleteGrant,
controllers.grant.delete
stripe.deleteGrant,
grant.deleteGrant
);
// POST to get suggested organizations to distribute to
@@ -38,14 +34,14 @@ router.delete(
router.post(
'/organizations/',
checkAuth(roles.DONOR),
controllers.organization.findSuggested
organization.findSuggestedCharities
);
// GET min and optimal amount to choose
router.get(
'/organizations/amounts',
checkAuth(roles.DONOR),
controllers.organization.findAmounts
organization.findOptimalBundleAmounts
);
// // Retrieve a single Donor by Id
+6 -10
View File
@@ -3,19 +3,15 @@ const express = require('express'),
checkAuth = require('../middleware/check-auth'),
roles = require('../helpers/roles');
const controllers = require('../controllers/organization');
const { organization, cause, region } = require('../controllers');
// Charity signup route
router.post('/', controllers.organization.create);
router.post('/', organization.createOrganization);
// Add cause
router.post('/cause', checkAuth(roles.ORGANIZATION), controllers.cause.create);
// // Add cause
// router.post('/cause', checkAuth(roles.ORGANIZATION), cause.createCause);
// Add region
router.post(
'/region',
checkAuth(roles.ORGANIZATION),
controllers.region.create
);
// // Add region
// router.post('/region', checkAuth(roles.ORGANIZATION), region.createRegion);
module.exports = router;
+13 -9
View File
@@ -1,27 +1,31 @@
const express = require('express'),
router = express.Router();
const controllers = require('../controllers/public');
const sgController = require('../controllers/sendgrid.controller');
const {
sendgrid,
cause,
region,
organization,
user
} = require('../controllers');
// Retrieve all causes
router.get('/causes', controllers.cause.findAll);
router.get('/causes', cause.getAllCauses);
// Retrieve all regions
router.get('/regions', controllers.region.findAll);
router.get('/regions', region.getAllRegions);
// Retrieve all organizations
router.get('/organizations', controllers.organization.findAll);
router.get('/organizations', organization.getAllOrganizations);
// Retrieve charities based on inputted search
// TODO: fix sql injection attack
router.get('/organizations/:search', controllers.organization.searchOrgs);
router.get('/organizations/:search', organization.searchOrganizations);
// Add user email to database from the landing page
router.post('/users/landing', controllers.user.addEmail);
router.post('/users/landing', user.addEmail);
// Test sending an email
router.post('/email/test', sgController.testEmail);
router.post('/email/test', sendgrid.testEmail);
module.exports = router;
-14
View File
@@ -1,14 +0,0 @@
const express = require('express'),
router = express.Router(),
checkAuth = require('../middleware/check-auth'),
roles = require('../helpers/roles');
const controller = require('../controllers/donor/stripe.controller');
// POST create one time or monthly charge for grant
router.post('/donor/grant', checkAuth(roles.DONOR), controller.grantCharge);
// DELETE grant's plan under subscription
router.delete('/donor/grant', checkAuth(roles.DONOR), controller.deleteGrant);
module.exports = router;
-2
View File
@@ -70,8 +70,6 @@ app.use('/api/auth', require('./app/routes/auth.route.js'));
app.use('/api', require('./app/routes/public.route.js'));
//admin routes
app.use('/admin', require('./app/routes/admin.route'));
//stripe routes
app.use('/api/stripe', require('./app/routes/stripe.route'));
//404 not found error handling on any other routes
app.use((req, res, next) => {