diff --git a/app/config/associate.js b/app/config/associate.js index be44529..537dd2b 100644 --- a/app/config/associate.js +++ b/app/config/associate.js @@ -15,7 +15,7 @@ module.exports = models => { donor.hasMany(Grant, { foreignKey: 'donor_id' }); Grant.belongsToMany(Organization, { - through: 'grants_organizations', + through: 'Grant_Organization', foreignKey: 'grant_id', otherKey: 'organization_id' }); diff --git a/app/controllers/donor/grant.controller.js b/app/controllers/donor/grant.controller.js index ce70d61..d3fe410 100644 --- a/app/controllers/donor/grant.controller.js +++ b/app/controllers/donor/grant.controller.js @@ -4,21 +4,16 @@ const db = require('../../../models'), const stripe = require('./stripe.controller'); const sendgrid = require('../sendgrid.controller'); -const { Grant, Cause, Region, Organization, sequelize } = db; - +const { Grant, Cause, Region, Organization, GrantOrganization, sequelize } = db; +console.log(db); // Create a grant for certain donor -exports.create = (req, res, next) => { +exports.create = async (req, res, next) => { const user = req.user; - var { - name, - monthly, - causes, - regions, - organizations, - amount, - stripeToken - } = req.body; + var { name, monthly, organizations, amount, stripeToken } = req.body; + + const causes = organizations.map(org => org.primary_cause); + const regions = organizations.map(org => org.primary_region); actual_total = Math.round(amount * 100) / 100; @@ -26,60 +21,65 @@ exports.create = (req, res, next) => { throw errorMaker(400, 'No stripe token given'); } - return sequelize - .transaction(function(t) { - return Grant.create( - { - donor_id: user.id, - name, - amount: actual_total, - monthly, - num_causes: causes.length, - num_regions: regions.length - }, - { - transaction: t - } - ).then(grant => { - return Promise.all([ - grant.addCauses(causes, { transaction: t }), - grant.addRegions(regions, { transaction: t }), - organizations.map(org => { - grant.addOrganization(org.id, { - through: { amount: org.amount }, - transaction: t - }); - }) - ]).then(result => grant); - }); - }) - .then(function(grants) { - // transaction committed - stripe.grantCharge({ - grant: grants.dataValues, - stripeToken, - stripeToken, - organizations, + let transaction; + + try { + // get transaction + transaction = await sequelize.transaction(); + + const grant = await Grant.create( + { + donor_id: user.id, + name, + amount: actual_total, monthly, - amount, - user - }); + num_causes: causes.length, + num_regions: regions.length + }, + { + transaction + } + ); - sendgrid.paymentReceipt({ - organizations, - total_amount: actual_total, - receiver: user.email - }); - - return res.status(200).json({ - message: 'Successfully charged or subscribed', - grant: grants.dataValues - }); - }) - .catch(function(error) { - // transaction rollback - next(error); + const grantsOrgs = organizations.map(org => { + return { + grant_id: grant.id, + organization_id: org.id, + amount: org.amount + }; }); + + await GrantOrganization.bulkCreate(grantsOrgs, { + transaction + }); + + await stripe.grantCharge({ + grant, + stripeToken, + stripeToken, + organizations, + monthly, + amount, + user + }); + + await sendgrid.paymentReceipt({ + organizations, + total_amount: actual_total, + receiver: user.email + }); + + // commit + await transaction.commit(); + + return res.status(200).json({ + message: 'Successfully charged or subscribed', + grant + }); + } catch (error) { + if (error) await transaction.rollback(); + next(error); + } }; // Find grants with causes, regions, and organizations by donor_id diff --git a/models/Donor.js b/models/Donor.js index a15d05c..2887376 100644 --- a/models/Donor.js +++ b/models/Donor.js @@ -45,11 +45,5 @@ module.exports = (sequelize, DataTypes) => { country: DataTypes.STRING }); - Donor.associate = models => { - Donor.hasMany(models.Grant, { - foreignKey: 'donor_id' - }); - }; - return Donor; }; diff --git a/models/Grant.js b/models/Grant.js index 36754f2..98400be 100644 --- a/models/Grant.js +++ b/models/Grant.js @@ -1,3 +1,5 @@ +const Donor = require('./Donor'); + module.exports = (sequelize, DataTypes) => { const Grant = sequelize.define('Grant', { id: { @@ -25,16 +27,19 @@ module.exports = (sequelize, DataTypes) => { num_regions: { type: DataTypes.INTEGER, allowNull: false + }, + + donor_id: { + type: DataTypes.UUID, + allowNull: false, + references: { + model: Donor(sequelize, DataTypes), + key: 'id' + } } }); Grant.associate = models => { - Grant.belongsToMany(models.Organization, { - through: 'grants_organizations', - foreignKey: 'grant_id', - otherKey: 'organization_id' - }); - Grant.hasMany(models.Charge, { foreignKey: 'grant_id' }); }; diff --git a/models/Grant_Organization.js b/models/Grant_Organization.js index 78003d2..5867db7 100644 --- a/models/Grant_Organization.js +++ b/models/Grant_Organization.js @@ -1,14 +1,33 @@ +const Organization = require('./Organization'), + Grant = require('./Grant'); + module.exports = (sequelize, DataTypes) => { - const GrantsOrganizations = sequelize.define('Grants_Organizations', { + const GrantOrganization = sequelize.define('GrantOrganization', { id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, + grant_id: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: Grant(sequelize, DataTypes), + key: 'id' + } + }, + organization_id: { + type: DataTypes.UUID, + allowNull: false, + references: { + model: Organization(sequelize, DataTypes), + key: 'id' + } + }, amount: { type: DataTypes.INTEGER, allowNull: false } }); - return GrantsOrganizations; + return GrantOrganization; }; diff --git a/models/Project.js b/models/Project.js index 567f23d..0d1fd00 100644 --- a/models/Project.js +++ b/models/Project.js @@ -51,7 +51,7 @@ module.exports = (sequelize, DataTypes) => { } }, number_people_impacted: { - type: DataTypes.STRING, + type: DataTypes.INTEGER, defaultValue: 0 } });