window._ABConfig.getProductDiscountedPricing = ({ variantId, amount, quantity, sellingPlanId }) => {
console.log("Executed DiscountBundlesByBundleType");
if (!variantId) {
console.error('Please provide a current variant id');
return [];
}
//helper functions
const isDiscountUsageLimitExceed = (customerDiscountUsage, bundle) => {
if (customerDiscountUsage && customerDiscountUsage.length) {
const targetDiscountUsage = customerDiscountUsage.find(
(discountUsage) => discountUsage?.uniqueRef === bundle?.uniqueRef
);
return targetDiscountUsage && targetDiscountUsage?.usageCount >= bundle?.limitToUsePerCustomer;
}
return false;
};
const isBundleRestrictedCustomerByTagsByDiscount = (item, customerTags) => {
if (!item?.restrictTags) return false;
const restrictTags = item?.restrictTags?.split(',');
return customerTags && customerTags.length > 0 && customerTags.some((tag) => restrictTags?.includes(tag));
};
const isBundleAllowedByCustomersTagByDiscount = (item, customerTags) => {
if (!item?.allowedTags) return true;
const allowedCustomersOnly = item?.allowedTags?.split(',');
return (
customerTags &&
customerTags.length > 0 &&
customerTags.some((tag) => allowedCustomersOnly?.includes(tag))
);
};
const isBundleRestrictedByDiscount = (item, customerTags) => {
return isBundleRestrictedCustomerByTagsByDiscount(item, customerTags) || !isBundleAllowedByCustomersTagByDiscount(item, customerTags);
};
const processBundleRules = (bundles, type, fields) =>
bundles
.filter((bundle) => bundle?.bundleType === type)
.map((rule) => {
const parsedRule = { ...rule };
fields.forEach((field) => {
parsedRule[field] = JSON.parse(rule[field]);
});
return parsedRule;
});
const getBestDiscount = (applicableDiscounts, lineItem, discountKey = 'discount') => {
return applicableDiscounts.reduce((greater, current) => {
const greaterDiscount = greater?.[discountKey];
const currentDiscount = current?.[discountKey];
if ((greater?.discountType === "PERCENTAGE" && current?.discountType === "PERCENTAGE") ||
(greater?.discountType === "FIXED_AMOUNT" && current?.discountType === "FIXED_AMOUNT")) {
return currentDiscount > greaterDiscount ? current : greater;
} else if (current?.discountType === "FIXED_AMOUNT" && greater?.discountType === "PERCENTAGE") {
return currentDiscount > ((greaterDiscount / 100) * lineItem?.totalAmount) ? current : greater;
} else if (current?.discountType === "PERCENTAGE" && greater?.discountType === "FIXED_AMOUNT") {
return ((currentDiscount / 100) * lineItem?.totalAmount) > greaterDiscount ? current : greater;
}
return currentDiscount > greaterDiscount ? current : greater;
});
};
const getApplicableTieredDiscount = (volumeDiscountBundles, lineItem) => {
let applicableDiscount = null;
const updatedVolumeDiscountBundles = volumeDiscountBundles.map(bundle => {
const updatedTieredDiscount = bundle?.tieredDiscount.map(discount => {
return {
...discount,
appliesOn: bundle?.appliesOn
};
})
return {
...bundle,
tieredDiscount: updatedTieredDiscount
}
});
const volumeDiscountBundlesTieredDiscount = updatedVolumeDiscountBundles.reduce((acc, item) => {
return acc.concat(item?.tieredDiscount);
}, []);
let applicableQuantityBasedDiscount = volumeDiscountBundlesTieredDiscount
.filter(tieredDiscount => tieredDiscount?.discountBasedOn === "QUANTITY")
.filter(tieredDiscount => lineItem?.quantity >= tieredDiscount?.value);
applicableQuantityBasedDiscount = applicableQuantityBasedDiscount.length > 0 ? getBestDiscount(applicableQuantityBasedDiscount, lineItem) : null;
let applicableSpendAmountBasedDiscount = volumeDiscountBundlesTieredDiscount
.filter(tieredDiscount => tieredDiscount?.discountBasedOn === "AMOUNT")
.filter(tieredDiscount => lineItem?.totalAmount >= tieredDiscount?.value);
applicableSpendAmountBasedDiscount = applicableSpendAmountBasedDiscount.length > 0 ? getBestDiscount(applicableSpendAmountBasedDiscount, lineItem, ) : null;
if (applicableQuantityBasedDiscount && applicableSpendAmountBasedDiscount) {
if ((applicableQuantityBasedDiscount?.discountType === "PERCENTAGE" && applicableSpendAmountBasedDiscount?.discountType === "PERCENTAGE") || (applicableQuantityBasedDiscount?.discountType === "FIXED_AMOUNT" && applicableSpendAmountBasedDiscount?.discountType === "FIXED_AMOUNT")) {
if (applicableQuantityBasedDiscount?.discount > applicableSpendAmountBasedDiscount?.discount) {
applicableDiscount = applicableQuantityBasedDiscount;
} else {
applicableDiscount = applicableSpendAmountBasedDiscount;
}
}else if(applicableQuantityBasedDiscount?.discountType === "PERCENTAGE" && applicableSpendAmountBasedDiscount?.discountType === "FIXED_AMOUNT"){
if (((applicableQuantityBasedDiscount?.discount / 100) * lineItem?.totalAmount) > applicableSpendAmountBasedDiscount?.discount) {
applicableDiscount = applicableQuantityBasedDiscount;
} else {
applicableDiscount = applicableSpendAmountBasedDiscount;
}
}else if(applicableQuantityBasedDiscount?.discountType === "FIXED_AMOUNT" && applicableSpendAmountBasedDiscount?.discountType === "PERCENTAGE"){
if (applicableQuantityBasedDiscount?.discount > ((applicableSpendAmountBasedDiscount?.discount / 100) * lineItem?.totalAmount)) {
applicableDiscount = applicableQuantityBasedDiscount;
} else {
applicableDiscount = applicableSpendAmountBasedDiscount;
}
}
} else if (applicableQuantityBasedDiscount) {
applicableDiscount = applicableQuantityBasedDiscount;
} else if (applicableSpendAmountBasedDiscount) {
applicableDiscount = applicableSpendAmountBasedDiscount;
}
return applicableDiscount;
}
const getApplicablePercentOrFixedDiscount = (discountedPricingBundles, lineItem) => {
let applicableDiscount = null;
let applicableQuantityBasedDiscount = discountedPricingBundles
.map(bundle => {
return {
...bundle,
minProductCount: bundle?.minProductCount || 0,
maxProductCount: bundle?.maxProductCount || 0,
minOrderAmount: bundle?.minOrderAmount || 0
};
})
.filter(bundle => {
const minCount = bundle.minProductCount;
const maxCount = bundle.maxProductCount;
const minAmount = bundle.minOrderAmount;
if (minCount > 0 && lineItem.quantity < minCount) return false;
if (maxCount > 0 && lineItem.quantity > maxCount) return false;
if (minAmount > 0 && lineItem.amount < minAmount) return false;
return true;
});
applicableDiscount = applicableQuantityBasedDiscount.length > 0 ? getBestDiscount(applicableQuantityBasedDiscount, lineItem, 'discountValue') : null;
if(applicableDiscount){
applicableDiscount = {
discountBasedOn: applicableDiscount?.minOrderAmount > 0 && applicableDiscount?.minProductCount === 0 ? "AMOUNT" : "QUANTITY",
value: applicableDiscount?.minOrderAmount > 0 && applicableDiscount?.minProductCount === 0 ? lineItem?.totalAmount : lineItem?.quantity,
discount: applicableDiscount?.discountValue,
discountType: applicableDiscount?.discountType,
appliesOn: applicableDiscount?.appliesOn
}
}
return applicableDiscount;
}
const discountBundles = [{"id":12174,"shop":"conquest-maps.myshopify.com","name":"15% Off Everything for Compass Club Members!","description":"15% Off Everything for Compass Club Members!","status":"ACTIVE","customerIncludeTags":null,"discountType":"PERCENTAGE","discountValue":15.0,"products":"null","variants":"null","sequenceNo":null,"bundleType":"DISCOUNTED_PRICING","settings":null,"bundleProductId":null,"bundleVariantId":null,"productHandle":null,"discountId":null,"price":null,"numberOfProducts":0,"subscriptionBundlingEnabled":false,"subscriptionId":null,"minProductCount":null,"maxProductCount":null,"uniqueRef":"GOoBr6pXjJ","bundleRedirect":"CART","customRedirectURL":null,"minOrderAmount":null,"tieredDiscount":null,"productViewStyle":"QUICK_ADD","singleProductSettings":"null","trackInventory":false,"sellingPlanType":"BUNDLE_LEVEL","clearCart":"ENABLED","minPrice":null,"maxPrice":null,"externalBuildABoxId":null,"variantVisibilityType":"SHOW_VARIANTS_AS_INDIVIDUAL","subTitle":null,"freeShipping":false,"themeType":"THEME_TWO","showBundleInProductPage":true,"combinedWithProductDiscount":true,"combinedWithShippingDiscount":true,"combinedWithOrderDiscount":true,"allowedTags":"compass-club,compass-club-renew,compass-club-monthly-founding-member-intro,compass-club-monthly-founding-member-permanent,Compass Club Admin,compass-club-monthly-membership,compass-club-annual-membership,compass-club-annual-founding-membership","restrictTags":null,"selectionType":"FLEXIBLE","bundleHtml":"null","discountedVariants":"null","allowedCountries":null,"appliesOn":"ONE_TIME","purchaseRequirement":"NO_REQUIREMENT","productDiscountType":"EACH_PRODUCT","countrySelectionType":"ALL_COUNTRY","discountApplyApproach":"SHOPIFY_DISCOUNT_FUNCTION","discountedProductChooseType":"CHOOSE_ALL","internalName":"Compass Club Member 15% Off","sections":"[{\"id\":1,\"name\":\"\",\"description\":\"\",\"minProductCount\":0,\"maxProductCount\":0,\"variants\":[]}]","limitToUsePerCustomer":null,"discountedVariantSelectionLimit":null,"hideOneTimePurchase":false,"hideSubscriptionPurchase":false,"maxOrderAmount":null,"collectionData":"[{\"id\":265735012455,\"title\":\"Products on Sale\",\"handle\":\"products-on-sale\",\"image\":null},{\"id\":263153090663,\"title\":\"Products not on Sale\",\"handle\":\"products-not-on-sale\",\"image\":null}]","productSelectionType":"COLLECTION","tag":"Compass-Club-15-Off","productChooseType":null,"variantSelectionLimit":null}];
const customerTags = null;
let customerDiscountUsage = [];
let isLoggedIn = false;
const filteredDiscountBundles = Array.isArray(discountBundles) && discountBundles.length > 0 && discountBundles?.filter((bundle) => {
if (bundle?.status !== 'ACTIVE') {
return false;
}
if ((bundle?.allowedTags || bundle?.restrictTags || bundle?.limitToUsePerCustomer > 0) && !isLoggedIn) {
return false;
}
if ((bundle?.allowedTags || bundle?.restrictTags) && isLoggedIn && isBundleRestrictedByDiscount(bundle, customerTags)) {
return false;
}
if (bundle?.limitToUsePerCustomer > 0 && isDiscountUsageLimitExceed(customerDiscountUsage, bundle)) {
return false;
}
if (bundle?.appliesOn === "ONE_TIME" && sellingPlanId != null) {
return false;
}
if (bundle?.appliesOn === "SUBSCRIPTION" && sellingPlanId === null) {
return false;
}
try {
const variants = JSON.parse(bundle?.variants || '[]');
return variants.some((variant) => parseInt(variant?.variantId) === parseInt(variantId));
} catch (e) {
console.error('Failed to parse JSON:', e);
return false;
}
}) || [];
const totalAmount = amount * quantity;
const lineItem = {variantId, quantity, amount, totalAmount };
const volumeDiscountBundles = processBundleRules(filteredDiscountBundles, 'VOLUME_DISCOUNT', ["variants", "tieredDiscount"]);
const discountedPricingBundles = processBundleRules(filteredDiscountBundles, 'DISCOUNTED_PRICING', ["variants"]);
let applicableDiscount = null;
const volumeDiscount = getApplicableTieredDiscount(volumeDiscountBundles, lineItem);
const pricingDiscount = getApplicablePercentOrFixedDiscount(discountedPricingBundles, lineItem);
if (volumeDiscount && pricingDiscount) {
applicableDiscount = getBestDiscount([volumeDiscount, pricingDiscount], lineItem);
} else {
applicableDiscount = volumeDiscount || pricingDiscount;
}
const discountAmount = applicableDiscount?.discountType === "PERCENTAGE" ? (totalAmount * applicableDiscount?.discount) / 100 : applicableDiscount?.discount;
const discountedPrice = applicableDiscount?.discountType === "PERCENTAGE" ? (totalAmount - discountAmount) : ( totalAmount - applicableDiscount?.discount);
return {
variantId,
quantity,
amount,
totalAmount,
discountType: applicableDiscount?.discountType,
discountValue: applicableDiscount?.discount,
discountAmount,
discountedPrice: !isNaN(discountedPrice) ? discountedPrice : undefined,
discountConfigure: applicableDiscount?.appliesOn
};
};