Przeglądaj źródła

Merge pull request #23462 from overleaf/ls-update-pricing-logic-for-small-educational-plans

Update pricing logic for small educational plans

GitOrigin-RevId: 0051f238ce50b2067b7dc75d08f55dc1c7ac3502
Liangjun Song 1 rok temu
rodzic
commit
eb5417fad5

+ 23 - 2
services/web/app/src/Features/Subscription/SubscriptionGroupHandler.js

@@ -143,8 +143,12 @@ async function _addSeatsSubscriptionChange(userId, adding) {
         .additional_license_legacy_price_in_cents
         .additional_license_legacy_price_in_cents
 
 
     if (
     if (
-      planPriceInCents / 100 > recurlySubscription.planPrice &&
-      legacyUnitPriceInCents > 0
+      _shouldUseLegacyPricing(
+        recurlySubscription.planPrice,
+        planPriceInCents / 100,
+        usage,
+        size
+      )
     ) {
     ) {
       unitPrice = legacyUnitPriceInCents / 100
       unitPrice = legacyUnitPriceInCents / 100
     }
     }
@@ -163,6 +167,23 @@ async function _addSeatsSubscriptionChange(userId, adding) {
   }
   }
 }
 }
 
 
+function _shouldUseLegacyPricing(
+  actualPlanPrice,
+  currentPlanPrice,
+  usage,
+  size
+) {
+  // For small educational groups (5 or fewer members)
+  // 2025 pricing is cheaper than legacy pricing
+  if (size <= 5 && usage === 'educational') {
+    return currentPlanPrice < actualPlanPrice
+  }
+
+  // For all other scenarios
+  // 2025 pricing is more expensive than legacy pricing
+  return currentPlanPrice > actualPlanPrice
+}
+
 async function previewAddSeatsSubscriptionChange(userId, adding) {
 async function previewAddSeatsSubscriptionChange(userId, adding) {
   const { changeRequest, currentAddonQuantity } =
   const { changeRequest, currentAddonQuantity } =
     await _addSeatsSubscriptionChange(userId, adding)
     await _addSeatsSubscriptionChange(userId, adding)

+ 60 - 0
services/web/test/unit/src/Subscription/SubscriptionGroupHandlerTests.js

@@ -143,6 +143,16 @@ describe('SubscriptionGroupHandler', function () {
           },
           },
         },
         },
       },
       },
+      educational: {
+        collaborator: {
+          USD: {
+            5: {
+              price_in_cents: 10000,
+              additional_license_legacy_price_in_cents: 5000,
+            },
+          },
+        },
+      },
     }
     }
 
 
     this.Handler = SandboxedModule.require(modulePath, {
     this.Handler = SandboxedModule.require(modulePath, {
@@ -509,6 +519,56 @@ describe('SubscriptionGroupHandler', function () {
             )
             )
             .should.equal(true)
             .should.equal(true)
         })
         })
+
+        it('should return the subscription change preview with legacy add-on price for small educational group', async function () {
+          this.PlansLocator.findLocalPlanInSettings = sinon.stub().returns({
+            ...this.localPlanInSettings,
+            planCode: 'group_collaborator_5_educational',
+            canUseFlexibleLicensing: true,
+          })
+          this.recurlySubscription.planPrice =
+            this.GroupPlansData.enterprise.collaborator.USD[5].price_in_cents /
+              100 +
+            1
+
+          preview =
+            await this.Handler.promises.previewAddSeatsSubscriptionChange(
+              this.adminUser_id,
+              this.adding
+            )
+          this.recurlySubscription.getRequestForAddOnPurchase
+            .calledWithExactly(
+              this.RecurlyEntities.MEMBERS_LIMIT_ADD_ON_CODE,
+              this.adding,
+              this.GroupPlansData.enterprise.collaborator.USD[5]
+                .additional_license_legacy_price_in_cents / 100
+            )
+            .should.equal(true)
+        })
+
+        it('should return the subscription change preview with non-legacy add-on price for small educational group', async function () {
+          this.PlansLocator.findLocalPlanInSettings = sinon.stub().returns({
+            ...this.localPlanInSettings,
+            planCode: 'group_collaborator_5_educational',
+            canUseFlexibleLicensing: true,
+          })
+          this.recurlySubscription.planPrice =
+            this.GroupPlansData.enterprise.collaborator.USD[5].price_in_cents /
+            100
+
+          preview =
+            await this.Handler.promises.previewAddSeatsSubscriptionChange(
+              this.adminUser_id,
+              this.adding
+            )
+          this.recurlySubscription.getRequestForAddOnPurchase
+            .calledWithExactly(
+              this.RecurlyEntities.MEMBERS_LIMIT_ADD_ON_CODE,
+              this.adding,
+              undefined
+            )
+            .should.equal(true)
+        })
       })
       })
     })
     })
   })
   })