Skip to content

Commit

Permalink
feat: more refactors
Browse files Browse the repository at this point in the history
  • Loading branch information
ArmanNik committed Aug 30, 2024
1 parent aa85bc1 commit c639fe0
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 61 deletions.
35 changes: 31 additions & 4 deletions src/lib/sdk/billing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,9 @@ export class Billing {
paymentMethodId: string,
billingAddressId: string = undefined,
invites: string[] = undefined,
couponId: string = undefined
couponId: string = undefined,
taxId: string = undefined,
billingBudget: number = undefined
): Promise<Organization> {
const path = `/organizations`;
const params = {
Expand All @@ -319,7 +321,9 @@ export class Billing {
paymentMethodId,
billingAddressId,
invites,
couponId
couponId,
taxId,
billingBudget
};
const uri = new URL(this.client.config.endpoint + path);
return await this.client.call(
Expand Down Expand Up @@ -368,14 +372,37 @@ export class Billing {
organizationId: string,
billingPlan: string,
paymentMethodId: string,
billingAddressId: string = undefined
billingAddressId: string = undefined,
invites: string[] = undefined,
couponId: string = undefined,
taxId: string = undefined,
billingBudget: number = undefined
): Promise<Organization> {
const path = `/organizations/${organizationId}/plan`;
const params = {
organizationId,
billingPlan,
paymentMethodId,
billingAddressId
billingAddressId,
invites,
couponId,
taxId,
billingBudget
};
const uri = new URL(this.client.config.endpoint + path);
return await this.client.call(
'patch',
uri,
{
'content-type': 'application/json'
},
params
);
}
async validateOrganization(organizationId: string): Promise<Organization> {
const path = `/organizations/${organizationId}/validate`;
const params = {
organizationId
};
const uri = new URL(this.client.config.endpoint + path);
return await this.client.call(
Expand Down
20 changes: 20 additions & 0 deletions src/lib/stores/billing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,3 +438,23 @@ export function calculateResourceSurplus(total: number, limit: number, limitUnit
const realLimit = (limitUnit ? sizeToBytes(limit, limitUnit) : limit) || Infinity;
return total > realLimit ? total - realLimit : 0;
}

export function buildOrgRedirectURL(
base: string,
name: string,
plan: string,
paymentMethodId: string,
id: string,
collaborators: string[] = null,
coupon: string = null
) {
const url = new URL(base);
url.searchParams.append('name', name);
url.searchParams.append('plan', plan);
url.searchParams.append('paymentMethod', paymentMethodId);
url.searchParams.append('validate', id);
if (collaborators?.length) url.searchParams.append('collaborators', collaborators.join(','));
if (coupon) url.searchParams.append('coupon', coupon);

return url.toString();
}
1 change: 1 addition & 0 deletions src/lib/stores/organization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type Organization = Models.Team<Record<string, unknown>> & {
amount: number;
billingTaxId?: string;
billingPlanDowngrade?: Tier;
client_secret?: string;
};

export type OrganizationList = {
Expand Down
62 changes: 47 additions & 15 deletions src/routes/(console)/apply-credit/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
} from '$lib/layout';
import { type PaymentList } from '$lib/sdk/billing';
import { app } from '$lib/stores/app';
import { buildOrgRedirectURL } from '$lib/stores/billing.js';
import { campaigns } from '$lib/stores/campaigns';
import { addNotification } from '$lib/stores/notifications';
import { organizationList, type Organization } from '$lib/stores/organization';
import { sdk } from '$lib/stores/sdk';
import { confirmPayment } from '$lib/stores/stripe.js';
import { ID } from '@appwrite.io/console';
import { onMount } from 'svelte';
import { writable } from 'svelte/store';
Expand Down Expand Up @@ -83,6 +85,19 @@
if (campaign?.plan) {
billingPlan = campaign.plan;
}
if ($page.url.searchParams.has('name')) {
name = $page.url.searchParams.get('name');
}
if ($page.url.searchParams.has('paymentMethod')) {
paymentMethodId = $page.url.searchParams.get('paymentMethod');
}
if ($page.url.searchParams.has('collaborators')) {
collaborators = $page.url.searchParams.get('collaborators')?.split(',') ?? [];
}
if ($page.url.searchParams.has('validate')) {
const id = $page.url.searchParams.get('validate');
await sdk.forConsole.billing.validateOrganization(id);
}
});
async function loadPaymentMethods() {
Expand All @@ -106,9 +121,11 @@
name,
billingPlan,
paymentMethodId,
undefined,
collaborators?.length ? collaborators : undefined,
couponData?.code ? couponData.code : undefined
null,
collaborators?.length ? collaborators : null,
couponData?.code ? couponData.code : null,
taxId ?? null,
billingBudget ?? null
);
}
// Upgrade existing org
Expand All @@ -117,20 +134,20 @@
selectedOrg.$id,
billingPlan,
paymentMethodId,
undefined,
collaborators?.length ? collaborators : undefined,
couponData?.code ? couponData.code : undefined
null,
collaborators?.length ? collaborators : null,
couponData?.code ? couponData.code : null,
taxId ?? null,
billingBudget ?? null
);
}
// Existing pro org
else {
org = selectedOrg;
// Add coupon
if (couponData?.code) {
await sdk.forConsole.billing.addCredit(org.$id, couponData.code);
}
// Add collaborators
if (collaborators?.length) {
collaborators.forEach(async (collaborator) => {
await sdk.forConsole.teams.createMembership(
Expand All @@ -143,17 +160,32 @@
);
});
}
}
// Add budget
if (billingBudget) {
await sdk.forConsole.billing.updateBudget(org.$id, billingBudget, [75]);
if (billingBudget) {
await sdk.forConsole.billing.updateBudget(org.$id, billingBudget, [75]);
}
if (taxId) {
await sdk.forConsole.billing.updateTaxId(org.$id, taxId);
}
}
// Add tax ID
if (taxId) {
await sdk.forConsole.billing.updateTaxId(org.$id, taxId);
// Confirm payment if required
if (org?.client_secret) {
let redirectURL = buildOrgRedirectURL(
`${base}/apply-credit`,
name,
billingPlan,
paymentMethodId,
org.$id,
collaborators,
couponData?.code
);
await confirmPayment(org.$id, org.client_secret, paymentMethodId, redirectURL);
await sdk.forConsole.billing.validateOrganization(org.$id);
}
trackEvent(Submit.CreditRedeem, {
coupon: couponData.code,
campaign: couponData?.campaign
Expand Down
38 changes: 28 additions & 10 deletions src/routes/(console)/create-organization/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@
WizardSecondaryFooter
} from '$lib/layout';
import type { Coupon, PaymentList } from '$lib/sdk/billing';
import { tierToPlan } from '$lib/stores/billing';
import { buildOrgRedirectURL, tierToPlan } from '$lib/stores/billing';
import { addNotification } from '$lib/stores/notifications';
import { organizationList, type Organization } from '$lib/stores/organization';
import { sdk } from '$lib/stores/sdk';
import { confirmPayment } from '$lib/stores/stripe';
import { ID } from '@appwrite.io/console';
import { onMount } from 'svelte';
import { writable } from 'svelte/store';
Expand Down Expand Up @@ -78,6 +79,16 @@
billingPlan = plan as BillingPlan;
}
}
if ($page.url.searchParams.has('paymentMethod')) {
paymentMethodId = $page.url.searchParams.get('paymentMethod');
}
if ($page.url.searchParams.has('collaborators')) {
collaborators = $page.url.searchParams.get('collaborators')?.split(',') ?? [];
}
if ($page.url.searchParams.has('validate')) {
const id = $page.url.searchParams.get('validate');
await sdk.forConsole.billing.validateOrganization(id);
}
if (anyOrgFree) {
billingPlan = BillingPlan.PRO;
}
Expand Down Expand Up @@ -118,18 +129,25 @@
billingPlan,
paymentMethodId,
null,
collaborators?.length ? collaborators : undefined,
couponData?.code
collaborators?.length ? collaborators : null,
couponData?.code ?? null,
taxId ?? null,
billingBudget ?? null
);
//Add budget
if (billingBudget) {
await sdk.forConsole.billing.updateBudget(org.$id, billingBudget, [75]);
}
if (org?.client_secret) {
let redirectURL = buildOrgRedirectURL(
`${base}/create-organization`,
name,
billingPlan,
paymentMethodId,
org.$id,
collaborators,
couponData?.code
);
await confirmPayment(org.$id, org.client_secret, paymentMethodId, redirectURL);
// Add tax ID
if (taxId) {
await sdk.forConsole.billing.updateTaxId(org.$id, taxId);
await sdk.forConsole.billing.validateOrganization(org.$id);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@
WizardSecondaryFooter
} from '$lib/layout';
import { type Coupon, type PaymentList } from '$lib/sdk/billing';
import { plansInfo, tierToPlan, type Tier } from '$lib/stores/billing';
import { buildOrgRedirectURL, plansInfo, tierToPlan, type Tier } from '$lib/stores/billing';
import { addNotification } from '$lib/stores/notifications';
import { organization, organizationList, type Organization } from '$lib/stores/organization';
import { sdk } from '$lib/stores/sdk';
import { confirmPayment } from '$lib/stores/stripe.js';
import { user } from '$lib/stores/user';
import { VARS } from '$lib/system';
import { onMount } from 'svelte';
Expand Down Expand Up @@ -98,6 +99,17 @@
} else {
billingPlan = BillingPlan.PRO;
}
if ($page.url.searchParams.has('paymentMethod')) {
paymentMethodId = $page.url.searchParams.get('paymentMethod');
}
if ($page.url.searchParams.has('collaborators')) {
collaborators = $page.url.searchParams.get('collaborators')?.split(',') ?? [];
}
if ($page.url.searchParams.has('validate')) {
const id = $page.url.searchParams.get('validate');
await sdk.forConsole.billing.validateOrganization(id);
}
});
async function loadPaymentMethods() {
Expand Down Expand Up @@ -172,41 +184,26 @@
$organization.$id,
billingPlan,
paymentMethodId,
null
null,
collaborators?.length ? collaborators : null,
couponData?.code ? couponData.code : null,
taxId ?? null,
billingBudget ?? null
);
//Add coupon
if (couponData?.code) {
await sdk.forConsole.billing.addCredit(org.$id, couponData.code);
trackEvent(Submit.CreditRedeem);
}
//Add budget
if (billingBudget) {
await sdk.forConsole.billing.updateBudget(org.$id, billingBudget, [75]);
}
//Add collaborators
if (collaborators?.length) {
const newCollaborators = collaborators.filter(
(collaborator) =>
!data?.members?.memberships?.find((m) => m.userEmail === collaborator)
if (org?.client_secret) {
let redirectURL = buildOrgRedirectURL(
`${base}/create-organization`,
org.name,
billingPlan,
paymentMethodId,
org.$id,
collaborators,
couponData?.code
);
newCollaborators.forEach(async (collaborator) => {
await sdk.forConsole.teams.createMembership(
org.$id,
['owner'],
collaborator,
undefined,
undefined,
`${$page.url.origin}/${base}/organization-${org.$id}`
);
});
}
await confirmPayment(org.$id, org.client_secret, paymentMethodId, redirectURL);
//Add tax ID
if (taxId) {
await sdk.forConsole.billing.updateTaxId(org.$id, taxId);
await sdk.forConsole.billing.validateOrganization(org.$id);
}
await invalidate(Dependencies.ACCOUNT);
Expand Down

0 comments on commit c639fe0

Please sign in to comment.