Merge pull request #21839 from overleaf/em-subscription-change-preview-premium

Subscription preview for users with standalone AI add-on

GitOrigin-RevId: 636fa5aca8538bb95e79040d5c309dc505cfb17a
This commit is contained in:
Eric Mc Sween
2024-11-19 09:05:09 +00:00
committed by Copybot
parent 34fa1e12e7
commit 424fd5b591
12 changed files with 253 additions and 32 deletions
@@ -31,7 +31,10 @@ const RecurlyClient = require('./RecurlyClient')
const { AI_ADD_ON_CODE } = require('./RecurlyEntities')
/**
* @import { SubscriptionChangeDescription } from '../../../../types/subscription/subscription-change-preview'
* @import { SubscriptionChangePreview } from '../../../../types/subscription/subscription-change-preview'
* @import { RecurlySubscriptionChange } from './RecurlyEntities'
* @import { PaymentMethod } from './types'
*/
const groupPlanModalOptions = Settings.groupPlanModalOptions
@@ -516,38 +519,17 @@ async function previewAddonPurchase(req, res) {
)
/** @type {SubscriptionChangePreview} */
const changePreview = {
change: {
const changePreview = makeChangePreview(
{
type: 'add-on-purchase',
addOn: {
code: addOn.code,
name: addOn.name,
},
},
currency: subscription.currency,
immediateCharge: subscriptionChange.immediateCharge,
paymentMethod: paymentMethod.toString(),
nextInvoice: {
date: subscription.periodEnd.toISOString(),
plan: {
name: subscriptionChange.nextPlanName,
amount: subscriptionChange.nextPlanPrice,
},
addOns: subscriptionChange.nextAddOns.map(addOn => ({
code: addOn.code,
name: addOn.name,
quantity: addOn.quantity,
unitAmount: addOn.unitPrice,
amount: addOn.preTaxTotal,
})),
subtotal: subscriptionChange.subtotal,
tax: {
rate: subscription.taxRate,
amount: subscriptionChange.tax,
},
total: subscriptionChange.total,
},
}
subscriptionChange,
paymentMethod
)
res.render('subscriptions/preview-change', { changePreview })
}
@@ -619,6 +601,31 @@ async function removeAddon(req, res, next) {
}
}
async function previewSubscription(req, res, next) {
const planCode = req.query.planCode
if (!planCode) {
return HttpErrorHandler.notFound(req, res, 'Missing plan code')
}
const plan = await RecurlyClient.promises.getPlan(planCode)
const userId = SessionManager.getLoggedInUserId(req.session)
const subscriptionChange =
await SubscriptionHandler.promises.previewSubscriptionChange(
userId,
planCode
)
const paymentMethod = await RecurlyClient.promises.getPaymentMethod(userId)
const changePreview = makeChangePreview(
{
type: 'premium-subscription',
plan: { code: plan.code, name: plan.name },
},
subscriptionChange,
paymentMethod
)
res.render('subscriptions/preview-change', { changePreview })
}
function updateSubscription(req, res, next) {
const origin = req && req.query ? req.query.origin : null
const user = SessionManager.getSessionUser(req.session)
@@ -887,6 +894,48 @@ async function getLatamCountryBannerDetails(req, res) {
return latamCountryBannerDetails
}
/**
* Build a subscription change preview for display purposes
*
* @param {SubscriptionChangeDescription} subscriptionChangeDescription A description of the change for the frontend
* @param {RecurlySubscriptionChange} subscriptionChange The subscription change object coming from Recurly
* @param {PaymentMethod} paymentMethod The payment method associated to the user
* @return {SubscriptionChangePreview}
*/
function makeChangePreview(
subscriptionChangeDescription,
subscriptionChange,
paymentMethod
) {
const subscription = subscriptionChange.subscription
return {
change: subscriptionChangeDescription,
currency: subscription.currency,
immediateCharge: subscriptionChange.immediateCharge,
paymentMethod: paymentMethod.toString(),
nextInvoice: {
date: subscription.periodEnd.toISOString(),
plan: {
name: subscriptionChange.nextPlanName,
amount: subscriptionChange.nextPlanPrice,
},
addOns: subscriptionChange.nextAddOns.map(addOn => ({
code: addOn.code,
name: addOn.name,
quantity: addOn.quantity,
unitAmount: addOn.unitPrice,
amount: addOn.preTaxTotal,
})),
subtotal: subscriptionChange.subtotal,
tax: {
rate: subscription.taxRate,
amount: subscriptionChange.tax,
},
total: subscriptionChange.total,
},
}
}
module.exports = {
plansPage: expressify(plansPage),
plansPageLightDesign: expressify(plansPageLightDesign),
@@ -896,6 +945,7 @@ module.exports = {
cancelSubscription,
canceledSubscription: expressify(canceledSubscription),
cancelV1Subscription,
previewSubscription: expressify(previewSubscription),
updateSubscription,
cancelPendingSubscriptionChange,
updateAccountEmailAddress,