@coursebuilder/core
Version:
Core package for Course Builder
199 lines (197 loc) • 6.75 kB
JavaScript
import {
PricingFormattedInputSchema
} from "./chunk-4EOF5F5J.js";
import {
formatPricesForProduct
} from "./chunk-NTGLTY3X.js";
import {
__name
} from "./chunk-VLQXSCFN.js";
// src/lib/actions/prices-formatted.ts
import { isAfter } from "date-fns";
import { find } from "@coursebuilder/nodash";
var checkForAnyAvailableUpgrades = /* @__PURE__ */ __name(async ({ upgradeFromPurchaseId, productId, purchases, courseBuilderAdapter }) => {
if (upgradeFromPurchaseId)
return upgradeFromPurchaseId;
const validPurchases = getValidPurchases(purchases);
const productIdsAlreadyPurchased = validPurchases.map((purchase) => purchase.productId);
const potentialUpgrades = await courseBuilderAdapter.availableUpgradesForProduct(validPurchases, productId);
const availableUpgrades = potentialUpgrades.filter((availableUpgrade) => {
return !productIdsAlreadyPurchased.includes(availableUpgrade.upgradableTo.id);
});
return find(validPurchases, (purchase) => {
const upgradeProductIds = availableUpgrades.map((upgrade) => upgrade.upgradableFrom.id);
return upgradeProductIds.includes(purchase.productId);
})?.id;
}, "checkForAnyAvailableUpgrades");
var getValidPurchases = /* @__PURE__ */ __name((purchases) => {
return purchases.filter((purchase) => [
"Valid",
"Restricted"
].includes(purchase.status));
}, "getValidPurchases");
function couponIsValid(coupon) {
if (coupon) {
const unlimitedUse = coupon.maxUses === -1;
const now = /* @__PURE__ */ new Date();
if (!unlimitedUse && coupon.usedCount >= coupon.maxUses)
return false;
if (coupon.expires && isAfter(now, coupon.expires))
return false;
} else {
return false;
}
return true;
}
__name(couponIsValid, "couponIsValid");
async function getActiveMerchantCoupon({ productId, siteCouponId, code, courseBuilderAdapter }) {
let activeMerchantCoupon = null;
let usedCouponId;
const defaultCoupons = productId ? await courseBuilderAdapter.getDefaultCoupon([
productId
]) : void 0;
const defaultMerchantCoupon = defaultCoupons ? defaultCoupons.defaultMerchantCoupon : null;
const incomingCoupon = await courseBuilderAdapter.couponForIdOrCode({
couponId: siteCouponId,
code
});
if (
// compare the discounts if there is a coupon and site/sale running
incomingCoupon?.merchantCoupon && couponIsValid(incomingCoupon) && defaultMerchantCoupon
) {
const { merchantCoupon: incomingMerchantCoupon } = incomingCoupon;
if (incomingMerchantCoupon.percentageDiscount >= defaultMerchantCoupon.percentageDiscount) {
activeMerchantCoupon = incomingMerchantCoupon;
usedCouponId = incomingCoupon.id;
} else {
activeMerchantCoupon = defaultMerchantCoupon;
usedCouponId = defaultCoupons?.defaultCoupon?.id;
}
} else if (
// if it's a coupon, use it
incomingCoupon?.merchantCoupon && couponIsValid(incomingCoupon)
) {
activeMerchantCoupon = incomingCoupon.merchantCoupon;
usedCouponId = incomingCoupon.id;
} else if (
// if a sale is running, use that
defaultMerchantCoupon
) {
activeMerchantCoupon = defaultMerchantCoupon;
usedCouponId = defaultCoupons?.defaultCoupon?.id;
}
const defaultCoupon = defaultCoupons?.defaultCoupon;
return {
usedCouponId,
activeMerchantCoupon,
...defaultCoupon && defaultCoupon.merchantCouponId === activeMerchantCoupon?.id && {
defaultCoupon
}
};
}
__name(getActiveMerchantCoupon, "getActiveMerchantCoupon");
var CheckForAvailableCouponsSchema = PricingFormattedInputSchema.pick({
merchantCoupon: true,
couponId: true,
code: true,
productId: true
});
var checkForAvailableCoupons = /* @__PURE__ */ __name(async ({ merchantCoupon, couponId, productId, courseBuilderAdapter }) => {
if (merchantCoupon?.id) {
return {
activeMerchantCoupon: merchantCoupon,
defaultCoupon: void 0
};
} else {
const { activeMerchantCoupon, defaultCoupon, usedCouponId } = await getActiveMerchantCoupon({
siteCouponId: couponId,
productId,
code: void 0,
courseBuilderAdapter
});
const minimalDefaultCoupon = defaultCoupon && {
expires: defaultCoupon.expires?.toISOString(),
percentageDiscount: defaultCoupon.percentageDiscount.toString()
};
return {
activeMerchantCoupon,
defaultCoupon,
usedCouponId
};
}
}, "checkForAvailableCoupons");
async function getPricesFormatted(request, cookies, options) {
const currentUser = options.getCurrentUser ? await options.getCurrentUser() : null;
const { productId, quantity = 1, couponId, merchantCoupon, upgradeFromPurchaseId: _upgradeFromPurchaseId, autoApplyPPP, userId = currentUser?.id } = PricingFormattedInputSchema.parse(request.body);
if (!productId)
return {
status: 400,
body: "productId is required"
};
if (!options.adapter)
return {
status: 400,
body: "Adapter not found"
};
const purchases = getValidPurchases(await options.adapter.getPurchasesForUser(userId));
const country = request.headers?.["x-vercel-ip-country"] || request.body?.country || process.env.DEFAULT_COUNTRY || "US";
let upgradeFromPurchaseId = await checkForAnyAvailableUpgrades({
upgradeFromPurchaseId: _upgradeFromPurchaseId,
productId,
purchases,
country,
courseBuilderAdapter: options.adapter
});
const restrictedPurchase = purchases.find((purchase) => {
return purchase.productId === productId && purchase.status === "Restricted";
});
if (restrictedPurchase) {
const validPurchase = purchases.find((purchase) => {
return purchase.productId === productId && purchase.status === "Valid";
});
if (!validPurchase) {
upgradeFromPurchaseId = restrictedPurchase.id;
}
}
const { activeMerchantCoupon, defaultCoupon, usedCouponId } = await checkForAvailableCoupons({
merchantCoupon,
couponId,
productId,
courseBuilderAdapter: options.adapter
});
const usedCoupon = usedCouponId ? await options.adapter.getCoupon(usedCouponId) : null;
const productPrices = await formatPricesForProduct({
productId,
country,
quantity,
merchantCouponId: activeMerchantCoupon?.id,
...upgradeFromPurchaseId && {
upgradeFromPurchaseId
},
userId,
autoApplyPPP,
usedCouponId,
ctx: options.adapter
});
return {
body: {
...productPrices,
...defaultCoupon && {
defaultCoupon
},
...usedCoupon && {
usedCoupon,
usedCouponId
}
},
headers: {
"Content-Type": "application/json"
},
cookies
};
}
__name(getPricesFormatted, "getPricesFormatted");
export {
getPricesFormatted
};
//# sourceMappingURL=chunk-WEFCBOK6.js.map