diff --git a/server/private/lib/billing/getOrgTierData.ts b/server/private/lib/billing/getOrgTierData.ts index fbfb5cb0..adda2414 100644 --- a/server/private/lib/billing/getOrgTierData.ts +++ b/server/private/lib/billing/getOrgTierData.ts @@ -12,7 +12,7 @@ */ import { getTierPriceSet } from "@server/lib/billing/tiers"; -import { getOrgSubscriptionData } from "#private/routers/billing/getOrgSubscription"; +import { getOrgSubscriptionsData } from "@server/private/routers/billing/getOrgSubscriptions"; import { build } from "@server/build"; export async function getOrgTierData( @@ -25,22 +25,32 @@ export async function getOrgTierData( return { tier, active }; } - const { subscription, items } = await getOrgSubscriptionData(orgId); + // TODO: THIS IS INEFFICIENT!!! WE SHOULD IMPROVE HOW WE STORE TIERS WITH SUBSCRIPTIONS AND RETRIEVE THEM - if (items && items.length > 0) { - const tierPriceSet = getTierPriceSet(); - // Iterate through tiers in order (earlier keys are higher tiers) - for (const [tierId, priceId] of Object.entries(tierPriceSet)) { - // Check if any subscription item matches this tier's price ID - const matchingItem = items.find((item) => item.priceId === priceId); - if (matchingItem) { - tier = tierId; - break; + const subscriptionsWithItems = await getOrgSubscriptionsData(orgId); + + for (const { subscription, items } of subscriptionsWithItems) { + if (items && items.length > 0) { + const tierPriceSet = getTierPriceSet(); + // Iterate through tiers in order (earlier keys are higher tiers) + for (const [tierId, priceId] of Object.entries(tierPriceSet)) { + // Check if any subscription item matches this tier's price ID + const matchingItem = items.find((item) => item.priceId === priceId); + if (matchingItem) { + tier = tierId; + break; + } } } - } - if (subscription && subscription.status === "active") { - active = true; + + if (subscription && subscription.status === "active") { + active = true; + } + + // If we found a tier and active subscription, we can stop + if (tier && active) { + break; + } } return { tier, active }; } diff --git a/server/private/routers/billing/getOrgSubscription.ts b/server/private/routers/billing/getOrgSubscriptions.ts similarity index 81% rename from server/private/routers/billing/getOrgSubscription.ts rename to server/private/routers/billing/getOrgSubscriptions.ts index e1f8316e..989e27d8 100644 --- a/server/private/routers/billing/getOrgSubscription.ts +++ b/server/private/routers/billing/getOrgSubscriptions.ts @@ -48,7 +48,7 @@ registry.registerPath({ responses: {} }); -export async function getOrgSubscription( +export async function getOrgSubscriptions( req: Request, res: Response, next: NextFunction @@ -66,12 +66,9 @@ export async function getOrgSubscription( const { orgId } = parsedParams.data; - let subscriptionData = null; - let itemsData: SubscriptionItem[] = []; + let subscriptions = null; try { - const { subscription, items } = await getOrgSubscriptionData(orgId); - subscriptionData = subscription; - itemsData = items; + subscriptions = await getOrgSubscriptionsData(orgId); } catch (err) { if ((err as Error).message === "Not found") { return next( @@ -86,8 +83,7 @@ export async function getOrgSubscription( return response(res, { data: { - subscription: subscriptionData, - items: itemsData + subscriptions }, success: true, error: false, @@ -102,9 +98,9 @@ export async function getOrgSubscription( } } -export async function getOrgSubscriptionData( +export async function getOrgSubscriptionsData( orgId: string -): Promise<{ subscription: Subscription | null; items: SubscriptionItem[] }> { +): Promise> { const org = await db .select() .from(orgs) @@ -122,21 +118,21 @@ export async function getOrgSubscriptionData( .where(eq(customers.orgId, orgId)) .limit(1); - let subscription = null; - let items: SubscriptionItem[] = []; + const subscriptionsWithItems: Array<{ + subscription: Subscription; + items: SubscriptionItem[]; + }> = []; if (customer.length > 0) { - // Get subscription for customer + // Get all subscriptions for customer const subs = await db .select() .from(subscriptions) - .where(eq(subscriptions.customerId, customer[0].customerId)) - .limit(1); + .where(eq(subscriptions.customerId, customer[0].customerId)); - if (subs.length > 0) { - subscription = subs[0]; - // Get subscription items - items = await db + for (const subscription of subs) { + // Get subscription items for each subscription + const items = await db .select() .from(subscriptionItems) .where( @@ -145,8 +141,13 @@ export async function getOrgSubscriptionData( subscription.subscriptionId ) ); + + subscriptionsWithItems.push({ + subscription, + items + }); } } - return { subscription, items }; + return subscriptionsWithItems; } diff --git a/server/private/routers/billing/index.ts b/server/private/routers/billing/index.ts index 106f3e43..e7770ec2 100644 --- a/server/private/routers/billing/index.ts +++ b/server/private/routers/billing/index.ts @@ -13,6 +13,6 @@ export * from "./createCheckoutSessionSAAS"; export * from "./createPortalSession"; -export * from "./getOrgSubscription"; +export * from "./getOrgSubscriptions"; export * from "./getOrgUsage"; export * from "./internalGetOrgTier"; diff --git a/server/private/routers/external.ts b/server/private/routers/external.ts index 3377db46..ddc2afe0 100644 --- a/server/private/routers/external.ts +++ b/server/private/routers/external.ts @@ -175,10 +175,10 @@ if (build === "saas") { ); authenticated.get( - "/org/:orgId/billing/subscription", + "/org/:orgId/billing/subscriptions", verifyOrgAccess, verifyUserHasAction(ActionsEnum.billing), - billing.getOrgSubscription + billing.getOrgSubscriptions ); authenticated.get( diff --git a/server/routers/billing/types.ts b/server/routers/billing/types.ts index 4e0aab52..f29b7e14 100644 --- a/server/routers/billing/types.ts +++ b/server/routers/billing/types.ts @@ -1,8 +1,7 @@ import { Limit, Subscription, SubscriptionItem, Usage } from "@server/db"; export type GetOrgSubscriptionResponse = { - subscription: Subscription | null; - items: SubscriptionItem[]; + subscriptions: Array<{ subscription: Subscription; items: SubscriptionItem[] }>; }; export type GetOrgUsageResponse = {