UNPKG

@coursebuilder/core

Version:

Core package for Course Builder

228 lines (226 loc) 8.9 kB
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