Some checks failed
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Admin Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Codespell / Check for spelling errors (push) Has been cancelled
Sync Repositories / sync_changes (push) Has been cancelled
Synced from upstream: 8853637e981ed7d8a6cff32bd98e7afe20f54362
99 lines
3.5 KiB
TypeScript
99 lines
3.5 KiB
TypeScript
import { orderBy } from "lodash-es";
|
|
// plane imports
|
|
import { EProductSubscriptionEnum, IPaymentProduct, TProductSubscriptionType, TSubscriptionPrice } from "@plane/types";
|
|
|
|
/**
|
|
* Calculates the yearly discount percentage when switching from monthly to yearly billing
|
|
* @param monthlyPrice - The monthly subscription price
|
|
* @param yearlyPricePerMonth - The monthly equivalent price when billed yearly
|
|
* @returns The discount percentage as a whole number (floored)
|
|
*/
|
|
export const calculateYearlyDiscount = (monthlyPrice: number, yearlyPricePerMonth: number): number => {
|
|
const monthlyCost = monthlyPrice * 12;
|
|
const yearlyCost = yearlyPricePerMonth * 12;
|
|
const amountSaved = monthlyCost - yearlyCost;
|
|
const discountPercentage = (amountSaved / monthlyCost) * 100;
|
|
return Math.floor(discountPercentage);
|
|
};
|
|
|
|
/**
|
|
* Gets the display name for a subscription plan variant
|
|
* @param planVariant - The subscription plan variant enum
|
|
* @returns The human-readable name of the plan
|
|
*/
|
|
export const getSubscriptionName = (planVariant: EProductSubscriptionEnum): string => {
|
|
switch (planVariant) {
|
|
case EProductSubscriptionEnum.FREE:
|
|
return "Free";
|
|
case EProductSubscriptionEnum.ONE:
|
|
return "One";
|
|
case EProductSubscriptionEnum.PRO:
|
|
return "Pro";
|
|
case EProductSubscriptionEnum.BUSINESS:
|
|
return "Business";
|
|
case EProductSubscriptionEnum.ENTERPRISE:
|
|
return "Enterprise";
|
|
default:
|
|
return "--";
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Gets the base subscription name for upgrade/downgrade paths
|
|
* @param planVariant - The current subscription plan variant
|
|
* @returns The name of the base subscription plan
|
|
*/
|
|
export const getBaseSubscriptionName = (planVariant: TProductSubscriptionType): string => {
|
|
switch (planVariant) {
|
|
case EProductSubscriptionEnum.ONE:
|
|
return getSubscriptionName(EProductSubscriptionEnum.FREE);
|
|
case EProductSubscriptionEnum.PRO:
|
|
return getSubscriptionName(EProductSubscriptionEnum.FREE);
|
|
case EProductSubscriptionEnum.BUSINESS:
|
|
return getSubscriptionName(EProductSubscriptionEnum.PRO);
|
|
case EProductSubscriptionEnum.ENTERPRISE:
|
|
return getSubscriptionName(EProductSubscriptionEnum.BUSINESS);
|
|
default:
|
|
return "--";
|
|
}
|
|
};
|
|
|
|
export type TSubscriptionPriceDetail = {
|
|
monthlyPriceDetails: TSubscriptionPrice;
|
|
yearlyPriceDetails: TSubscriptionPrice;
|
|
};
|
|
|
|
/**
|
|
* Gets the price details for a subscription product
|
|
* @param product - The payment product to get price details for
|
|
* @returns Array of price details for monthly and yearly plans
|
|
*/
|
|
export const getSubscriptionPriceDetails = (product: IPaymentProduct | undefined): TSubscriptionPriceDetail => {
|
|
const productPrices = product?.prices || [];
|
|
const monthlyPriceDetails = orderBy(productPrices, ["recurring"], ["desc"])?.find(
|
|
(price) => price.recurring === "month"
|
|
);
|
|
const monthlyPriceAmount = Number(((monthlyPriceDetails?.unit_amount || 0) / 100).toFixed(2));
|
|
const yearlyPriceDetails = orderBy(productPrices, ["recurring"], ["desc"])?.find(
|
|
(price) => price.recurring === "year"
|
|
);
|
|
const yearlyPriceAmount = Number(((yearlyPriceDetails?.unit_amount || 0) / 1200).toFixed(2));
|
|
|
|
return {
|
|
monthlyPriceDetails: {
|
|
key: "monthly",
|
|
id: monthlyPriceDetails?.id,
|
|
currency: "$",
|
|
price: monthlyPriceAmount,
|
|
recurring: "month",
|
|
},
|
|
yearlyPriceDetails: {
|
|
key: "yearly",
|
|
id: yearlyPriceDetails?.id,
|
|
currency: "$",
|
|
price: yearlyPriceAmount,
|
|
recurring: "year",
|
|
},
|
|
};
|
|
};
|