This commit is contained in:
John Yeo
2025-12-19 19:11:29 +00:00
parent 6ec7c0f011
commit 9eccb3a8cf
6 changed files with 70 additions and 5 deletions

View File

@@ -7,3 +7,19 @@
// newItems: body.items,
// products: [product],
// });
import type { SubscriptionUpdateV0Params } from "../../../../../../../shared";
import type { AutumnContext } from "../../../../../honoUtils/HonoEnv";
import type { UpdateSubscriptionContext } from "../fetch/updateSubscriptionContextSchema";
export const computeSubscriptionUpdateCustomConfigurationPlan = ({
ctx: AutumnContext,
updateSubscriptionContext,
params,
}: {
ctx: AutumnContext;
updateSubscriptionContext: UpdateSubscriptionContext;
params: SubscriptionUpdateV0Params;
}) => {
return {};
};

View File

@@ -22,6 +22,7 @@ export const computeSubscriptionUpdatePlan = (
},
): SubscriptionUpdatePlan => {
const intent = computeSubscriptionUpdateIntent(params);
const computePlan = getComputeSubscriptionUpdatePlanIntentMap(intent);
return computePlan(ctx, { updateSubscriptionContext, params });

View File

@@ -7,6 +7,7 @@ import type { AutumnContext } from "@/honoUtils/HonoEnv";
import { CusService } from "../../../../customers/CusService";
import { fetchStripeCustomerForBilling } from "../../fetch/fetchStripeUtils/fetchStripeCustomerForBilling";
import { fetchStripeSubscriptionForBilling } from "../../fetch/fetchStripeUtils/fetchStripeSubscriptionForBilling";
import { fetchTargetCusProductForUpdate } from "./fetchTargetCusProductForUpdate";
import type { UpdateSubscriptionContext } from "./updateSubscriptionContextSchema";
/**
@@ -42,9 +43,10 @@ export const fetchApiSubscriptionUpdateContext = async (
withEntities: true,
});
const targetCustomerProduct = fullCustomer.customer_products.find(
(cp) => cp.product.id === productId,
);
const targetCustomerProduct = fetchTargetCusProductForUpdate({
params,
fullCustomer,
});
if (!targetCustomerProduct) {
throw new InternalError({

View File

@@ -0,0 +1,32 @@
import {
type FullCustomer,
isCusProductOnEntity,
type SubscriptionUpdateV0Params,
} from "@autumn/shared";
export const fetchTargetCusProductForUpdate = ({
params,
fullCustomer,
}: {
params: SubscriptionUpdateV0Params;
fullCustomer: FullCustomer;
}) => {
const cusProducts = fullCustomer.customer_products;
const productId = params.product_id;
const internalEntityId = fullCustomer.entity?.internal_id;
const cusProductId = params.customer_product_id;
if (cusProductId) {
return cusProducts.find((cp) => cp.id === cusProductId);
}
return cusProducts.find((cp) => {
const productIdMatch = cp.product.id === productId;
const entityIdMatch = isCusProductOnEntity({
cusProduct: cp,
internalEntityId,
});
return productIdMatch && entityIdMatch;
});
};

View File

@@ -4,7 +4,7 @@ import { ProductItemSchema } from "../../../models/productV2Models/productItemMo
import { CustomerDataSchema } from "../../common/customerData";
import { EntityDataSchema } from "../../models";
export const SubscriptionUpdateV0ParamsSchema = z.object({
export const ExtSubscriptionUpdateV0ParamsSchema = z.object({
// Customer / Entity Info
customer_id: z.string(),
product_id: z.string().nullish(),
@@ -26,6 +26,15 @@ export const SubscriptionUpdateV0ParamsSchema = z.object({
prorate_billing: z.boolean().optional(),
});
export const SubscriptionUpdateV0ParamsSchema =
ExtSubscriptionUpdateV0ParamsSchema.extend({
customer_product_id: z.string().optional(),
});
export type ExtSubscriptionUpdateV0Params = z.infer<
typeof ExtSubscriptionUpdateV0ParamsSchema
>;
export type SubscriptionUpdateV0Params = z.infer<
typeof SubscriptionUpdateV0ParamsSchema
>;

View File

@@ -43,7 +43,12 @@ export const isCusProductTrialing = ({
);
};
// ATTACH PRIMITIVES
/**
* Returns true if the customer product is assigned to the given entity,
* or if no entity is specified, true if the product is not assigned to any entity.
* @param cusProduct - The customer product object
* @param internalEntityId - The internal entity ID to check, or undefined to check for unassigned
*/
export const isCusProductOnEntity = ({
cusProduct,
internalEntityId,