Skip to content

Commit 7e619a9

Browse files
committed
zen: black admin
1 parent 2abafbc commit 7e619a9

3 files changed

Lines changed: 164 additions & 78 deletions

File tree

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import { Billing } from "../src/billing.js"
2+
import { and, Database, desc, eq, isNotNull, lt, sql } from "../src/drizzle/index.js"
3+
import { BillingTable, PaymentTable, SubscriptionTable } from "../src/schema/billing.sql.js"
4+
5+
const fromWrkID = process.argv[2]
6+
const toWrkID = process.argv[3]
7+
8+
if (!fromWrkID || !toWrkID) {
9+
console.error("Usage: bun foo.ts <fromWrkID> <toWrkID>")
10+
process.exit(1)
11+
}
12+
13+
console.log(`Transferring subscription from ${fromWrkID} to ${toWrkID}`)
14+
15+
// Look up the FROM workspace billing
16+
const fromBilling = await Database.use((tx) =>
17+
tx
18+
.select({
19+
customerID: BillingTable.customerID,
20+
subscriptionID: BillingTable.subscriptionID,
21+
subscriptionCouponID: BillingTable.subscriptionCouponID,
22+
paymentMethodID: BillingTable.paymentMethodID,
23+
paymentMethodType: BillingTable.paymentMethodType,
24+
paymentMethodLast4: BillingTable.paymentMethodLast4,
25+
})
26+
.from(BillingTable)
27+
.where(eq(BillingTable.workspaceID, fromWrkID))
28+
.then((rows) => rows[0]),
29+
)
30+
if (!fromBilling) throw new Error(`Error: FROM workspace has no billing record`)
31+
if (!fromBilling.customerID) throw new Error(`Error: FROM workspace has no Stripe customer ID`)
32+
if (!fromBilling.subscriptionID) throw new Error(`Error: FROM workspace has no subscription`)
33+
34+
const fromSubscription = await Database.use((tx) =>
35+
tx
36+
.select({ userID: SubscriptionTable.userID })
37+
.from(SubscriptionTable)
38+
.where(eq(SubscriptionTable.workspaceID, fromWrkID))
39+
.then((rows) => rows[0]),
40+
)
41+
if (!fromSubscription) throw new Error(`Error: FROM workspace has no subscription`)
42+
43+
// Look up the previous customer ID in FROM workspace
44+
const subscriptionPayment = await Database.use((tx) =>
45+
tx
46+
.select({
47+
customerID: PaymentTable.customerID,
48+
timeCreated: PaymentTable.timeCreated,
49+
})
50+
.from(PaymentTable)
51+
.where(and(eq(PaymentTable.workspaceID, fromWrkID), sql`JSON_EXTRACT(enrichment, '$.type') = 'subscription'`))
52+
.then((rows) => {
53+
if (rows.length > 1) {
54+
console.error(`Error: Multiple subscription payments found for workspace ${fromWrkID}`)
55+
process.exit(1)
56+
}
57+
return rows[0]
58+
}),
59+
)
60+
const fromPrevPayment = await Database.use((tx) =>
61+
tx
62+
.select({ customerID: PaymentTable.customerID })
63+
.from(PaymentTable)
64+
.where(
65+
and(
66+
eq(PaymentTable.workspaceID, fromWrkID),
67+
isNotNull(PaymentTable.customerID),
68+
lt(PaymentTable.timeCreated, subscriptionPayment.timeCreated),
69+
),
70+
)
71+
.orderBy(desc(PaymentTable.timeCreated))
72+
.limit(1)
73+
.then((rows) => rows[0]),
74+
)
75+
if (!fromPrevPayment?.customerID) throw new Error(`Error: FROM workspace has no previous Stripe customer to revert to`)
76+
if (fromPrevPayment.customerID === fromBilling.customerID)
77+
throw new Error(`Error: FROM workspace has the same Stripe customer ID as the current one`)
78+
79+
const fromPrevPaymentMethods = await Billing.stripe().customers.listPaymentMethods(fromPrevPayment.customerID, {})
80+
if (fromPrevPaymentMethods.data.length === 0)
81+
throw new Error(`Error: FROM workspace has no previous Stripe payment methods`)
82+
83+
// Look up the TO workspace billing
84+
const toBilling = await Database.use((tx) =>
85+
tx
86+
.select({
87+
customerID: BillingTable.customerID,
88+
subscriptionID: BillingTable.subscriptionID,
89+
})
90+
.from(BillingTable)
91+
.where(eq(BillingTable.workspaceID, toWrkID))
92+
.then((rows) => rows[0]),
93+
)
94+
if (!toBilling) throw new Error(`Error: TO workspace has no billing record`)
95+
if (toBilling.subscriptionID) throw new Error(`Error: TO workspace already has a subscription`)
96+
97+
console.log(`FROM:`)
98+
console.log(` Old Customer ID: ${fromBilling.customerID}`)
99+
console.log(` New Customer ID: ${fromPrevPayment.customerID}`)
100+
console.log(`TO:`)
101+
console.log(` Old Customer ID: ${toBilling.customerID}`)
102+
console.log(` New Customer ID: ${fromBilling.customerID}`)
103+
104+
// Clear workspaceID from Stripe customer metadata
105+
await Billing.stripe().customers.update(fromPrevPayment.customerID, {
106+
metadata: {
107+
workspaceID: fromWrkID,
108+
},
109+
})
110+
await Billing.stripe().customers.update(fromBilling.customerID, {
111+
metadata: {
112+
workspaceID: toWrkID,
113+
},
114+
})
115+
116+
await Database.transaction(async (tx) => {
117+
await tx
118+
.update(BillingTable)
119+
.set({
120+
customerID: fromPrevPayment.customerID,
121+
subscriptionID: null,
122+
subscriptionCouponID: null,
123+
paymentMethodID: fromPrevPaymentMethods.data[0].id,
124+
paymentMethodLast4: fromPrevPaymentMethods.data[0].card?.last4 ?? null,
125+
paymentMethodType: fromPrevPaymentMethods.data[0].type,
126+
})
127+
.where(eq(BillingTable.workspaceID, fromWrkID))
128+
129+
await tx
130+
.update(BillingTable)
131+
.set({
132+
customerID: fromBilling.customerID,
133+
subscriptionID: fromBilling.subscriptionID,
134+
subscriptionCouponID: fromBilling.subscriptionCouponID,
135+
paymentMethodID: fromBilling.paymentMethodID,
136+
paymentMethodLast4: fromBilling.paymentMethodLast4,
137+
paymentMethodType: fromBilling.paymentMethodType,
138+
})
139+
.where(eq(BillingTable.workspaceID, toWrkID))
140+
141+
await tx
142+
.update(SubscriptionTable)
143+
.set({
144+
workspaceID: toWrkID,
145+
userID: fromSubscription.userID,
146+
})
147+
.where(eq(SubscriptionTable.workspaceID, fromWrkID))
148+
149+
await tx
150+
.update(PaymentTable)
151+
.set({
152+
workspaceID: toWrkID,
153+
})
154+
.where(
155+
and(
156+
eq(PaymentTable.workspaceID, fromWrkID),
157+
sql`JSON_EXTRACT(enrichment, '$.type') = 'subscription'`,
158+
eq(PaymentTable.amount, 20000000000),
159+
),
160+
)
161+
})
162+
163+
console.log(`done`)

packages/console/core/script/lookup-user.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ async function printWorkspace(workspaceID: string) {
143143
amount: PaymentTable.amount,
144144
paymentID: PaymentTable.paymentID,
145145
invoiceID: PaymentTable.invoiceID,
146+
customerID: PaymentTable.customerID,
146147
timeCreated: PaymentTable.timeCreated,
147148
timeRefunded: PaymentTable.timeRefunded,
148149
})

packages/console/core/script/remove-black.ts

Lines changed: 0 additions & 78 deletions
This file was deleted.

0 commit comments

Comments
 (0)