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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user