From 226f5c114932e87f1c4a83d4eb5c6d89e13c80e9 Mon Sep 17 00:00:00 2001 From: Arjun Patel Date: Sat, 2 Feb 2019 19:33:44 -0800 Subject: [PATCH] merging create grant and stripe calls --- app/config/associate.js | 10 ++- app/controllers/donor/grant.controller.js | 13 ++-- app/controllers/donor/index.js | 3 +- .../{ => donor}/stripe.controller.js | 64 +++++++++++++++---- ...22133-add-subscription-id-payment-plans.js | 20 ++++++ app/models/donor.model.js | 6 +- app/models/paymentplan.model.js | 4 ++ app/routes/donor.route.js | 14 +++- app/routes/stripe.route.js | 5 +- 9 files changed, 112 insertions(+), 27 deletions(-) rename app/controllers/{ => donor}/stripe.controller.js (58%) create mode 100644 app/migrations/20190203022133-add-subscription-id-payment-plans.js diff --git a/app/config/associate.js b/app/config/associate.js index 634eefb..8c010d4 100644 --- a/app/config/associate.js +++ b/app/config/associate.js @@ -28,9 +28,15 @@ module.exports = models => { foreignKey: 'grant_id', otherKey: 'organization_id' }); + Grant.hasMany(Charge, { foreignKey: 'grant_id' }); - Donor.hasOne(PaymentPlan, { - foreignKey: 'user_id' + Donor.hasMany(PaymentPlan, { + foreignKey: 'subscription_id', + sourceKey: 'subscription_id' + }); + + Grant.hasOne(PaymentPlan, { + foreignKey: 'grant_id' }); }; diff --git a/app/controllers/donor/grant.controller.js b/app/controllers/donor/grant.controller.js index 426f5be..84e8518 100644 --- a/app/controllers/donor/grant.controller.js +++ b/app/controllers/donor/grant.controller.js @@ -28,12 +28,15 @@ exports.create = (req, res, next) => { ]).then(result => grant); }); }) - .then(function(grant) { + .then(function(grants) { // transaction committed - res.status(201).json({ - grant, - message: 'Grant Created' - }); + // res.status(201).json({ + // grant, + // message: 'Grant Created' + // }); + + req.grant = grants.dataValues; + next(); }) .catch(function(error) { // transaction rollback diff --git a/app/controllers/donor/index.js b/app/controllers/donor/index.js index 77a4459..d9614d1 100644 --- a/app/controllers/donor/index.js +++ b/app/controllers/donor/index.js @@ -1,5 +1,6 @@ module.exports = { donor: require('./donor.controller'), grant: require('./grant.controller'), - organization: require('./organization.controller') + organization: require('./organization.controller'), + stripe: require('./stripe.controller') }; diff --git a/app/controllers/stripe.controller.js b/app/controllers/donor/stripe.controller.js similarity index 58% rename from app/controllers/stripe.controller.js rename to app/controllers/donor/stripe.controller.js index 288b9f8..c329eff 100644 --- a/app/controllers/stripe.controller.js +++ b/app/controllers/donor/stripe.controller.js @@ -1,5 +1,5 @@ -const db = require('../config/db.config.js'), - errorMaker = require('../helpers/error.maker'); +const db = require('../../config/db.config.js'), + errorMaker = require('../../helpers/error.maker'); const stripe = require('stripe')('sk_test_n8NCvCFjD1xFhGiEq6SI8CXj'); @@ -7,16 +7,20 @@ const { Donor, Charge, PaymentPlan } = db; // Subscribe user to plan or one time charge exports.grantCharge = async (req, res, next) => { - const { stripeToken, grant_id, amount, monthly } = req.body; + const { stripeToken, monthly } = req.body; + const { grant_id } = req.grant; + + const amount = req.body.amount * 100; //stripe standards + const user = req.user; - const product_id = 'prod_ER3jOog6QMX1GP'; + const product_id = 'prod_ER3jOog6QMX1GP', + default_plan_id = 'default_plan'; // main Grants product try { const donors = await Donor.findAll({ where: { id: user.id } }); // check if already a stripe customer let { stripe_id, subscription_id } = donors[0]; - console.log(stripeToken); if (!stripe_id) { const customer = await stripe.customers.create({ @@ -62,31 +66,63 @@ exports.grantCharge = async (req, res, next) => { if (!subscription_id) { let subscription = await stripe.subscriptions.create({ customer: stripe_id, - items: [{ plan: plan.id }] + items: [{ plan: default_plan_id }] }); + subscription_id = subscription.id; + await Donor.update( { subscription_id: subscription.id }, { where: { id: user.id } } ); - } else - await stripe.subscriptionItems.create({ - subscription: subscription_id, - plan: plan.id - }); + } + + const sub_item = await stripe.subscriptionItems.create({ + subscription: subscription_id, + plan: plan.id + }); result = await PaymentPlan.create({ plan_id: plan.id, amount, - grant_id: grant_id + grant_id, + subscription_id, + sub_item_id: sub_item.id }); } - res.status(200).json({ + return res.status(200).json({ message: 'Successfully charged or subscribed', - result + grant: req.grant }); } catch (error) { next(error); } }; + +// Delete grant's stripe plan under subscription +exports.deleteGrant = async (req, res, next) => { + const { grant_id } = req.body; + + try { + const paymentPlans = await PaymentPlan.findAll({ where: { grant_id } }); + + // check if there are plans for that grant + if (!paymentPlans.length) { + res.status(400).json({ + message: 'Not a valid grant' + }); + } else { + const plan = paymentPlans[0]; + + await stripe.subscriptionItems.del(plan.sub_item_id); + + res.status(201).json({ + message: 'Removed monthly subscription plan', + plan + }); + } + } catch (error) { + next(error); + } +}; diff --git a/app/migrations/20190203022133-add-subscription-id-payment-plans.js b/app/migrations/20190203022133-add-subscription-id-payment-plans.js new file mode 100644 index 0000000..b95b908 --- /dev/null +++ b/app/migrations/20190203022133-add-subscription-id-payment-plans.js @@ -0,0 +1,20 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.addColumn('payment_plans', 'sub_item_id', { + type: Sequelize.UUID, + unique: true + }); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.dropTable('users'); + */ + } +}; diff --git a/app/models/donor.model.js b/app/models/donor.model.js index b87ae58..c8f9d83 100644 --- a/app/models/donor.model.js +++ b/app/models/donor.model.js @@ -7,11 +7,13 @@ module.exports = (sequelize, DataTypes) => { }, stripe_id: { type: DataTypes.UUID, - defaultValue: null + defaultValue: null, + unique: true }, subscription_id: { type: DataTypes.UUID, - defaultValue: null + defaultValue: null, + unique: true }, first_name: { type: DataTypes.STRING, diff --git a/app/models/paymentplan.model.js b/app/models/paymentplan.model.js index e74df31..f5aadb7 100644 --- a/app/models/paymentplan.model.js +++ b/app/models/paymentplan.model.js @@ -14,6 +14,10 @@ module.exports = (sequelize, DataTypes) => { amount: { type: DataTypes.INTEGER, allowNull: false + }, + sub_item_id: { + type: DataTypes.UUID, + unique: true } }); diff --git a/app/routes/donor.route.js b/app/routes/donor.route.js index aa9efa1..c024179 100644 --- a/app/routes/donor.route.js +++ b/app/routes/donor.route.js @@ -20,10 +20,20 @@ router.get('/grants/', checkAuth(roles.DONOR), controllers.grant.findByDonorId); * - monthly true or false * - donor_id * */ -router.post('/grants/', checkAuth(roles.DONOR), controllers.grant.create); +router.post( + '/grants/', + checkAuth(roles.DONOR), + controllers.grant.create, + controllers.stripe.grantCharge +); // DELECT a grant of a donor -router.delete('/grants/', checkAuth(roles.DONOR), controllers.grant.delete); +router.delete( + '/grants/', + checkAuth(roles.DONOR), + controllers.stripe.deleteGrant, + controllers.grant.delete +); // POST to get suggested organizations to distribute to // running "the algorithm" diff --git a/app/routes/stripe.route.js b/app/routes/stripe.route.js index 5917869..01d8b38 100644 --- a/app/routes/stripe.route.js +++ b/app/routes/stripe.route.js @@ -3,9 +3,12 @@ const express = require('express'), checkAuth = require('../middleware/check-auth'), roles = require('../helpers/roles'); -const controller = require('../controllers/stripe.controller'); +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;