Skip to content

Commit

Permalink
[dashboard] Show Team Subscription UI for owners without seat as well
Browse files Browse the repository at this point in the history
  • Loading branch information
geropl authored and roboquat committed Sep 21, 2022
1 parent 13d9fa9 commit a29b8ac
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 9 deletions.
7 changes: 3 additions & 4 deletions components/dashboard/src/settings/Teams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { Disposable } from "@gitpod/gitpod-protocol";
import { PaymentContext } from "../payment-context";
import { PageWithSettingsSubMenu } from "./PageWithSettingsSubMenu";
import { UserContext } from "../user-context";
import { BillingMode } from "@gitpod/gitpod-protocol/lib/billing-mode";

export default function Teams() {
return (
Expand Down Expand Up @@ -604,10 +605,8 @@ function AllTeams() {
</React.Fragment>
);

const showTeamPlans =
userBillingMode &&
(userBillingMode.mode === "chargebee" ||
(userBillingMode.mode === "usage-based" && !!userBillingMode.hasChargebeeTeamPlan));
// TOOD(gpl) We might want to reduce visibility of those actions similarly to how we guard access to that API, cmp.: https://github.com/gitpod-io/gitpod/blob/db90aefb9f7dc1d062e9cb73241c1fda2eccee4b/components/server/ee/src/workspace/gitpod-server-impl.ts#L2011
const showTeamPlans = BillingMode.showTeamSubscriptionUI(userBillingMode);
return (
<div>
{showTeamPlans ? (
Expand Down
2 changes: 1 addition & 1 deletion components/dashboard/src/settings/settings-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function renderBillingMenuEntries(billingMode?: BillingMode) {
link: [settingsPathBilling],
},
// We need to allow access to "Team Plans" here, at least for owners.
...(billingMode.hasChargebeeTeamSubscription
...(BillingMode.showTeamSubscriptionUI(billingMode)
? [
{
title: "Team Plans",
Expand Down
12 changes: 11 additions & 1 deletion components/gitpod-protocol/src/billing-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ export namespace BillingMode {
);
}

export function showTeamSubscriptionUI(billingMode?: BillingMode): boolean {
if (!billingMode) {
return false;
}
return (
billingMode.mode === "chargebee" ||
(billingMode.mode === "usage-based" && !!billingMode.hasChargebeeTeamSubscription)
);
}

export function canSetWorkspaceClass(billingMode?: BillingMode): boolean {
if (!billingMode) {
return false;
Expand Down Expand Up @@ -62,6 +72,6 @@ interface UsageBased {
/** User is already converted, but is member with at least one Chargebee-based "Team Plan" */
hasChargebeeTeamPlan?: boolean;

/** User is already converted, but is member in at least one Chargebee-based "Team Subscription" */
/** User is already converted, but is member or owner in at least one Chargebee-based "Team Subscription" */
hasChargebeeTeamSubscription?: boolean;
}
12 changes: 9 additions & 3 deletions components/server/ee/src/billing/billing-mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import { Subscription } from "@gitpod/gitpod-protocol/lib/accounting-protocol";
import { Config } from "../../../src/config";
import { StripeService } from "../user/stripe-service";
import { BillingMode } from "@gitpod/gitpod-protocol/lib/billing-mode";
import { TeamDB, TeamSubscription2DB, UserDB } from "@gitpod/gitpod-db/lib";
import { TeamDB, TeamSubscription2DB, TeamSubscriptionDB, UserDB } from "@gitpod/gitpod-db/lib";
import { Plans } from "@gitpod/gitpod-protocol/lib/plans";
import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution";
import { TeamSubscription2 } from "@gitpod/gitpod-protocol/lib/team-subscription-protocol";
import { TeamSubscription, TeamSubscription2 } from "@gitpod/gitpod-protocol/lib/team-subscription-protocol";

export const BillingModes = Symbol("BillingModes");
export interface BillingModes {
Expand All @@ -42,6 +42,7 @@ export class BillingModesImpl implements BillingModes {
@inject(ConfigCatClientFactory) protected readonly configCatClientFactory: ConfigCatClientFactory;
@inject(SubscriptionService) protected readonly subscriptionSvc: SubscriptionService;
@inject(StripeService) protected readonly stripeSvc: StripeService;
@inject(TeamSubscriptionDB) protected readonly teamSubscriptionDb: TeamSubscriptionDB;
@inject(TeamSubscription2DB) protected readonly teamSubscription2Db: TeamSubscription2DB;
@inject(TeamDB) protected readonly teamDB: TeamDB;
@inject(UserDB) protected readonly userDB: UserDB;
Expand Down Expand Up @@ -96,6 +97,10 @@ export class BillingModesImpl implements BillingModes {
const cbPersonalSubscriptions = cbSubscriptions.filter(
(s) => !isTeamSubscription(s) && s.planId !== Plans.FREE_OPEN_SOURCE.chargebeeId,
);
const cbOwnedTeamSubscriptions = (
await this.teamSubscriptionDb.findTeamSubscriptions({ userId: user.id })
).filter((ts) => TeamSubscription.isActive(ts, now.toISOString()));

let canUpgradeToUBB = false;
if (cbPersonalSubscriptions.length > 0) {
if (cbPersonalSubscriptions.every((s) => Subscription.isCancelled(s, now.toISOString()))) {
Expand Down Expand Up @@ -125,14 +130,15 @@ export class BillingModesImpl implements BillingModes {
const hasUbbPaidTeam = teamsModes.some((tm) => tm.mode === "usage-based" && !!tm.paid);
const hasCbTeam = teamsModes.some((tm) => tm.mode === "chargebee");
const hasCbTeamSeat = cbTeamSubscriptions.length > 0;
const hasCbTeamSubscription = cbOwnedTeamSubscriptions.length > 0;

if (hasUbbPaidTeam || hasUbbPersonal) {
// UBB is greedy: once a user has at least a paid team membership, they should benefit from it!
const result: BillingMode = { mode: "usage-based" };
if (hasCbTeam) {
result.hasChargebeeTeamPlan = true;
}
if (hasCbTeamSeat) {
if (hasCbTeamSeat || hasCbTeamSubscription) {
result.hasChargebeeTeamSubscription = true;
}
return result;
Expand Down

0 comments on commit a29b8ac

Please sign in to comment.