@coursebuilder/core
Version:
Core package for Course Builder
228 lines (226 loc) • 8.9 kB
JavaScript
import {
getPPPDiscountPercent
} from "./chunk-UIVG44OI.js";
import {
getBulkDiscountPercent
} from "./chunk-JX5MYOL7.js";
import {
z
} from "./chunk-JLNB6NRA.js";
import {
__name
} from "./chunk-VLQXSCFN.js";
// src/lib/pricing/determine-coupon-to-apply.ts
var PrismaCtxSchema = z.any();
var PurchaseSchema = z.any();
var DetermineCouponToApplyParamsSchema = z.object({
prismaCtx: PrismaCtxSchema,
merchantCouponId: z.string().optional(),
country: z.string(),
quantity: z.number(),
userId: z.string().optional(),
productId: z.string(),
purchaseToBeUpgraded: PurchaseSchema.nullable(),
autoApplyPPP: z.boolean(),
usedCoupon: z.object({
merchantCouponId: z.string().nullable().optional(),
restrictedToProductId: z.string().nullable().optional()
}).nullable().optional()
});
var SPECIAL_TYPE = "special";
var PPP_TYPE = "ppp";
var BULK_TYPE = "bulk";
var NONE_TYPE = "none";
var determineCouponToApply = /* @__PURE__ */ __name(async (params) => {
const { prismaCtx, merchantCouponId, country, quantity, userId, productId, purchaseToBeUpgraded, autoApplyPPP, usedCoupon } = DetermineCouponToApplyParamsSchema.parse(params);
const { getMerchantCoupon, getPurchasesForUser } = prismaCtx;
const couponRestrictedToDifferentProduct = usedCoupon?.merchantCouponId === merchantCouponId && usedCoupon?.restrictedToProductId && usedCoupon?.restrictedToProductId !== productId;
const candidateMerchantCoupon = !couponRestrictedToDifferentProduct && merchantCouponId ? await getMerchantCoupon(merchantCouponId) : null;
const specialMerchantCouponToApply = candidateMerchantCoupon?.type === SPECIAL_TYPE ? candidateMerchantCoupon : null;
const userPurchases = await getPurchasesForUser(userId);
const pppDetails = await getPPPDetails({
specialMerchantCoupon: specialMerchantCouponToApply,
appliedMerchantCoupon: candidateMerchantCoupon,
country,
quantity,
purchaseToBeUpgraded,
userPurchases,
autoApplyPPP,
prismaCtx
});
const { bulkCouponToBeApplied, consideredBulk } = await getBulkCouponDetails({
prismaCtx,
userId,
productId,
quantity,
appliedMerchantCoupon: specialMerchantCouponToApply,
pppApplied: pppDetails.pppApplied
});
let couponToApply = null;
if (pppDetails.status === VALID_PPP) {
couponToApply = pppDetails.pppCouponToBeApplied;
} else if (bulkCouponToBeApplied) {
couponToApply = bulkCouponToBeApplied;
} else {
couponToApply = specialMerchantCouponToApply;
}
const availableCoupons = pppDetails.availableCoupons;
const appliedCouponType = z.string().nullish().transform((couponType) => {
if (couponType === PPP_TYPE) {
return PPP_TYPE;
} else if (couponType === SPECIAL_TYPE) {
return SPECIAL_TYPE;
} else if (couponType === BULK_TYPE) {
return BULK_TYPE;
} else {
return NONE_TYPE;
}
}).parse(couponToApply?.type);
return {
appliedMerchantCoupon: couponToApply || void 0,
appliedCouponType,
availableCoupons,
bulk: consideredBulk
};
}, "determineCouponToApply");
var UserPurchasesSchema = z.any();
var MerchantCouponSchema = z.any();
var GetPPPDetailsParamsSchema = z.object({
specialMerchantCoupon: MerchantCouponSchema.nullable(),
appliedMerchantCoupon: MerchantCouponSchema.nullable(),
quantity: z.number(),
country: z.string(),
purchaseToBeUpgraded: PurchaseSchema.nullable(),
userPurchases: UserPurchasesSchema,
autoApplyPPP: z.boolean(),
prismaCtx: PrismaCtxSchema
});
var NO_PPP = "NO_PPP";
var INVALID_PPP = "INVALID_PPP";
var VALID_PPP = "VALID_PPP";
var getPPPDetails = /* @__PURE__ */ __name(async ({ specialMerchantCoupon, appliedMerchantCoupon, country, quantity, purchaseToBeUpgraded, userPurchases, autoApplyPPP, prismaCtx }) => {
const hasMadeNonPPPDiscountedPurchase = userPurchases.some((purchase) => purchase.status === "Valid");
const hasOnlyPPPDiscountedPurchases = !hasMadeNonPPPDiscountedPurchase;
const expectedPPPDiscountPercent = getPPPDiscountPercent(country);
const shouldLookupPPPMerchantCouponForUpgrade = appliedMerchantCoupon === null && purchaseToBeUpgraded !== null && hasOnlyPPPDiscountedPurchases && autoApplyPPP;
let pppMerchantCouponForUpgrade = null;
if (shouldLookupPPPMerchantCouponForUpgrade) {
pppMerchantCouponForUpgrade = await lookupApplicablePPPMerchantCoupon({
prismaCtx,
pppDiscountPercent: expectedPPPDiscountPercent
});
}
const pppCouponToBeApplied = appliedMerchantCoupon?.type === PPP_TYPE ? appliedMerchantCoupon : pppMerchantCouponForUpgrade;
const pppDiscountIsBetter = (specialMerchantCoupon?.percentageDiscount || 0) < expectedPPPDiscountPercent;
const pppConditionsMet = expectedPPPDiscountPercent > 0 && quantity === 1 && hasOnlyPPPDiscountedPurchases && pppDiscountIsBetter;
const pppApplied = quantity === 1 && appliedMerchantCoupon?.type === "ppp" && expectedPPPDiscountPercent > 0;
let availableCoupons = [];
if (pppConditionsMet) {
availableCoupons = await couponForType(PPP_TYPE, expectedPPPDiscountPercent, prismaCtx, country);
}
const baseDetails = {
pppApplied: false,
pppCouponToBeApplied: null,
availableCoupons
};
if (pppCouponToBeApplied === null) {
return {
...baseDetails,
status: NO_PPP
};
}
const couponPercentDoesNotMatchCountry = expectedPPPDiscountPercent !== pppCouponToBeApplied?.percentageDiscount;
const couponPercentOutOfRange = expectedPPPDiscountPercent <= 0 || expectedPPPDiscountPercent >= 1;
const pppAppliedToBulkPurchase = quantity > 1;
const invalidCoupon = couponPercentDoesNotMatchCountry || couponPercentOutOfRange || pppAppliedToBulkPurchase;
if (invalidCoupon) {
return {
...baseDetails,
status: INVALID_PPP,
availableCoupons: []
};
}
return {
...baseDetails,
status: VALID_PPP,
pppApplied,
pppCouponToBeApplied
};
}, "getPPPDetails");
var LookupApplicablePPPMerchantCouponParamsSchema = z.object({
prismaCtx: PrismaCtxSchema,
pppDiscountPercent: z.number()
});
var lookupApplicablePPPMerchantCoupon = /* @__PURE__ */ __name(async (params) => {
const { prismaCtx, pppDiscountPercent } = LookupApplicablePPPMerchantCouponParamsSchema.parse(params);
const { getMerchantCouponForTypeAndPercent } = prismaCtx;
const pppMerchantCoupon = await getMerchantCouponForTypeAndPercent({
type: PPP_TYPE,
percentageDiscount: pppDiscountPercent
});
if (pppMerchantCoupon === null)
return null;
return pppMerchantCoupon;
}, "lookupApplicablePPPMerchantCoupon");
var GetBulkCouponDetailsParamsSchema = z.object({
prismaCtx: PrismaCtxSchema,
userId: z.string().optional(),
productId: z.string(),
quantity: z.number(),
appliedMerchantCoupon: MerchantCouponSchema.nullable(),
pppApplied: z.boolean()
});
var getBulkCouponDetails = /* @__PURE__ */ __name(async (params) => {
const { prismaCtx, userId, productId, quantity, appliedMerchantCoupon, pppApplied } = GetBulkCouponDetailsParamsSchema.parse(params);
const seatCount = await getQualifyingSeatCount({
userId,
productId,
newPurchaseQuantity: quantity,
prismaCtx
});
const consideredBulk = seatCount > 1;
const bulkCouponPercent = getBulkDiscountPercent(seatCount);
const bulkDiscountIsBetter = (appliedMerchantCoupon?.percentageDiscount || 0) < bulkCouponPercent;
const bulkDiscountAvailable = bulkCouponPercent > 0 && bulkDiscountIsBetter && !pppApplied;
if (bulkDiscountAvailable) {
const bulkCoupons = await couponForType(BULK_TYPE, bulkCouponPercent, prismaCtx);
const bulkCoupon = bulkCoupons[0];
return {
bulkCouponToBeApplied: bulkCoupon,
consideredBulk
};
} else {
return {
bulkCouponToBeApplied: null,
consideredBulk
};
}
}, "getBulkCouponDetails");
var getQualifyingSeatCount = /* @__PURE__ */ __name(async ({ userId, productId: purchasingProductId, newPurchaseQuantity, prismaCtx }) => {
const { getPurchasesForUser } = prismaCtx;
const userPurchases = await getPurchasesForUser(userId);
const bulkPurchase = userPurchases.find(({ productId, bulkCoupon }) => productId === purchasingProductId && Boolean(bulkCoupon));
const existingSeatsPurchasedForThisProduct = bulkPurchase?.bulkCoupon?.maxUses || 0;
return newPurchaseQuantity + existingSeatsPurchasedForThisProduct;
}, "getQualifyingSeatCount");
async function couponForType(type, percentageDiscount, prismaCtx, country) {
const { getMerchantCouponsForTypeAndPercent } = prismaCtx;
const merchantCoupons = await getMerchantCouponsForTypeAndPercent({
type,
percentageDiscount
}) || [];
return merchantCoupons.map((coupon) => {
const { identifier, ...rest } = coupon;
return {
...rest,
...country && {
country
}
};
});
}
__name(couponForType, "couponForType");
export {
determineCouponToApply
};
//# sourceMappingURL=chunk-QDGLZ5WB.js.map