Merge pull request #24523 from overleaf/jdt-prevent-bundle-dbl-buys
Redirect bundle purchases when users already have it GitOrigin-RevId: d8e3c0256db08c08c2be24f38caef91fb26b90e8
This commit is contained in:
committed by
Copybot
parent
f11a6a6b87
commit
f7f4a03abb
@@ -197,6 +197,14 @@ async function doSyncFromV1(v1UserId) {
|
||||
return refreshFeatures(user._id, 'sync-v1')
|
||||
}
|
||||
|
||||
async function hasFeaturesViaWritefull(userId) {
|
||||
const user = await UserGetter.promises.getUser(userId, {
|
||||
_id: 1,
|
||||
writefull: 1,
|
||||
})
|
||||
return Boolean(user?.writefull?.isPremium)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
featuresEpochIsCurrent,
|
||||
computeFeatures: callbackify(computeFeatures),
|
||||
@@ -209,10 +217,12 @@ module.exports = {
|
||||
'featuresChanged',
|
||||
]),
|
||||
scheduleRefreshFeatures: callbackify(scheduleRefreshFeatures),
|
||||
hasFeaturesViaWritefull: callbackify(hasFeaturesViaWritefull),
|
||||
promises: {
|
||||
computeFeatures,
|
||||
refreshFeatures,
|
||||
scheduleRefreshFeatures,
|
||||
doSyncFromV1,
|
||||
hasFeaturesViaWritefull,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -477,6 +477,22 @@ function isStandaloneAiAddOnPlanCode(planCode) {
|
||||
return STANDALONE_AI_ADD_ON_CODES.includes(planCode)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether subscription change will have have the ai bundle once the change is processed
|
||||
*
|
||||
* @param {RecurlySubscriptionChange} subscriptionChange The subscription change object coming from Recurly
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
function subscriptionChangeIsAiAssistUpgrade(subscriptionChange) {
|
||||
return Boolean(
|
||||
isStandaloneAiAddOnPlanCode(subscriptionChange.nextPlanCode) ||
|
||||
subscriptionChange.nextAddOns?.some(
|
||||
addOn => addOn.code === AI_ADD_ON_CODE
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
AI_ADD_ON_CODE,
|
||||
MEMBERS_LIMIT_ADD_ON_CODE,
|
||||
@@ -493,5 +509,6 @@ module.exports = {
|
||||
RecurlyCoupon,
|
||||
RecurlyAccount,
|
||||
isStandaloneAiAddOnPlanCode,
|
||||
subscriptionChangeIsAiAssistUpgrade,
|
||||
RecurlyImmediateCharge,
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ const HttpErrorHandler = require('../Errors/HttpErrorHandler')
|
||||
const RecurlyClient = require('./RecurlyClient')
|
||||
const { AI_ADD_ON_CODE } = require('./RecurlyEntities')
|
||||
const PlansLocator = require('./PlansLocator')
|
||||
const RecurlyEntities = require('./RecurlyEntities')
|
||||
|
||||
/**
|
||||
* @import { SubscriptionChangeDescription } from '../../../../types/subscription/subscription-change-preview'
|
||||
@@ -45,7 +46,6 @@ function formatGroupPlansDataForDash() {
|
||||
|
||||
async function userSubscriptionPage(req, res) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
|
||||
await SplitTestHandler.promises.getAssignment(req, res, 'pause-subscription')
|
||||
|
||||
const groupPricingDiscount = await SplitTestHandler.promises.getAssignment(
|
||||
@@ -321,13 +321,19 @@ async function previewAddonPurchase(req, res) {
|
||||
try {
|
||||
subscriptionChange =
|
||||
await SubscriptionHandler.promises.previewAddonPurchase(userId, addOnCode)
|
||||
|
||||
const hasBundleViaWritefull =
|
||||
await FeaturesUpdater.promises.hasFeaturesViaWritefull(userId)
|
||||
const isAiUpgrade =
|
||||
RecurlyEntities.subscriptionChangeIsAiAssistUpgrade(subscriptionChange)
|
||||
if (hasBundleViaWritefull && isAiUpgrade) {
|
||||
return res.redirect(
|
||||
'/user/subscription?redirect-reason=writefull-entitled'
|
||||
)
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof DuplicateAddOnError) {
|
||||
return HttpErrorHandler.badRequest(
|
||||
req,
|
||||
res,
|
||||
`Subscription already has add-on "${addOnCode}"`
|
||||
)
|
||||
return res.redirect('/user/subscription?redirect-reason=double-buy')
|
||||
}
|
||||
throw err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user