Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions src/libs/SubscriptionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,6 @@ Onyx.connect({
callback: (value) => (billingStatus = value),
});

let firstPolicyDate: OnyxEntry<string>;
Onyx.connect({
key: ONYXKEYS.NVP_PRIVATE_FIRST_POLICY_CREATED_DATE,
callback: (value) => {
firstPolicyDate = value;
},
});

let hasManualTeam2025Pricing: OnyxEntry<string>;
Onyx.connect({
key: ONYXKEYS.NVP_PRIVATE_MANUAL_TEAM_2025_PRICING,
Expand Down Expand Up @@ -582,7 +574,7 @@ function shouldCalculateBillNewDot(): boolean {
return canDowngrade && getOwnedPaidPolicies(allPolicies, currentUserAccountID).length === 1;
}

function checkIfHasTeam2025Pricing() {
function checkIfHasTeam2025Pricing(firstPolicyDate: string | undefined) {
if (hasManualTeam2025Pricing) {
return true;
}
Expand All @@ -594,12 +586,17 @@ function checkIfHasTeam2025Pricing() {
return differenceInDays(firstPolicyDate, CONST.SUBSCRIPTION.TEAM_2025_PRICING_START_DATE) >= 0;
}

function getSubscriptionPrice(plan: PersonalPolicyTypeExcludedProps | null, preferredCurrency: PreferredCurrency, privateSubscriptionType: SubscriptionType | undefined): number {
function getSubscriptionPrice(
plan: PersonalPolicyTypeExcludedProps | null,
preferredCurrency: PreferredCurrency,
privateSubscriptionType: SubscriptionType | undefined,
firstPolicyDate: string | undefined,
): number {
if (!privateSubscriptionType || !plan) {
return 0;
}

const hasTeam2025Pricing = checkIfHasTeam2025Pricing();
const hasTeam2025Pricing = checkIfHasTeam2025Pricing(firstPolicyDate);

if (hasTeam2025Pricing && plan === CONST.POLICY.TYPE.TEAM) {
return CONST.SUBSCRIPTION_PRICES[preferredCurrency][plan][CONST.SUBSCRIPTION.PRICING_TYPE_2025];
Expand All @@ -613,10 +610,11 @@ function getSubscriptionPlanInfo(
privateSubscriptionType: SubscriptionType | undefined,
preferredCurrency: PreferredCurrency,
isFromComparisonModal: boolean,
firstPolicyDate: string | undefined,
): SubscriptionPlanInfo {
const priceValue = getSubscriptionPrice(subscriptionPlan, preferredCurrency, privateSubscriptionType);
const priceValue = getSubscriptionPrice(subscriptionPlan, preferredCurrency, privateSubscriptionType, firstPolicyDate);
const price = convertToShortDisplayString(priceValue, preferredCurrency);
const hasTeam2025Pricing = checkIfHasTeam2025Pricing();
const hasTeam2025Pricing = checkIfHasTeam2025Pricing(firstPolicyDate);

if (subscriptionPlan === CONST.POLICY.TYPE.TEAM) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
Expand Down Expand Up @@ -718,4 +716,5 @@ export {
shouldCalculateBillNewDot,
getSubscriptionPlanInfo,
getSubscriptionPrice,
checkIfHasTeam2025Pricing,
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import useThemeStyles from '@hooks/useThemeStyles';
import {getSubscriptionPlanInfo} from '@libs/SubscriptionUtils';
import variables from '@styles/variables';
import type CONST from '@src/CONST';
import useOnyx from '@src/hooks/useOnyx';
import ONYXKEYS from '@src/ONYXKEYS';
import SubscriptionPlanCardActionButton from './SubscriptionPlanCardActionButton';

type PersonalPolicyTypeExcludedProps = Exclude<ValueOf<typeof CONST.POLICY.TYPE>, 'personal'>;
Expand All @@ -36,7 +38,14 @@ function SubscriptionPlanCard({subscriptionPlan, isFromComparisonModal = false,
const currentSubscriptionPlan = useSubscriptionPlan();
const privateSubscription = usePrivateSubscription();
const preferredCurrency = usePreferredCurrency();
const {title, src, description, benefits, note, subtitle} = getSubscriptionPlanInfo(subscriptionPlan, privateSubscription?.type, preferredCurrency, isFromComparisonModal);
const [firstPolicyDate] = useOnyx(ONYXKEYS.NVP_PRIVATE_FIRST_POLICY_CREATED_DATE, {canBeMissing: true});
const {title, src, description, benefits, note, subtitle} = getSubscriptionPlanInfo(
subscriptionPlan,
privateSubscription?.type,
preferredCurrency,
isFromComparisonModal,
firstPolicyDate,
);
const isSelected = isFromComparisonModal && subscriptionPlan === currentSubscriptionPlan;
const benefitsColumns = shouldUseNarrowLayout || isFromComparisonModal ? 1 : 2;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ function SubscriptionSettings() {
const preferredCurrency = usePreferredCurrency();
const illustrations = useThemeIllustrations();
const isAnnual = privateSubscription?.type === CONST.SUBSCRIPTION.TYPE.ANNUAL;
const subscriptionPrice = getSubscriptionPrice(subscriptionPlan, preferredCurrency, privateSubscription?.type);
const [firstPolicyDate] = useOnyx(ONYXKEYS.NVP_PRIVATE_FIRST_POLICY_CREATED_DATE, {canBeMissing: true});
const subscriptionPrice = getSubscriptionPrice(subscriptionPlan, preferredCurrency, privateSubscription?.type, firstPolicyDate);
const priceDetails = translate(`subscription.yourPlan.${subscriptionPlan === CONST.POLICY.TYPE.CORPORATE ? 'control' : 'collect'}.${isAnnual ? 'priceAnnual' : 'pricePayPerUse'}`, {
lower: convertToShortDisplayString(subscriptionPrice, preferredCurrency),
upper: convertToShortDisplayString(subscriptionPrice * CONST.SUBSCRIPTION_PRICE_FACTOR, preferredCurrency),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ function SubscriptionSettings() {
const {isActingAsDelegate, showDelegateNoAccessModal} = useContext(DelegateNoAccessContext);
const isAnnual = privateSubscription?.type === CONST.SUBSCRIPTION.TYPE.ANNUAL;
const [privateTaxExempt] = useOnyx(ONYXKEYS.NVP_PRIVATE_TAX_EXEMPT, {canBeMissing: true});
const subscriptionPrice = getSubscriptionPrice(subscriptionPlan, preferredCurrency, privateSubscription?.type);
const [firstPolicyDate] = useOnyx(ONYXKEYS.NVP_PRIVATE_FIRST_POLICY_CREATED_DATE, {canBeMissing: true});
const subscriptionPrice = getSubscriptionPrice(subscriptionPlan, preferredCurrency, privateSubscription?.type, firstPolicyDate);
const priceDetails = translate(`subscription.yourPlan.${subscriptionPlan === CONST.POLICY.TYPE.CORPORATE ? 'control' : 'collect'}.${isAnnual ? 'priceAnnual' : 'pricePayPerUse'}`, {
lower: convertToShortDisplayString(subscriptionPrice, preferredCurrency),
upper: convertToShortDisplayString(subscriptionPrice * CONST.SUBSCRIPTION_PRICE_FACTOR, preferredCurrency),
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/SubscriptionUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Onyx from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import {
calculateRemainingFreeTrialDays,
checkIfHasTeam2025Pricing,
doesUserHavePaymentCardAdded,
getEarlyDiscountInfo,
getSubscriptionStatus,
Expand Down Expand Up @@ -505,6 +506,25 @@ describe('SubscriptionUtils', () => {
});
});

describe('checkIfHasTeam2025Pricing', () => {
it('should return true if the user is on a team plan and has a first policy date', () => {
expect(checkIfHasTeam2025Pricing('2025-10-22')).toBeTruthy();
});

it('should return true if the user has no first policy date', () => {
expect(checkIfHasTeam2025Pricing(undefined)).toBeTruthy();
});

it('should return false if the user has created workspace before the team 2025 pricing start date', () => {
expect(checkIfHasTeam2025Pricing('2022-10-22')).toBeFalsy();
});

it('should return true if the user has manual team 2025 pricing', async () => {
await Onyx.merge(ONYXKEYS.NVP_PRIVATE_MANUAL_TEAM_2025_PRICING, '2025-10-22');
expect(checkIfHasTeam2025Pricing('2022-10-22')).toBeTruthy();
});
});

describe('shouldShowDiscountBanner', () => {
const ownerAccountID = 234;
const policyID = '100012';
Expand Down
Loading