Files
formbricks-formbricks/apps/web/lib/utils/billing.ts
2025-04-25 08:13:15 +00:00

55 lines
2.6 KiB
TypeScript

import { TOrganizationBilling } from "@formbricks/types/organizations";
// Function to calculate billing period start date based on organization plan and billing period
export const getBillingPeriodStartDate = (billing: TOrganizationBilling): Date => {
const now = new Date();
if (billing.plan === "free") {
// For free plans, use the first day of the current calendar month
return new Date(now.getFullYear(), now.getMonth(), 1);
} else if (billing.period === "yearly" && billing.periodStart) {
// For yearly plans, use the same day of the month as the original subscription date
const periodStart = new Date(billing.periodStart);
// Use UTC to avoid timezone-offset shifting when parsing ISO date-only strings
const subscriptionDay = periodStart.getUTCDate();
// Helper function to get the last day of a specific month
const getLastDayOfMonth = (year: number, month: number): number => {
// Create a date for the first day of the next month, then subtract one day
return new Date(year, month + 1, 0).getDate();
};
// Calculate the adjusted day for the current month
const lastDayOfCurrentMonth = getLastDayOfMonth(now.getFullYear(), now.getMonth());
const adjustedCurrentMonthDay = Math.min(subscriptionDay, lastDayOfCurrentMonth);
// Calculate the current month's adjusted subscription date
const currentMonthSubscriptionDate = new Date(now.getFullYear(), now.getMonth(), adjustedCurrentMonthDay);
// If today is before the subscription day in the current month (or its adjusted equivalent),
// we should use the previous month's subscription day as our start date
if (now.getDate() < adjustedCurrentMonthDay) {
// Calculate previous month and year
const prevMonth = now.getMonth() === 0 ? 11 : now.getMonth() - 1;
const prevYear = now.getMonth() === 0 ? now.getFullYear() - 1 : now.getFullYear();
// Calculate the adjusted day for the previous month
const lastDayOfPreviousMonth = getLastDayOfMonth(prevYear, prevMonth);
const adjustedPreviousMonthDay = Math.min(subscriptionDay, lastDayOfPreviousMonth);
// Return the adjusted previous month date
return new Date(prevYear, prevMonth, adjustedPreviousMonthDay);
} else {
return currentMonthSubscriptionDate;
}
} else if (billing.period === "monthly" && billing.periodStart) {
// For monthly plans with a periodStart, use that date
return new Date(billing.periodStart);
} else {
// For other plans, use the periodStart from billing
if (!billing.periodStart) {
throw new Error("billing period start is not set");
}
return new Date(billing.periodStart);
}
};