From 0bbe4b2e5a72f364a98dcd96daad308c74dfe56e Mon Sep 17 00:00:00 2001 From: Kristina <7614497+khjrtbrg@users.noreply.github.com> Date: Thu, 23 Jan 2025 11:30:22 +0100 Subject: [PATCH] [web] show monthly rates on group plans (#23019) GitOrigin-RevId: e500869be9def2c150b4773f2f18883021ab356b --- .../Subscription/SubscriptionHelper.js | 36 ++++++++++++++++++- services/web/locales/en.json | 1 + services/web/scripts/plan-prices/plans.mjs | 5 +++ .../Subscription/SubscriptionHelperTests.js | 20 +++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/services/web/app/src/Features/Subscription/SubscriptionHelper.js b/services/web/app/src/Features/Subscription/SubscriptionHelper.js index 1ee6ebcefa..d6bcb08167 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionHelper.js +++ b/services/web/app/src/Features/Subscription/SubscriptionHelper.js @@ -9,14 +9,38 @@ function shouldPlanChangeAtTermEnd(oldPlan, newPlan) { return oldPlan.price_in_cents > newPlan.price_in_cents } +/** + * This is duplicated in: + * - services/web/scripts/plan-prices/plans.mjs + * - services/web/modules/subscriptions/frontend/js/pages/plans-new-design/group-member-picker/group-plan-pricing.js + * @param {number} number + * @returns {number} + */ +function roundUpToNearest5Cents(number) { + return Math.ceil(number * 20) / 20 +} + /** * @import { CurrencyCode } from '../../../../types/subscription/currency' */ +/** + * @typedef {Object} PlanToPrice + * @property {string} collaborator + * @property {string} professional + */ + +/** + * @typedef {Object} LocalizedGroupPrice + * @property {PlanToPrice} price + * @property {PlanToPrice} pricePerUser + * @property {PlanToPrice} pricePerUserPerMonth + */ + /** * @param {CurrencyCode} recommendedCurrency * @param {string} locale - * @returns {{ price: { collaborator: string, professional: string }, pricePerUser: { collaborator: string, professional: string } }} - localized group price + * @returns {LocalizedGroupPrice} */ function generateInitialLocalizedGroupPrice(recommendedCurrency, locale) { const INITIAL_LICENSE_SIZE = 2 @@ -27,11 +51,17 @@ function generateInitialLocalizedGroupPrice(recommendedCurrency, locale) { INITIAL_LICENSE_SIZE ].price_in_cents / 100 const collaboratorPricePerUser = collaboratorPrice / INITIAL_LICENSE_SIZE + const collaboratorPricePerUserPerMonth = roundUpToNearest5Cents( + collaboratorPrice / INITIAL_LICENSE_SIZE / 12 + ) const professionalPrice = GroupPlansData.enterprise.professional[recommendedCurrency][ INITIAL_LICENSE_SIZE ].price_in_cents / 100 const professionalPricePerUser = professionalPrice / INITIAL_LICENSE_SIZE + const professionalPricePerUserPerMonth = roundUpToNearest5Cents( + professionalPrice / INITIAL_LICENSE_SIZE / 12 + ) /** * @param {number} price @@ -49,6 +79,10 @@ function generateInitialLocalizedGroupPrice(recommendedCurrency, locale) { collaborator: formatPrice(collaboratorPricePerUser), professional: formatPrice(professionalPricePerUser), }, + pricePerUserPerMonth: { + collaborator: formatPrice(collaboratorPricePerUserPerMonth), + professional: formatPrice(professionalPricePerUserPerMonth), + }, } } diff --git a/services/web/locales/en.json b/services/web/locales/en.json index e7e6f6de88..cd5b68da76 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -1507,6 +1507,7 @@ "per_month": "per month", "per_month_billed_annually": "per month, billed annually", "per_user": "per user", + "per_user_per_month": "per user / per month", "per_user_per_year": "per user / per year", "per_user_year": "per user / year", "per_year": "per year", diff --git a/services/web/scripts/plan-prices/plans.mjs b/services/web/scripts/plan-prices/plans.mjs index c89fd3110b..aa5548f1d0 100644 --- a/services/web/scripts/plan-prices/plans.mjs +++ b/services/web/scripts/plan-prices/plans.mjs @@ -64,6 +64,11 @@ const currencies = [ 'USD', ] +/** + * This is duplicated in: + * - services/web/app/src/Features/Subscription/SubscriptionHelper.js + * - services/web/modules/subscriptions/frontend/js/pages/plans-new-design/group-member-picker/group-plan-pricing.js + */ function roundUpToNearest5Cents(number) { return Math.ceil(number * 20) / 20 } diff --git a/services/web/test/unit/src/Subscription/SubscriptionHelperTests.js b/services/web/test/unit/src/Subscription/SubscriptionHelperTests.js index 69dcb20ea1..a6e1ffa089 100644 --- a/services/web/test/unit/src/Subscription/SubscriptionHelperTests.js +++ b/services/web/test/unit/src/Subscription/SubscriptionHelperTests.js @@ -157,6 +157,10 @@ describe('SubscriptionHelper', function () { collaborator: '5 CHF', professional: '50 CHF', }, + pricePerUserPerMonth: { + collaborator: '0,45 CHF', + professional: '4,20 CHF', + }, }) }) }) @@ -178,6 +182,10 @@ describe('SubscriptionHelper', function () { collaborator: '10 kr.', professional: '100 kr.', }, + pricePerUserPerMonth: { + collaborator: '0,85 kr.', + professional: '8,35 kr.', + }, }) }) }) @@ -199,6 +207,10 @@ describe('SubscriptionHelper', function () { collaborator: '15 kr', professional: '150 kr', }, + pricePerUserPerMonth: { + collaborator: '1,25 kr', + professional: '12,50 kr', + }, }) }) }) @@ -222,6 +234,10 @@ describe('SubscriptionHelper', function () { collaborator: 'kr 20', professional: 'kr 200', }, + pricePerUserPerMonth: { + collaborator: 'kr 1.70', + professional: 'kr 16.70', + }, }) }) }) @@ -243,6 +259,10 @@ describe('SubscriptionHelper', function () { collaborator: '$25', professional: '$250', }, + pricePerUserPerMonth: { + collaborator: '$2.10', + professional: '$20.85', + }, }) }) })