0

Update credit_billing.ts

This commit is contained in:
Nicolas 2024-06-05 13:22:03 -07:00
parent 5991000d2b
commit ec10eb09f3

View File

@ -36,7 +36,10 @@ export async function supaBillTeam(team_id: string, credits: number) {
let couponCredits = 0;
if (coupons && coupons.length > 0) {
couponCredits = coupons.reduce((total, coupon) => total + coupon.credits, 0);
couponCredits = coupons.reduce(
(total, coupon) => total + coupon.credits,
0
);
}
let sortedCoupons = coupons.sort((a, b) => b.credits - a.credits);
@ -55,28 +58,27 @@ export async function supaBillTeam(team_id: string, credits: number) {
usedCredits = usedCredits - sortedCoupons[0].credits;
// update coupon credits
await supabase_service
.from("coupons")
.update({
credits: 0
})
.eq("id", sortedCoupons[0].id);
.from("coupons")
.update({
credits: 0,
})
.eq("id", sortedCoupons[0].id);
sortedCoupons.shift();
} else {
// update coupon credits
await supabase_service
.from("coupons")
.update({
credits: sortedCoupons[0].credits - usedCredits
})
.eq("id", sortedCoupons[0].id);
.from("coupons")
.update({
credits: sortedCoupons[0].credits - usedCredits,
})
.eq("id", sortedCoupons[0].id);
usedCredits = 0;
}
}
return await createCreditUsage({ team_id, credits: 0 });
// not enough coupon credits and no subscription
// not enough coupon credits and no subscription
} else {
// update coupon credits
const usedCredits = credits - couponCredits;
@ -84,7 +86,7 @@ export async function supaBillTeam(team_id: string, credits: number) {
await supabase_service
.from("coupons")
.update({
credits: 0
credits: 0,
})
.eq("id", sortedCoupons[i].id);
}
@ -101,14 +103,18 @@ export async function supaBillTeam(team_id: string, credits: number) {
await supabase_service
.from("coupons")
.update({
credits: 0
credits: 0,
})
.eq("id", sortedCoupons[i].id);
}
const usedCredits = credits - couponCredits;
return await createCreditUsage({ team_id, subscription_id: subscription.id, credits: usedCredits });
} else { // using only coupon credits
return await createCreditUsage({
team_id,
subscription_id: subscription.id,
credits: usedCredits,
});
} else {
// using only coupon credits
let usedCredits = credits;
while (usedCredits > 0) {
// update coupons
@ -116,26 +122,29 @@ export async function supaBillTeam(team_id: string, credits: number) {
usedCredits = usedCredits - sortedCoupons[0].credits;
// update coupon credits
await supabase_service
.from("coupons")
.update({
credits: 0
})
.eq("id", sortedCoupons[0].id);
.from("coupons")
.update({
credits: 0,
})
.eq("id", sortedCoupons[0].id);
sortedCoupons.shift();
} else {
// update coupon credits
await supabase_service
.from("coupons")
.update({
credits: sortedCoupons[0].credits - usedCredits
})
.eq("id", sortedCoupons[0].id);
.from("coupons")
.update({
credits: sortedCoupons[0].credits - usedCredits,
})
.eq("id", sortedCoupons[0].id);
usedCredits = 0;
}
}
return await createCreditUsage({ team_id, subscription_id: subscription.id, credits: 0 });
return await createCreditUsage({
team_id,
subscription_id: subscription.id,
credits: 0,
});
}
}
@ -144,7 +153,11 @@ export async function supaBillTeam(team_id: string, credits: number) {
return await createCreditUsage({ team_id, credits });
}
return await createCreditUsage({ team_id, subscription_id: subscription.id, credits });
return await createCreditUsage({
team_id,
subscription_id: subscription.id,
credits,
});
}
export async function checkTeamCredits(team_id: string, credits: number) {
@ -157,12 +170,13 @@ export async function supaCheckTeamCredits(team_id: string, credits: number) {
}
// Retrieve the team's active subscription
const { data: subscription, error: subscriptionError } = await supabase_service
.from("subscriptions")
.select("id, price_id, current_period_start, current_period_end")
.eq("team_id", team_id)
.eq("status", "active")
.single();
const { data: subscription, error: subscriptionError } =
await supabase_service
.from("subscriptions")
.select("id, price_id, current_period_start, current_period_end")
.eq("team_id", team_id)
.eq("status", "active")
.single();
// Check for available coupons
const { data: coupons } = await supabase_service
@ -173,7 +187,10 @@ export async function supaCheckTeamCredits(team_id: string, credits: number) {
let couponCredits = 0;
if (coupons && coupons.length > 0) {
couponCredits = coupons.reduce((total, coupon) => total + coupon.credits, 0);
couponCredits = coupons.reduce(
(total, coupon) => total + coupon.credits,
0
);
}
// Free credits, no coupons
@ -204,23 +221,30 @@ export async function supaCheckTeamCredits(team_id: string, credits: number) {
console.log("totalCreditsUsed", totalCreditsUsed);
const end = new Date();
end.setDate(end.getDate() + 30);
end.setDate(end.getDate() + 30);
// check if usage is within 80% of the limit
const creditLimit = FREE_CREDITS;
const creditUsagePercentage = (totalCreditsUsed + credits) / creditLimit;
if (creditUsagePercentage >= 0.8) {
await sendNotification(team_id, NotificationType.APPROACHING_LIMIT, new Date().toISOString(), end.toISOString());
await sendNotification(
team_id,
NotificationType.APPROACHING_LIMIT,
new Date().toISOString(),
end.toISOString()
);
}
// 5. Compare the total credits used with the credits allowed by the plan.
if (totalCreditsUsed + credits > FREE_CREDITS) {
// Send email notification for insufficient credits
await sendNotification(team_id, NotificationType.LIMIT_REACHED, new Date().toISOString(), end.toISOString());
await sendNotification(
team_id,
NotificationType.LIMIT_REACHED,
new Date().toISOString(),
end.toISOString()
);
return {
success: false,
message: "Insufficient credits, please upgrade!",
@ -231,19 +255,19 @@ export async function supaCheckTeamCredits(team_id: string, credits: number) {
let totalCreditsUsed = 0;
try {
const { data: creditUsages, error: creditUsageError } = await supabase_service
.rpc("get_credit_usage_2", {
sub_id: subscription.id,
start_time: subscription.current_period_start,
end_time: subscription.current_period_end
});
const { data: creditUsages, error: creditUsageError } =
await supabase_service.rpc("get_credit_usage_2", {
sub_id: subscription.id,
start_time: subscription.current_period_start,
end_time: subscription.current_period_end,
});
if (creditUsageError) {
console.error("Error calculating credit usage:", creditUsageError);
}
if (creditUsages && creditUsages.length > 0) {
totalCreditsUsed = creditUsages[0].total_credits_used;
totalCreditsUsed = creditUsages[0].total_credits_used;
}
} catch (error) {
console.error("Error calculating credit usage:", error);
@ -260,7 +284,9 @@ export async function supaCheckTeamCredits(team_id: string, credits: number) {
.single();
if (priceError) {
throw new Error(`Failed to retrieve price for price_id: ${subscription.price_id}`);
throw new Error(
`Failed to retrieve price for price_id: ${subscription.price_id}`
);
}
const creditLimit = price.credits;
@ -268,11 +294,21 @@ export async function supaCheckTeamCredits(team_id: string, credits: number) {
// Compare the adjusted total credits used with the credits allowed by the plan
if (adjustedCreditsUsed + credits > price.credits) {
await sendNotification(team_id, NotificationType.LIMIT_REACHED, subscription.current_period_start, subscription.current_period_end);
await sendNotification(
team_id,
NotificationType.LIMIT_REACHED,
subscription.current_period_start,
subscription.current_period_end
);
return { success: false, message: "Insufficient credits, please upgrade!" };
} else if (creditUsagePercentage >= 0.8) {
// Send email notification for approaching credit limit
await sendNotification(team_id, NotificationType.APPROACHING_LIMIT, subscription.current_period_start, subscription.current_period_end);
await sendNotification(
team_id,
NotificationType.APPROACHING_LIMIT,
subscription.current_period_start,
subscription.current_period_end
);
}
return { success: true, message: "Sufficient credits available" };
@ -298,7 +334,10 @@ export async function countCreditsAndRemainingForCurrentBillingPeriod(
let couponCredits = 0;
if (coupons && coupons.length > 0) {
couponCredits = coupons.reduce((total, coupon) => total + coupon.credits, 0);
couponCredits = coupons.reduce(
(total, coupon) => total + coupon.credits,
0
);
}
if (subscriptionError || !subscription) {
@ -311,7 +350,9 @@ export async function countCreditsAndRemainingForCurrentBillingPeriod(
.eq("team_id", team_id);
if (creditUsageError || !creditUsages) {
throw new Error(`Failed to retrieve credit usage for team_id: ${team_id}`);
throw new Error(
`Failed to retrieve credit usage for team_id: ${team_id}`
);
}
const totalCreditsUsed = creditUsages.reduce(
@ -320,7 +361,11 @@ export async function countCreditsAndRemainingForCurrentBillingPeriod(
);
const remainingCredits = FREE_CREDITS + couponCredits - totalCreditsUsed;
return { totalCreditsUsed: totalCreditsUsed, remainingCredits, totalCredits: FREE_CREDITS + couponCredits };
return {
totalCreditsUsed: totalCreditsUsed,
remainingCredits,
totalCredits: FREE_CREDITS + couponCredits,
};
}
const { data: creditUsages, error: creditUsageError } = await supabase_service
@ -331,10 +376,15 @@ export async function countCreditsAndRemainingForCurrentBillingPeriod(
.lte("created_at", subscription.current_period_end);
if (creditUsageError || !creditUsages) {
throw new Error(`Failed to retrieve credit usage for subscription_id: ${subscription.id}`);
throw new Error(
`Failed to retrieve credit usage for subscription_id: ${subscription.id}`
);
}
const totalCreditsUsed = creditUsages.reduce((acc, usage) => acc + usage.credits_used, 0);
const totalCreditsUsed = creditUsages.reduce(
(acc, usage) => acc + usage.credits_used,
0
);
const { data: price, error: priceError } = await supabase_service
.from("prices")
@ -343,7 +393,9 @@ export async function countCreditsAndRemainingForCurrentBillingPeriod(
.single();
if (priceError || !price) {
throw new Error(`Failed to retrieve price for price_id: ${subscription.price_id}`);
throw new Error(
`Failed to retrieve price for price_id: ${subscription.price_id}`
);
}
const remainingCredits = price.credits + couponCredits - totalCreditsUsed;
@ -351,11 +403,19 @@ export async function countCreditsAndRemainingForCurrentBillingPeriod(
return {
totalCreditsUsed,
remainingCredits,
totalCredits: price.credits
totalCredits: price.credits,
};
}
async function createCreditUsage({ team_id, subscription_id, credits }: { team_id: string, subscription_id?: string, credits: number }) {
async function createCreditUsage({
team_id,
subscription_id,
credits,
}: {
team_id: string;
subscription_id?: string;
credits: number;
}) {
const { data: credit_usage } = await supabase_service
.from("credit_usage")
.insert([