fix: upgrading from past_due product, downgrade usage registered

This commit is contained in:
John Yeo
2025-04-21 20:14:20 +01:00
parent 8efcb67182
commit bebafbef2f
10 changed files with 33 additions and 21 deletions

View File

@@ -60,15 +60,15 @@ export const handleSubscriptionDeleted = async ({
return;
}
// Delete from subscriptions
try {
await SubService.deleteFromStripeId({
sb,
stripeId: subscription.id,
});
} catch (error) {
logger.error("Error deleting from subscriptions table", error);
}
// // Delete from subscriptions
// try {
// await SubService.deleteFromStripeId({
// sb,
// stripeId: subscription.id,
// });
// } catch (error) {
// logger.error("Error deleting from subscriptions table", error);
// }
// Prematurely canceled if cancel_at_period_end is false or cancel_at is more than 20 seconds apart from current_period_end
let prematurelyCanceled = subIsPrematurelyCanceled(subscription);

View File

@@ -345,7 +345,7 @@ attachRouter.post("/attach", async (req: any, res) => {
attachParams.metadata = metadata;
attachParams.isCustom = isCustom || false;
attachParams.disableFreeTrial = disableFreeTrial;
logger.info(
`Customer: ${chalk.yellow(
`${attachParams.customer.id} (${attachParams.customer.name})`

View File

@@ -274,6 +274,7 @@ export const createFullCusProduct = async ({
anchorToUnix,
carryExistingUsages = false,
carryOverTrial = false,
isDowngrade = false,
}: {
sb: SupabaseClient;
attachParams: InsertCusProductParams;
@@ -294,6 +295,7 @@ export const createFullCusProduct = async ({
anchorToUnix?: number;
carryExistingUsages?: boolean;
carryOverTrial?: boolean;
isDowngrade?: boolean;
}) => {
disableFreeTrial = attachParams.disableFreeTrial || disableFreeTrial;
@@ -380,6 +382,7 @@ export const createFullCusProduct = async ({
entitlements: entitlements,
curCusProduct: curCusProduct as FullCusProduct,
carryExistingUsages,
isDowngrade,
});
// 2. create customer prices

View File

@@ -24,6 +24,7 @@ import {
} from "@/internal/customers/add-product/handleSameProduct.js";
import { pricesOnlyOneOff } from "@/internal/prices/priceUtils.js";
import { getPricesForCusProduct } from "../change-product/scheduleUtils.js";
import { ACTIVE_STATUSES } from "../products/CusProductService.js";
export const getExistingCusProducts = async ({
product,
@@ -43,9 +44,8 @@ export const getExistingCusProducts = async ({
let curMainProduct = cusProducts.find(
(cp: any) =>
cp.product.group === product.group &&
// !cp.from_reward &&
!cp.product.is_add_on &&
cp.status === CusProductStatus.Active &&
ACTIVE_STATUSES.includes(cp.status) &&
!isOneOff(cp.customer_prices.map((cp: any) => cp.price))
);

View File

@@ -296,6 +296,7 @@ export const handleDowngrade = async ({
subscriptionScheduleIds: scheduledIds,
nextResetAt: latestPeriodEnd * 1000,
disableFreeTrial: true,
isDowngrade: true,
});
if (attachParams.org.api_version! >= APIVersion.v1_1) {

View File

@@ -125,14 +125,16 @@ export const addExistingUsagesToCusEnts = ({
curCusProduct,
carryExistingUsages = false,
printLogs = false,
isDowngrade = false,
}: {
cusEnts: CustomerEntitlement[];
entitlements: EntitlementWithFeature[];
curCusProduct: FullCusProduct;
carryExistingUsages?: boolean;
printLogs?: boolean;
isDowngrade?: boolean;
}) => {
if (!curCusProduct) {
if (!curCusProduct || isDowngrade) {
return cusEnts;
}

View File

@@ -11,10 +11,10 @@ import {
} from "@autumn/shared";
import { SupabaseClient } from "@supabase/supabase-js";
const ACTIVE_STATUSES = [
export const ACTIVE_STATUSES = [
CusProductStatus.Active,
CusProductStatus.Scheduled,
// CusProductStatus.PastDue,
CusProductStatus.PastDue,
];
export class CusProductService {

View File

@@ -71,7 +71,11 @@ const getOrCreateCustomerAndProducts = async ({
internalCustomerId: customer.internal_id,
withProduct: true,
withPrices: true,
inStatuses: [CusProductStatus.Active, CusProductStatus.Scheduled],
inStatuses: [
CusProductStatus.Active,
CusProductStatus.Scheduled,
CusProductStatus.PastDue,
],
logger,
});

View File

@@ -5,11 +5,11 @@ MOCHA_CMD="npx mocha --parallel --timeout 10000000 --ignore tests/00_setup.ts"
# TEST PARALLEL
if [ "$1" == "basic-parallel" ]; then
MOCHA_PARALLEL=true $MOCHA_SETUP && $MOCHA_CMD \
tests/basic/*.ts \
tests/basic/multi-feature/*.ts \
tests/basic/entities/*.ts \
# tests/basic/referrals/*.ts \
# tests/attach/**/*.ts \
tests/basic/referrals/*.ts \
tests/attach/**/*.ts \
# tests/basic/*.ts \
# tests/basic/multi-feature/*.ts \
# tests/basic/entities/*.ts \
elif [ "$1" == "advanced-parallel" ]; then

View File

@@ -71,6 +71,7 @@ describe(
});
it("should reattach premium group 1", async function () {
await timeout(3000);
await AutumnCli.attach({
customerId: customerId,
productId: attachProducts.premiumGroup1.id,
@@ -113,6 +114,7 @@ describe(
});
it("should reattach premium group 2 (scheduled should be cancelled)", async function () {
await timeout(3000);
let res = await AutumnCli.attach({
customerId: customerId,
productId: attachProducts.premiumGroup2.id,