CSR-1452 | More promo logic

Watch lineItems to automatically run revalidate when the cart changes
Add in auto add of addable vaps in beforeRouteEnter
Create adding of addableVaps to order in promo helper
This commit is contained in:
Scott Kiener 2023-11-07 15:34:31 -05:00
parent eb8ecb44e8
commit fa2bccb518
3 changed files with 75 additions and 5 deletions

View file

@ -1,6 +1,7 @@
import store from "@/store";
import { storeActions } from "@/constants/store-actions";
import { partTypeStrings } from "@/constants/part-type-strings";
import { deepClone } from "@/helpers/object-helper";
import baseMixin from "@/mixins/base-mixin.js";
export const promoPartNumberStrings = {
@ -126,6 +127,31 @@ export function getPromosThatMatchLineItemsOnOrder(promos, lineItemsOnOrder) {
return matchingPromos;
}
// Returns the vaps that the provided <promos> requires to be on the order to satisfy
// Items that are already in <lineItemsOnOrder> will not be returned
export function getVapsThatNeedToBeAddedToSatisfyPromos(
promos,
availableLineItems,
lineItemsOnOrder
) {
const clonedVaps = deepClone(lineItemsOnOrder.vaps ?? []);
const promosWithAddableVaps = getPromosWithAddableVaps(promos);
if (promosWithAddableVaps.length) {
const matchingLineItems = getLineItemsThatMatchPromos(
promosWithAddableVaps,
availableLineItems
);
// Check if matching items are already in the order
const idsOfVapsAlreadyInOrder = clonedVaps.map((lineItem) => lineItem.id);
const vapsToAddToCart = matchingLineItems.filter(
(lineItem) => !idsOfVapsAlreadyInOrder.includes(lineItem.id)
);
return vapsToAddToCart;
} else {
return [];
}
}
export function shouldStripPromoQueryString(fmgPageQueryValue) {
return pagesToStripPromoQueryStringFrom.includes(fmgPageQueryValue);
}

View file

@ -97,7 +97,11 @@ export default {
this.$refs[modalName].closeModal();
},
addRainDefenseToCart(modalName, part) {
this.currentCartItems.vaps.push(part);
// Clone vaps array, then replace this.currentCartItems.vaps with it at the end
// in order to successfully trigger parent's watcher
const clonedVaps = this.currentCartItems.vaps.slice(0);
clonedVaps.push(part);
this.currentCartItems.vaps = clonedVaps;
this.closeModal(modalName);
const message = this.getRainDefenseAddedMessage();
this.$emit("added-to-cart", {
@ -133,19 +137,23 @@ export default {
this.selectedWipers = ["REAR"];
}
}
// Clone vaps array, then replace this.currentCartItems.vaps with it at the end
// in order to successfully trigger parent's watcher
const clonedVaps = this.currentCartItems.vaps.slice(0);
itemsForCart.forEach((type) => {
if (type === wipersOfferedStrings.FRONT) {
part.frontWiperLineItems.forEach((part) => {
this.currentCartItems.vaps.push(part);
clonedVaps.push(part);
});
}
if (type === wipersOfferedStrings.REAR) {
part.rearWiperLineItems.forEach((part) => {
this.currentCartItems.vaps.push(part);
clonedVaps.push(part);
});
}
});
this.currentCartItems.vaps = clonedVaps;
this.closeModal(modalName);

View file

@ -88,7 +88,8 @@ import { paymentMethods } from "@/constants/payment-method-constants";
import { experimentSettings } from "@/constants/experiments";
import {
revalidatePromosAndValidateNewPromo,
getAddableVapsFromAvailableLineItems,
getPromosWithAddableVaps,
getVapsThatNeedToBeAddedToSatisfyPromos,
} from "@/helpers/promotions-helper";
import { queryStrings } from "@/constants/query-strings";
import { getQuerystringParameter } from "@/helpers/querystring-helper";
@ -177,7 +178,9 @@ export default {
"payment-method"
);
availableLineItems.push(...(validatePromoResponse?.orderPromos ?? []));
const newValidatedPromos = validatePromoResponse?.orderPromos ?? [];
availableLineItems.push(...newValidatedPromos);
// End of promo logic
const taxedAvailableLineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
@ -201,6 +204,15 @@ export default {
availableLineItems,
lineItemsFromStore
);
// Add items that were not in the store yet but added via query string promo validation
lineItems.promos = lineItems.promos ?? [];
lineItems.promos.push(...newValidatedPromos);
const vapsToAddToCart = getVapsThatNeedToBeAddedToSatisfyPromos(
newValidatedPromos,
availableLineItems,
lineItems
);
lineItems.vaps.push(...vapsToAddToCart);
// Call the "next" function to complete the transition to this page.
next((vm) => {
@ -412,11 +424,35 @@ export default {
shouldDisplayPiaAlert() {
return this.$route.params[this.routerParams.DISPLAY_PIA_ALERT];
},
// Necessary to make the watcher of lineItems work
// JavaScript does not keep a record of the old value, only a reference to it's location in the memory.
// This creates a separate location for oldValue/newValue so they can be compared
// See Vue github issue #2164
lineItemsCloneForWatcher() {
return Object.assign({}, this.lineItems);
},
},
watch: {
customCtaCopy(newValue) {
this.updateFooterButtonText(newValue);
},
lineItemsCloneForWatcher: {
handler(newValue, oldValue) {
if (
!oldValue ||
oldValue.length == 0 ||
!oldValue.vaps ||
!newValue ||
newValue.length == 0
) {
return;
}
if (oldValue.vaps.length != newValue.vaps.length) {
this.revalidatePromos();
}
},
deep: true,
},
},
components: {
funnelHeader,