diff --git a/server/tests/unit/billing/isProductUpgrade.test.ts b/server/tests/unit/billing/isProductUpgrade.test.ts index 76c42bc1b..87715b65f 100644 --- a/server/tests/unit/billing/isProductUpgrade.test.ts +++ b/server/tests/unit/billing/isProductUpgrade.test.ts @@ -192,7 +192,23 @@ describe("isProductUpgrade", () => { expect(isProductUpgrade({ prices1, prices2 })).toBe(true); }); - test("$20/mo to $200/yr = downgrade ($20/mo > $16.67/mo)", () => { + test("$20/mo to $500/yr = upgrade (larger interval always upgrade, even if expensive)", () => { + const prices1 = [ + createFixedPrice({ + amount: 20, + interval: BillingInterval.Month, + }), + ]; + const prices2 = [ + createFixedPrice({ + amount: 500, + interval: BillingInterval.Year, + }), + ]; + expect(isProductUpgrade({ prices1, prices2 })).toBe(true); + }); + + test("$20/mo to $200/yr = upgrade (larger interval always upgrade)", () => { const prices1 = [ createFixedPrice({ amount: 20, @@ -205,7 +221,7 @@ describe("isProductUpgrade", () => { interval: BillingInterval.Year, }), ]; - expect(isProductUpgrade({ prices1, prices2 })).toBe(false); + expect(isProductUpgrade({ prices1, prices2 })).toBe(true); }); test("$5/week to $20/mo = upgrade ($20/mo <= $20/mo)", () => { diff --git a/shared/utils/productUtils/isProductUpgrade.ts b/shared/utils/productUtils/isProductUpgrade.ts index 16d989322..5b6c6ffe5 100644 --- a/shared/utils/productUtils/isProductUpgrade.ts +++ b/shared/utils/productUtils/isProductUpgrade.ts @@ -2,6 +2,10 @@ import { Decimal } from "decimal.js"; import type { BillingInterval } from "../../models/productModels/intervals/billingInterval"; import type { Price } from "../../models/productModels/priceModels/priceModels"; +import { + compareBillingIntervals, + getLargestInterval, +} from "../intervalUtils/priceIntervalUtils"; import { intervalToValue } from "../intervalUtils"; import { nullish } from "../utils"; import { @@ -70,6 +74,17 @@ export const isProductUpgrade = ({ return true; } + const billingInterval1 = getLargestInterval({ prices: prices1 }); + const billingInterval2 = getLargestInterval({ prices: prices2 }); + + if (billingInterval1 && billingInterval2) { + const cmp = compareBillingIntervals({ + configA: billingInterval1, + configB: billingInterval2, + }); + if (cmp > 0) return true; + } + const total1 = getNormalizedTotal({ prices: prices1 }); const total2 = getNormalizedTotal({ prices: prices2 });