From e54ead578e532059944a1632ff85bc58cb4f4c22 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 5 Sep 2024 17:02:15 -0400 Subject: [PATCH 01/96] Add call to recal endpoint --- src/constants/endpoints.js | 4 +++ src/constants/store-actions.js | 1 + src/mixins/vehicle-questions-mixin.js | 12 +++++++- src/store/index.js | 40 +++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 43abf149c..2b5c654e5 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -84,6 +84,10 @@ const endpoints = { url: "/parts/api/v1/parts/supporting-items", method: "POST", }, + GetRecalPart: { + url: "/parts/api/v1/parts/recal-parts", + method: "GET", + }, GetAlertReasons: { url: "/location/api/v1/location/alert-reasons", method: "GET", diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 069079d35..f5c7ea047 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -53,6 +53,7 @@ const storeActions = { VALIDATE_ORDER_PROMO_AND_SAVE_SERVER_DATA: "validateOrderPromoAndSaveServerData", REVALIDATE_ORDER_PROMOS_AND_SAVE_SERVER_DATA: "revalidateOrderPromosAndSaveServerData", GET_INSURANCE_COMPANY_LIST: "getInsuranceCompanyList", + GET_RECAL_PARTS_AND_SAVE_TO_LINE_ITEMS: "getRecalPartsAndSaveToLineItems", // DEPENDENCY MUTATIONS RESET_DAMAGE_STATE_AND_DEPENDENCIES: "resetDamageAndDependencies", diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 2749d1933..517fc7c90 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -450,7 +450,17 @@ export default { const collectedGlassParts = this.reducedGlassPartsArray(partsOrQuestions); // save to store lineItems.glassParts - self.dispatchStoreAction(storeActions.SAVE_GLASS_PARTS, collectedGlassParts, false); + await self.dispatchStoreAction( + storeActions.SAVE_GLASS_PARTS, + collectedGlassParts, + false + ); + + await self.dispatchStoreActionWithLogging( + storeActions.GET_RECAL_PARTS_AND_SAVE_TO_LINE_ITEMS, + null, + currentPage + ); const payment = store.getters.payment; diff --git a/src/store/index.js b/src/store/index.js index aa5747a0f..a74a52623 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2855,6 +2855,46 @@ export const actions = { externalParameterMMS.externalParameterStyle ); }, + + async getRecalPartsAndSaveToLineItems(context, { pageNameToLog }) { + // identify each part that needs recal + const glassParts = context.state.order?.lineItems?.glassParts ?? []; + + for (let i = 0; i < glassParts.length; i++) { + // does this part need recal? + const needsRecal = + !!glassParts[i].requiresRecalibration && !!glassParts[i].recalibrationType; + + if (needsRecal) { + const recalType = glassParts[i].recalibrationType; + const parentAccountNumber = + context.state.order.payment.parentAccountNumber ?? + applicationConfig.CASH_PARENT_ACCOUNT_NUMBER; + + // Get part from API + const urlExtension = `${context.state.order.vehicle.carId}/${glassParts[i].partNumber}/${recalType}/${parentAccountNumber}/${context.state.order.serviceLocation.zipCode}/${applicationConfig.ANALYTICS_APPLICATION_NAME}/${context.state.order.referralSequenceNumber}`; + + const recalPartResponse = await globalMethods.callHttpClient({ + method: endpoints.GetRecalPart.method, + endpoint: `${endpoints.GetRecalPart.url}/${urlExtension}`, + payload: {}, + pageNameToLog: pageNameToLog, + }); + + // If any parts retrieved, add as children to the glass part. + if ( + recalPartResponse.status === 200 && + recalPartResponse.data.recalibrationParts?.length > 0 + ) { + if (!glassParts[i].childParts) { + glassParts[i].childParts = []; + } + + glassParts[i].childParts.push(...recalPartResponse.data.recalibrationParts); + } + } + } + }, }; export default createStore({ From 6f3e35388b7c7b2dfc434d59a80895d71201f5d5 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 12 Sep 2024 09:52:39 -0400 Subject: [PATCH 02/96] Create helper files --- src/constants/part-type-strings.js | 1 + src/helpers/recal-helper.js | 39 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/helpers/recal-helper.js diff --git a/src/constants/part-type-strings.js b/src/constants/part-type-strings.js index 3ad66c40a..4681e2776 100644 --- a/src/constants/part-type-strings.js +++ b/src/constants/part-type-strings.js @@ -2,6 +2,7 @@ const partTypeStrings = { FRONT_WIPER: "FRONT WIPER", REAR_WIPER: "REAR WIPER", RAIN_DEFENSE: "RAIN DEFENSE", + ADAS_RECALIBRATION: "ADAS RECALIBRATION", RECALIBRATION: "RECALIBRATION", REPLACE_FEE: "REPLACE FEE", RECYCLE_FEE: "RECYCLE FEE", diff --git a/src/helpers/recal-helper.js b/src/helpers/recal-helper.js new file mode 100644 index 000000000..d6b1d044f --- /dev/null +++ b/src/helpers/recal-helper.js @@ -0,0 +1,39 @@ +import { deepClone } from "@/helpers/object-helper"; +import { partTypeStrings } from "@/constants/part-type-strings"; + +const recalPartTypes = [partTypeStrings.RECALIBRATION, partTypeStrings.ADAS_RECALIBRATION]; + +export function isRecalPartOrHasChildRecalPart(lineItem) { + if (lineItem.childParts && lineItem.childParts.length > 0) { + return isRecalPart(lineItem) || containsRecalParts(lineItem.childParts); + } else { + return isRecalPart(lineItem); + } +} + +export function isRecalPart(lineItem) { + return recalPartTypes.some((type) => lineItem.partType === type); +} + +export function containsRecalParts(lineItems) { + if (!lineItems) { + return false; + } + return lineItems.some((li) => isRecalPartOrHasChildRecalPart(li)); +} + +export function getItemsWithoutRecalParts(lineItems) { + const copy = deepClone(lineItems); + + const firstLevelFiltered = copy.filter((li) => !isRecalPart(li)); + + const childrenFiltered = firstLevelFiltered.map((li) => { + if (li.childParts && li.childParts.length > 0) { + li.childParts = getItemsWithoutRecalParts(li.childParts); + } + + return li; + }); + + return childrenFiltered; +} From 51fb83932d38a84b0a29faa63f4f23c1d696e34f Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 12 Sep 2024 12:28:32 -0400 Subject: [PATCH 03/96] Update `containsRecalPart` to accept both lineitems formats --- src/helpers/recal-helper.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/helpers/recal-helper.js b/src/helpers/recal-helper.js index d6b1d044f..fa33e7849 100644 --- a/src/helpers/recal-helper.js +++ b/src/helpers/recal-helper.js @@ -19,7 +19,20 @@ export function containsRecalParts(lineItems) { if (!lineItems) { return false; } - return lineItems.some((li) => isRecalPartOrHasChildRecalPart(li)); + + if (Array.isArray(lineItems)) { + return lineItems.some((li) => isRecalPartOrHasChildRecalPart(li)); + } else { + // complex object form -- flatten and re-call. + const flattened = [ + ...(lineItems.glassParts ?? []), + ...(lineItems.supportingItems ?? []), + ...(lineItems.vaps ?? []), + ...(lineItems.promos ?? []), + ]; + + return flattened.some((li) => isRecalPartOrHasChildRecalPart(li)); + } } export function getItemsWithoutRecalParts(lineItems) { From e29248a7ed0b65c207a25c4ede65fd96b542b0e3 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 12 Sep 2024 12:29:22 -0400 Subject: [PATCH 04/96] Update quote to use new parts --- src/layouts/quote/quote.vue | 19 +++++++++---------- .../service-package-question.vue | 13 +++++-------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 3d539e630..c0e6165ea 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -30,6 +30,7 @@ insuranceCmsWidgetName="InsuranceServicePackageQuestionWidget" groupName="ServicePackageQuestion" :availableLineItems="availableLineItems" + :shouldHideRecalibration="shouldHideRecalibration" :isInsuranceSelected="isInsuranceSelected" @vapsItemsSelected="vapsItemsSelectedAction" @servicePackageDiscountSelected="servicePackageDiscountSelectedAction" @@ -131,6 +132,7 @@ import { containsLineItemWithPartType } from "@/helpers/service-package-helper"; import { nextTick } from "vue"; import { packageNames } from "@/constants/package-names"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; +import { containsRecalParts } from "@/helpers/recal-helper"; defineRule("option-required", required(errorMessages.OPTION_REQUIRED)); export default { @@ -209,10 +211,7 @@ export default { ]; // If the recal experiment is found then log the experiment exposure. - const isRecalibrationOnOrder = containsLineItemWithPartType( - partTypeStrings.RECALIBRATION, - availableLineItems - ); + const isRecalibrationOnOrder = containsRecalParts(availableLineItems); const canSafeliteRecalibrate = nullSafeGlassParts.some((glassPart) => { return glassPart.partType === "WINDSHIELD" && glassPart.canSafeliteRecalibrate; }); @@ -354,10 +353,7 @@ export default { return Object.assign({}, this.lineItems); }, isRecalibrationOnOrder() { - return containsLineItemWithPartType( - partTypeStrings.RECALIBRATION, - this?.availableLineItems - ); + return containsRecalParts(this.lineItems); }, shouldHideRecalibration() { const recalSettingValue = experimentMixin.methods.getSettingValue( @@ -366,10 +362,13 @@ export default { return recalSettingValue; }, showAfterpayBanner() { - return !this.isInsuranceSelected && (!this.isRecalibrationOnOrder || !this.shouldHideRecalibration) + return ( + !this.isInsuranceSelected && + (!this.isRecalibrationOnOrder || !this.shouldHideRecalibration) + ); }, showRecalDisclaimer() { - return this.isRecalibrationOnOrder && this.shouldHideRecalibration + return this.isRecalibrationOnOrder && this.shouldHideRecalibration; }, }, methods: { diff --git a/src/layouts/quote/service-package-question/service-package-question.vue b/src/layouts/quote/service-package-question/service-package-question.vue index 93d8ff79b..f17fe908a 100644 --- a/src/layouts/quote/service-package-question/service-package-question.vue +++ b/src/layouts/quote/service-package-question/service-package-question.vue @@ -36,6 +36,7 @@ import { getPromosWithAddableVaps, getLineItemsThatMatchPromos, } from "@/helpers/promotions-helper"; +import { containsRecalParts, getItemsWithoutRecalParts } from "@/helpers/recal-helper"; export default { name: "servicePackageQuestion", @@ -49,6 +50,7 @@ export default { availableLineItems: null, activePromos: null, servicePackage: null, + shouldHideRecalibration: Boolean, }, data() { return { @@ -142,10 +144,7 @@ export default { return modifiedAnswers; }, isRecalibrationOnOrder() { - return containsLineItemWithPartType( - partTypeStrings.RECALIBRATION, - this.nullSafeAvailableLineItems - ); + return containsRecalParts(this.nullSafeAvailableLineItems); }, isServicePackageDiscountOnOrder() { return containsLineItemWithPartType( @@ -242,10 +241,8 @@ export default { }, getPackagePrice(packageName, { discountedPrice = false, servicePackageDiscount = false }) { var lineItemsToPrice = [...this.nullSafeAvailableLineItems]; - if (this.isRecalibrationOnOrder) { - lineItemsToPrice = lineItemsToPrice.filter((item) => { - return item.partType != partTypeStrings.RECALIBRATION; - }); + if (this.shouldHideRecalibration && this.isRecalibrationOnOrder) { + lineItemsToPrice = getItemsWithoutRecalParts(lineItemsToPrice); } //remove service package discount part From e30f2631e5952411f9c842728c48872acbf7674f Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 17 Sep 2024 13:23:19 -0400 Subject: [PATCH 05/96] Merge issue --- src/layouts/quote/quote.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 599ba0f6a..c6176ff9d 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -30,7 +30,6 @@ insuranceCmsWidgetName="InsuranceServicePackageQuestionWidget" groupName="ServicePackageQuestion" :availableLineItems="availableLineItems" - :shouldHideRecalibration="shouldHideRecalibration" :isInsuranceSelected="isInsuranceSelected" :isRecalibrationOnOrder="isRecalibrationOnOrder" :shouldHideRecalibration="shouldHideRecalibration" From 1dde9eb6f7e50fe2f92579c29227c9a1f0bc4b35 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 17 Sep 2024 13:45:32 -0400 Subject: [PATCH 06/96] Update store getters for recal --- src/store/index.js | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index c95366add..b0037bc61 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -39,6 +39,7 @@ import { coverageType, coverageTypeValue, } from "@/constants/insurance"; +import { containsRecalParts } from "@/helpers/recal-helper"; // Export State const getDefaultState = () => { @@ -2421,8 +2422,9 @@ export const actions = { })); const order = context.getters.order; - - var providerNumber = order.serviceLocation?.provider?.providerNumber ?? order.serviceLocation?.zipCodeCtu; + + var providerNumber = + order.serviceLocation?.provider?.providerNumber ?? order.serviceLocation?.zipCodeCtu; if (providerNumber.startsWith("00")) { providerNumber = providerNumber.substring(1); } @@ -2912,34 +2914,7 @@ export default createStore({ // Private Functions function getHasRecalibrationPart(state) { - var hasRequiresRecalibration = - getNonFalseValuesOfPropertyInArrayOfObjects( - state.order.lineItems.glassParts, - "requiresRecalibration" - )?.length > 0; - var hasRecalibrationType = - getNonFalseValuesOfPropertyInArrayOfObjects( - state.order.lineItems.glassParts, - "recalibrationType" - )?.length > 0; - - if (hasRequiresRecalibration) { - if (hasRecalibrationType) { - // Has both 'requiresRecalibration' and 'recalibrationType' and 'recalibrationType' - return ( - getNonFalseValuesOfPropertyInArrayOfObjects( - state.order.lineItems.glassParts, - "recalibrationType" - )[0].toLowerCase() != "unknown" - ); - } else { - // Has 'requiresRecalibration' but no 'recalibrationType' at all - return true; - } - } else { - // Does not have 'requiresRecalibration' - return false; - } + return containsRecalParts(state.order.lineItems); } function sortArrayOfObjectsByPropertyValue(arrayOfObjects, propertyName) { From 51655e7247d73f704aae148f5eb4223099453296 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 17 Sep 2024 14:23:55 -0400 Subject: [PATCH 07/96] Update payment-method & cart for new recal --- src/fmg-components/cart/cart.vue | 4 ++-- src/layouts/payment-method/payment-method.vue | 10 ++++++---- src/mixins/base-mixin.js | 6 ++---- src/store/index.js | 5 +++-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue index 90c1adf98..0dffbd6de 100644 --- a/src/fmg-components/cart/cart.vue +++ b/src/fmg-components/cart/cart.vue @@ -305,8 +305,8 @@ export default { if (!this.lineItems || this.lineItems.length < 1) return; const lineItemsCopy = deepClone(this.lineItems); - lineItemsCopy.supportingItems = lineItemsCopy.supportingItems - ? baseMixin.methods.filterOutRecalibration(lineItemsCopy?.supportingItems) + lineItemsCopy.glassParts = lineItemsCopy.glassParts + ? baseMixin.methods.filterOutRecalibration(lineItemsCopy?.glassParts) : []; return lineItemsCopy; }, diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index ff7e6a8d8..2c458e124 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -153,6 +153,7 @@ import { partTypeStrings } from "@/constants/part-type-strings"; import { mapTaxedLineItemsToStoreFormat } from "../../store"; import { coverageStatus } from "@/constants/insurance"; import { containsLineItemWithPartType } from "@/helpers/service-package-helper"; +import { containsRecalParts } from "@/helpers/recal-helper"; defineRule("payment-method-required", required(errorMessages.OPTION_REQUIRED)); defineRule("recal-ack-required", required(errorMessages.RECAL_ACK_REQUIRED)); @@ -588,10 +589,11 @@ export default { }, computed: { isRecalibrationOnOrder() { - return containsLineItemWithPartType( - partTypeStrings.RECALIBRATION, - this.$store.getters.order.lineItems?.supportingItems - ); + const order = baseMixin.methods.hasSubmittedOrder() + ? baseMixin.methods.getSubmittedOrder() + : this.$store.getters.order; + + return containsRecalParts(order.lineItems); }, shouldHideRecalibration() { return this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE); diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index c1e60d16a..669e3306f 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -8,6 +8,7 @@ import { queryStrings } from "@/constants/query-strings"; import { dynamicStrings } from "@/constants/dynamic-strings"; import { partTypeStrings } from "../constants/part-type-strings"; import { showFmgLoadingModal } from "@/helpers/loading-modal-helper"; +import { getItemsWithoutRecalParts } from "@/helpers/recal-helper"; export default { data() { @@ -103,10 +104,7 @@ export default { return filteredLineItems; }, filterOutRecalibration(lineItems) { - const filteredLineItems = lineItems.filter((item) => { - return !item.partType.includes(partTypeStrings.RECALIBRATION); - }); - return filteredLineItems; + return getItemsWithoutRecalParts(lineItems); }, getTotalPriceOfAllLineItemsAndChildParts(lineItems, includeTax) { let totalPrice = 0; diff --git a/src/store/index.js b/src/store/index.js index 8a87018d6..f6751bcef 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2422,8 +2422,9 @@ export const actions = { })); const order = context.getters.order; - - var providerNumber = order.serviceLocation?.provider?.providerNumber ?? order.serviceLocation?.zipCodeCtu; + + var providerNumber = + order.serviceLocation?.provider?.providerNumber ?? order.serviceLocation?.zipCodeCtu; if (providerNumber.startsWith("00") && providerNumber.length > 5) { providerNumber = providerNumber.substring(1); } From daf9ecba0de30af4124effdd53b58655dc496bf3 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Thu, 26 Sep 2024 11:59:28 -0400 Subject: [PATCH 08/96] CSR-1600 CSR-1600 new endpoint from mule for applicable fees --- src/store/index.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index 89d0db2a3..1b48e3252 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1537,9 +1537,30 @@ export const actions = { ? context.getters.payment.billToAccountNumber : applicationConfig.CASH_DEFAULT_BILL_TO_ACCOUNT_NUMBER; + const order = context.getters.order; + const coverageStatus = order.payment?.insuranceCoverage?.coverageStatus; + const coverageSubStatus = order.payment?.insuranceCoverage?.coverageSubStatus; + const isItac = order.policy?.isItac ?? false; + const zipCode = order.serviceLocation?.provider?.address?.zipCode ?? order.serviceLocation?.zipCode; + + var providerNumber = + order.serviceLocation?.provider?.providerNumber ?? order.serviceLocation?.zipCodeCtu; + if (providerNumber.startsWith("00") && providerNumber.length > 5) { + providerNumber = providerNumber.substring(1); + } + + var endPoint = `${endpoints.GetMobileFeePart.url}/?damageType=${damageType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItac=${isItac}&zipCode=${zipCode}`; + if (coverageStatus) { + endPoint = `${endPoint}&coverageStatus=${coverageStatus}`; + } + + if (coverageSubStatus) { + endPoint = `${endPoint}&coverageSubStatus=${coverageSubStatus}`; + } + return globalMethods.callHttpClient({ method: endpoints.GetMobileFeePart.method, - endpoint: `${endpoints.GetMobileFeePart.url}/${damageType}/${parentAccountNumber}/${billToAccountNumber}`, + endpoint: endPoint, logApiCall: true, pageNameToLog: pageNameToLog, }); From feab3c5c54c32db022e42b811f785a252dee6114 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Thu, 26 Sep 2024 12:03:35 -0400 Subject: [PATCH 09/96] CSR-1600 prettier CSR-1600 prettier --- src/layouts/quote/quote.vue | 7 +------ src/store/index.js | 13 +++++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 8aedcc754..78ce15fa4 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -611,12 +611,7 @@ export default { }); eventLabel = eventLabel.slice(0, -1); - this.pushEventToGA( - "quote", - this.GaActions.SERVICE_PACKAGE_PRICE, - eventLabel, - true - ); + this.pushEventToGA("quote", this.GaActions.SERVICE_PACKAGE_PRICE, eventLabel, true); }); }, }, diff --git a/src/store/index.js b/src/store/index.js index 1b48e3252..e03e2ac16 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1541,13 +1541,14 @@ export const actions = { const coverageStatus = order.payment?.insuranceCoverage?.coverageStatus; const coverageSubStatus = order.payment?.insuranceCoverage?.coverageSubStatus; const isItac = order.policy?.isItac ?? false; - const zipCode = order.serviceLocation?.provider?.address?.zipCode ?? order.serviceLocation?.zipCode; + const zipCode = + order.serviceLocation?.provider?.address?.zipCode ?? order.serviceLocation?.zipCode; - var providerNumber = - order.serviceLocation?.provider?.providerNumber ?? order.serviceLocation?.zipCodeCtu; - if (providerNumber.startsWith("00") && providerNumber.length > 5) { - providerNumber = providerNumber.substring(1); - } + var providerNumber = + order.serviceLocation?.provider?.providerNumber ?? order.serviceLocation?.zipCodeCtu; + if (providerNumber.startsWith("00") && providerNumber.length > 5) { + providerNumber = providerNumber.substring(1); + } var endPoint = `${endpoints.GetMobileFeePart.url}/?damageType=${damageType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItac=${isItac}&zipCode=${zipCode}`; if (coverageStatus) { From b5d8d86b27258ec59395b93a0f640ba11f00195c Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Thu, 26 Sep 2024 13:44:29 -0400 Subject: [PATCH 10/96] CSR-2227 fix missing subheader copy. --- src/fmg-components/funnel-sub-header/funnel-sub-header.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fmg-components/funnel-sub-header/funnel-sub-header.vue b/src/fmg-components/funnel-sub-header/funnel-sub-header.vue index fa8aea13f..54c8aa34d 100644 --- a/src/fmg-components/funnel-sub-header/funnel-sub-header.vue +++ b/src/fmg-components/funnel-sub-header/funnel-sub-header.vue @@ -53,7 +53,7 @@ export default { return this.leftAlignHeader ? "justify-content-start" : "justify-content-center"; }, subText() { - return this.getCmsContent(this.cmsWidgetName, "HeaderSubText"); + return this.getCmsContent(this.cmsWidgetName, "SubheaderText"); }, backButtonAccessibleText() { return this.getCmsContent(this.cmsWidgetName, "BackButtonAccessibleText"); From 2419986c7ea4836e72bb14229557141854650f91 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Thu, 26 Sep 2024 15:34:10 -0400 Subject: [PATCH 11/96] CSR-1600 CSR-1600 mobile fee endpoint changes --- src/constants/insurance.js | 28 ++++++++++++++++++++++++++++ src/store/index.js | 17 ++++++++++------- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/constants/insurance.js b/src/constants/insurance.js index 1df261d63..5ab8c2572 100644 --- a/src/constants/insurance.js +++ b/src/constants/insurance.js @@ -29,6 +29,19 @@ export function coverageStatusValue(intCoverageStatus) { } } +export function coverageStatusEnum(strCoverageStatus) { + switch (strCoverageStatus) { + case coverageStatus.PENDING: + return 0; + case coverageStatus.NOCOMP: + return 1; + case coverageStatus.VERIFIED: + return 2; + default: + return null; + } +} + export const coverageType = { NONE: "None", DEDUCTIBLE: "Deductible", @@ -50,3 +63,18 @@ export function coverageTypeValue(intCoverageType) { return null; } } + +export function coverageTypeEnum(strCoverageType) { + switch (strCoverageType) { + case coverageType.NONE: + return 0; + case coverageType.DEDUCTIBLE: + return 1; + case coverageType.ITAC: + return 2; + case coverageType.NOCOMP: + return 3; + default: + return null; + } +} \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index e03e2ac16..562659bf0 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -36,8 +36,10 @@ import sharedMutations from "./vuex-shared-mutations/vuexSharedMutations"; import { coverageStatus, coverageStatusValue, + coverageStatusEnum, coverageType, coverageTypeValue, + coverageTypeEnum, } from "@/constants/insurance"; // Export State @@ -1531,16 +1533,17 @@ export const actions = { }, getMobileFeePart(context, { pageNameToLog }) { - const damageType = context.getters.damage.isRepair ? "Repair" : "Replace"; + const serviceType = context.getters.damage.isRepair ? "Repair" : "Install"; + const facilityType = "Mobile"; const parentAccountNumber = context.getters.payment.parentAccountNumber; const billToAccountNumber = context.getters.payment.billToAccountNumber ? context.getters.payment.billToAccountNumber : applicationConfig.CASH_DEFAULT_BILL_TO_ACCOUNT_NUMBER; const order = context.getters.order; - const coverageStatus = order.payment?.insuranceCoverage?.coverageStatus; - const coverageSubStatus = order.payment?.insuranceCoverage?.coverageSubStatus; - const isItac = order.policy?.isItac ?? false; + const coverageStatus = coverageStatusEnum(order.payment?.insuranceCoverage?.coverageStatus); + const coverageType = coverageTypeEnum(order.payment?.insuranceCoverage?.coverageType); + const isItacOptimized = order.policy?.isItac ?? false; const zipCode = order.serviceLocation?.provider?.address?.zipCode ?? order.serviceLocation?.zipCode; @@ -1550,13 +1553,13 @@ export const actions = { providerNumber = providerNumber.substring(1); } - var endPoint = `${endpoints.GetMobileFeePart.url}/?damageType=${damageType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItac=${isItac}&zipCode=${zipCode}`; + var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItac=${isItacOptimized}&zipCode=${zipCode}`; if (coverageStatus) { endPoint = `${endPoint}&coverageStatus=${coverageStatus}`; } - if (coverageSubStatus) { - endPoint = `${endPoint}&coverageSubStatus=${coverageSubStatus}`; + if (coverageType) { + endPoint = `${endPoint}&coverageType=${coverageType}`; } return globalMethods.callHttpClient({ From b4f402e04b50b0ec74bb798da95b78cb585364b4 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Thu, 26 Sep 2024 15:34:55 -0400 Subject: [PATCH 12/96] CSR-1600 prettier --- src/constants/insurance.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants/insurance.js b/src/constants/insurance.js index 5ab8c2572..f7550513b 100644 --- a/src/constants/insurance.js +++ b/src/constants/insurance.js @@ -77,4 +77,4 @@ export function coverageTypeEnum(strCoverageType) { default: return null; } -} \ No newline at end of file +} From fad42eba6ebdcfdb62b9b3b9c691b099d4f98863 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 26 Sep 2024 15:52:17 -0400 Subject: [PATCH 13/96] Update unit test --- src/store/store.spec.js | 104 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/src/store/store.spec.js b/src/store/store.spec.js index fb1c73f98..6c36c6c26 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -3950,6 +3950,110 @@ describe("Getters", () => { mutations.updateVaps(storeState, mockStateValues.funnelVaps); mutations.updateGlassToReplace(storeState, mockStateValues.glassToReplace); + //Assert + expect(getters.experimentOrder(storeState)).toEqual({ + funnelVehicleYear: mockStateValues.vehicleYear, + funnelVehicleMake: mockStateValues.vehicleMake, + funnelVehicleModel: mockStateValues.vehicleModel, + funnelVehicleStyle: mockStateValues.vehicleStyle, + funnelIsRepair: mockStateValues.isRepair, + funnelNumberOfChips: mockStateValues.numberOfChips, + funnelCarId: mockStateValues.carId, + funnelServiceCity: mockStateValues.serviceCity, + funnelServiceState: mockStateValues.serviceState, + funnelServiceZipCode: mockStateValues.serviceZipCode, + funnelParentAccountNumber: mockStateValues.parentAccountNumber, + funnelIsCoverageVerified: mockStateValues.isCoverageVerified, + funnelOrderPartNumbers: ["WINDSHIELDPARTNUMBER"], + funnelOrderPartTypes: ["ADAS, maybe"], + funnelHasRecalibrationPart: false, + funnelSelectedMultiGlass: false, + funnelSelectedWindshieldGlass: true, + funnelSelectedBackGlass: false, + funnelSelectedDriverSideGlass: false, + funnelSelectedPassengerSideGlass: false, + funnelProviderNumber: mockStateValues.funnelProviderNumber, + funnelReferralType: mockStateValues.funnelReferralType, + funnelServiceZipCodeCtu: mockStateValues.funnelServiceZipCodeCtu, + }); + }); + + test("Single windshield with recalibration child part > return correct experimentOrder values", () => { + // Arrange + const storeState = state; + const mockStateValues = { + vehicleYear: 1000, + vehicleMake: "CarMake", + vehicleModel: "CarModel", + vehicleStyle: "SuperCoolStyle", + isRepair: false, + numberOfChips: 0, + carId: "Gibberish", + serviceCity: "Columbus", + serviceState: "OH-IO", + serviceZipCode: 43215, + parentAccountNumber: "999999", + isCoverageVerified: false, + glassParts: [ + { + partNumber: "WINDSHIELDPARTNUMBER", + description: "This is a windshield", + recalibrationType: "ADAS, maybe", + requiresRecalibration: true, + requiresCapabilityQuestions: false, + childParts: [ + { + "partNumber": "THIRD RECAL", + "description": "Additional Static Recal", + "recalibrationType": "DUAL & RECAL THIRD & HC FUNCTION TEST & RL SENSOR", + "ribCode": "RL", + "safelitePartNumber": "THIRD RECAL", + "status": "ACTIVE", + "partType": "ADAS RECALIBRATION", + "childParts": [], + "recalibrationFees": [], + "salesTax": null + } + ], + }, + ], + otherParts: [], + glassToReplace: [ + { + glassLocation: "Windshield", + glassName: "Single", + }, + ], + funnelProviderNumber: "1", + funnelReferralType: "CASH QUOTE", + funnelServiceZipCodeCtu: "11111", + }; + + //Act + mutations.updateYear(storeState, mockStateValues.vehicleYear); + mutations.updateMake(storeState, mockStateValues.vehicleMake); + mutations.updateModel(storeState, mockStateValues.vehicleModel); + mutations.updateStyle(storeState, mockStateValues.vehicleStyle); + mutations.updateIsRepair(storeState, mockStateValues.isRepair); + mutations.updateNumberOfChips(storeState, mockStateValues.numberOfChips); + mutations.updateCarId(storeState, mockStateValues.carId); + mutations.updateServiceLocation(storeState, { + city: mockStateValues.serviceCity, + state: mockStateValues.serviceState, + zipCode: mockStateValues.serviceZipCode, + zipCodeCtu: mockStateValues.funnelServiceZipCodeCtu, + provider: { + providerNumber: mockStateValues.funnelProviderNumber, + }, + }); + mutations.updateParentAcctNumber(storeState, mockStateValues.parentAccountNumber); + mutations.updateInsuranceVerifiedStatus(storeState, mockStateValues.isCoverageVerified); + mutations.updateIsInsurance(storeState, false); + mutations.updateGlassParts(storeState, mockStateValues.glassParts); + mutations.updateSupportingItems(storeState, mockStateValues.funnelSupportingItems); + mutations.updateVaps(storeState, mockStateValues.funnelVaps); + mutations.updateGlassToReplace(storeState, mockStateValues.glassToReplace); + //Assert expect(getters.experimentOrder(storeState)).toEqual({ funnelVehicleYear: mockStateValues.vehicleYear, From 06a2d381fa6728ed5e9847fdbb81f52ca488cbbe Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Thu, 26 Sep 2024 17:34:13 -0400 Subject: [PATCH 14/96] Tweaks to dev changes --- src/layouts/confirmation/confirmation.vue | 6 ++---- src/layouts/quote/quote.vue | 12 +++--------- src/store/store.spec.js | 23 ++++++++++++----------- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 72ee038db..c7f944078 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -108,6 +108,7 @@ import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helpe import { experimentSettings } from "@/constants/experiments"; import { partTypeStrings } from "@/constants/part-type-strings"; import { containsLineItemWithPartType } from "@/helpers/service-package-helper"; +import { containsRecalParts } from "@/helpers/recal-helper.js"; export default { name: "confirmation", @@ -170,10 +171,7 @@ export default { }, computed: { isRecalibrationOnOrder() { - return containsLineItemWithPartType( - partTypeStrings.RECALIBRATION, - this?.lineItems?.supportingItems - ); + return containsRecalParts(this?.lineItems); }, shouldHideRecalibration() { return ( diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index c8e2dda02..b778116e9 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -583,9 +583,8 @@ export default { if (tier) { let lineItemsToPrice = this.availableLineItems; if (this.isRecalibrationOnOrder && this.shouldHideRecalibration) { - lineItemsToPrice = lineItemsToPrice?.filter((item) => { - return item.partType != partTypeStrings.RECALIBRATION; - }); + lineItemsToPrice = + baseMixin.methods.filterOutRecalibration(lineItemsToPrice); } if (this.isServicePackageDiscountOnOrder) { lineItemsToPrice = lineItemsToPrice?.filter((item) => { @@ -609,12 +608,7 @@ export default { }); eventLabel = eventLabel.slice(0, -1); - this.pushEventToGA( - "quote", - this.GaActions.SERVICE_PACKAGE_PRICE, - eventLabel, - true - ); + this.pushEventToGA("quote", this.GaActions.SERVICE_PACKAGE_PRICE, eventLabel, true); }); }, }, diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 6c36c6c26..9c546d3be 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -4003,17 +4003,18 @@ describe("Getters", () => { requiresCapabilityQuestions: false, childParts: [ { - "partNumber": "THIRD RECAL", - "description": "Additional Static Recal", - "recalibrationType": "DUAL & RECAL THIRD & HC FUNCTION TEST & RL SENSOR", - "ribCode": "RL", - "safelitePartNumber": "THIRD RECAL", - "status": "ACTIVE", - "partType": "ADAS RECALIBRATION", - "childParts": [], - "recalibrationFees": [], - "salesTax": null - } + partNumber: "THIRD RECAL", + description: "Additional Static Recal", + recalibrationType: + "DUAL & RECAL THIRD & HC FUNCTION TEST & RL SENSOR", + ribCode: "RL", + safelitePartNumber: "THIRD RECAL", + status: "ACTIVE", + partType: "ADAS RECALIBRATION", + childParts: [], + recalibrationFees: [], + salesTax: null, + }, ], }, ], From d8c14e77ea6491c05b380083c60e069df5f0f951 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 27 Sep 2024 13:32:37 -0400 Subject: [PATCH 15/96] CSR-1600 CSR-1600 correct name for itac flag on part service --- src/store/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index 562659bf0..00bdd486f 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1553,7 +1553,7 @@ export const actions = { providerNumber = providerNumber.substring(1); } - var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItac=${isItacOptimized}&zipCode=${zipCode}`; + var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItacOptimized=${isItacOptimized}&zipCode=${zipCode}`; if (coverageStatus) { endPoint = `${endPoint}&coverageStatus=${coverageStatus}`; } From 62d550750f19bd98f80af99accf7ff8831956bf1 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 27 Sep 2024 15:11:20 -0400 Subject: [PATCH 16/96] CSR-2237 CSR-2237 when coverage is verified, only show deductible for amount due in the cart --- src/mixins/base-mixin.js | 2 +- src/mixins/base-mixin.spec.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index c1e60d16a..15095746b 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -173,7 +173,7 @@ export default { !order.policy.isNoComp && !order.policy.isItac ) { - amountDue += order.policy.currentDeductible; + amountDue = order.policy.currentDeductible; } return ((amountDue * 100) / 100).toFixed(2); diff --git a/src/mixins/base-mixin.spec.js b/src/mixins/base-mixin.spec.js index 9a062a831..a3493910e 100644 --- a/src/mixins/base-mixin.spec.js +++ b/src/mixins/base-mixin.spec.js @@ -175,7 +175,7 @@ describe("baseMixin.js", () => { promos: [], }; - const payment = { insuranceCoverage: { isVerified: true } }; + const payment = { insuranceCoverage: { isVerified: false } }; const policy = { isNoComp: false, isItac: false, currentDeductible: 250 }; store.getters = { @@ -190,7 +190,7 @@ describe("baseMixin.js", () => { var amtDue = mixIn.methods.getAmountDue(lineItems); - expect(amtDue).toEqual("303.00"); + expect(amtDue).toEqual("53.00"); }); test("getAmountDue should function with a submitted order", () => { @@ -223,7 +223,7 @@ describe("baseMixin.js", () => { promos: [], }; - const payment = { insuranceCoverage: { isVerified: true } }; + const payment = { insuranceCoverage: { isVerified: false } }; const policy = { isNoComp: false, isItac: false, currentDeductible: 250 }; mixIn.methods.hasSubmittedOrder = jest.fn().mockReturnValue(true); @@ -240,7 +240,7 @@ describe("baseMixin.js", () => { var amtDue = mixIn.methods.getAmountDue(lineItems); - expect(amtDue).toEqual("303.00"); + expect(amtDue).toEqual("53.00"); }); test("getAmountDue for cash should sum lineitems", () => { From 8ebd0cd3060f61eaa93ad5da5ac778613470b4e6 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Sun, 29 Sep 2024 09:31:26 -0400 Subject: [PATCH 17/96] CSR-2237 CSR-2237 Added new getter that checks the 7777 and 9999 deductibles when determining if coverage is verified. Added the amount of vaps due to the amount due when using deductible/verified pricing. --- src/layouts/payment-method/payment-method.vue | 11 +++++---- src/mixins/base-mixin.js | 9 +++++-- src/store/index.js | 24 ++++++++++++++++--- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 3c8d23502..60eabcb02 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -626,13 +626,16 @@ export default { }, showInsuranceCoverageAs() { if (!this.isInsurance) return null; + if (this.isNoComp || this.isItac) { return coverageStatus.NOCOMP; - } else { - return this.hasSubmittedOrder() - ? this.getSubmittedOrder()?.payment.insuranceCoverage.coverageStatus - : this.$store.getters.payment.insuranceCoverage.coverageStatus; } + + if (this.$store.getters.coverageIsVerified) { + return coverageStatus.VERIFIED; + } + + return coverageStatus.PENDING; }, currentDeductible() { return this.hasSubmittedOrder() diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 15095746b..b740cc5ac 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -167,13 +167,18 @@ export default { } const order = this.hasSubmittedOrder() ? this.getSubmittedOrder() : store.getters.order; - if ( - order.payment.insuranceCoverage.isVerified && + store.getters.coverageIsVerified && !order.policy.isNoComp && !order.policy.isItac ) { amountDue = order.policy.currentDeductible; + if (lineItems.vaps) { + amountDue += this.getTotalPriceOfAllLineItemsAndChildParts( + lineItems.vaps, + includeTax + ); + } } return ((amountDue * 100) / 100).toFixed(2); diff --git a/src/store/index.js b/src/store/index.js index 00bdd486f..4ec245ff3 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -774,6 +774,24 @@ export const getters = { ); return !!nonWindshieldItems?.length; }, + coverageIsVerified: (state) => { + let order; + if (window.sessionStorage.getItem("submittedOrder") !== null) { + order = JSON.parse(window.sessionStorage.getItem("submittedOrder")); + } else { + order = state.order; + } + + if ( + order.payment?.insuranceCoverage?.isVerified && + order.policy?.currentDeductible != 9999 && + order.policy?.currentDeductible != 7777 + ) { + return true; + } + + return false; + }, isMobileAppointment: (state) => { return state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE; }, @@ -899,13 +917,13 @@ export const getters = { isVerifiedAndDeductibleZeroConfirmed: (state) => { // used as a CMS variable on /payment-method, needed for FunnelSubHeaderWidget on cart pages if ( - (state.order.policy.currentDeductible === 0 || - state.order.policy.currentDeductible > 0) && - state.order.payment.insuranceCoverage.coverageStatus === coverageStatus.VERIFIED && + state.order.policy.currentDeductible === 0 && + getters.coverageIsVerified(state) && !state.order.policy.isNoComp ) { return true; } + return false; }, requiresVerifiedRedirecting: (state) => { From 92e0e6e60d63bdce3aa49f399e92993454fa31d8 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 30 Sep 2024 06:22:52 -0400 Subject: [PATCH 18/96] CSR-2237 CSR-2237 move vaps and promos below deductible pricing to make sure it is added into the amount due and also avoid code duplication --- src/mixins/base-mixin.js | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index fdf1261e0..e30663fea 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -145,24 +145,13 @@ export default { includeTax ); } + if (lineItems.supportingItems) { amountDue += this.getTotalPriceOfAllLineItemsAndChildParts( lineItems.supportingItems, includeTax ); } - if (lineItems.vaps) { - amountDue += this.getTotalPriceOfAllLineItemsAndChildParts( - lineItems.vaps, - includeTax - ); - } - if (lineItems.promos) { - amountDue += this.getTotalPriceOfAllLineItemsAndChildParts( - lineItems.promos, - includeTax - ); - } const order = this.hasSubmittedOrder() ? this.getSubmittedOrder() : store.getters.order; if ( @@ -171,12 +160,20 @@ export default { !order.policy.isItac ) { amountDue = order.policy.currentDeductible; - if (lineItems.vaps) { - amountDue += this.getTotalPriceOfAllLineItemsAndChildParts( - lineItems.vaps, - includeTax - ); - } + } + + if (lineItems.vaps) { + amountDue += this.getTotalPriceOfAllLineItemsAndChildParts( + lineItems.vaps, + includeTax + ); + } + + if (lineItems.promos) { + amountDue += this.getTotalPriceOfAllLineItemsAndChildParts( + lineItems.promos, + includeTax + ); } return ((amountDue * 100) / 100).toFixed(2); From c41fe3fcfcd730fba2cde0e2f4fba632b63507cc Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 1 Oct 2024 08:21:47 -0400 Subject: [PATCH 19/96] CSR-2237 CSR-2237 found another cart price issue. Salestax was showing $13 on an order that was pending coverage. Changed salestax to return 0 for not verified insurance --- src/fmg-components/cart/cart.vue | 5 +++++ .../heritage-integration/navigation-helper.js | 2 ++ src/layouts/confirmation/confirmation.vue | 1 + src/layouts/quote/quote.vue | 3 ++- src/layouts/vehicle/vehicle.vue | 9 +++++++++ src/mixins/base-mixin.js | 16 ++++++++-------- 6 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue index 0dffbd6de..e6b66d4e6 100644 --- a/src/fmg-components/cart/cart.vue +++ b/src/fmg-components/cart/cart.vue @@ -1007,6 +1007,11 @@ export default { }, salesTax() { if (!this.lineItems || this.lineItems.length < 1) return; + + if (this.isInsurance && !this.showCoverageAsVerified) { + return 0; + } + return this.isInsurance || !this.shouldHideRecalibration ? baseMixin.methods.getSalesTax(this.lineItems) // calculate with recal (if on order) : baseMixin.methods.getSalesTax(this.lineItemsWithoutRecal); // calculated without recal diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 208a301e4..00687155b 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -109,8 +109,10 @@ export async function getImplicitNavigation(toRoute) { export async function navigateToHeritageFunnel({ shouldSaveSession, pageNameToLog }) { const log = getQuerystringParameter(queryStrings.LOG); if (eval(log)) { + console.log("------------- Navigate to heritage start -----------------"); console.log(new Date() + " applicationConfig: " + JSON.stringify(applicationConfig)); console.log(new Date() + " navigateToHeritageFunnel: " + applicationConfig.HERITAGE_FUNNEL); + console.log("------------- Navigate to heritage end -----------------"); } // Create the order (or save existing order) when navigating to Heritage Funnel. diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index c7f944078..dc3cc8085 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -60,6 +60,7 @@ v-model="lineItems" :showAsPaid="isPia" servicePackageOptionsCmsName="ServicePackageTitle" + :isInsurance="isInsurance" :insuranceDeductible="currentDeductible" :insuranceCompanyName="insuranceCompanyName" :showInsuranceCoverageAs="showInsuranceCoverageAs" diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index b778116e9..cfd51dc8b 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -438,7 +438,7 @@ export default { const payment = store.getters.order.payment; const log = getQuerystringParameter(queryStrings.LOG); if (eval(log)) { - console.log("quote.vue pagePrereqs:"); + console.log("------------- quote.vue pagePrereqs start -----------------"); console.log( new Date() + " store.getters.order.serviceLocation.zipCode: " + @@ -464,6 +464,7 @@ export default { " store.getters.order.payment.insuranceCoverage?.isVerified: " + payment?.insuranceCoverage?.isVerified ); + console.log("----------------- quote.vue pagePrereqs end -----------------"); } return ( store.getters.order.serviceLocation.zipCode && diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index 7f629db0a..30191e4fa 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -98,6 +98,9 @@ import store from "@/store"; import { storeActions } from "@/constants/store-actions.js"; import baseMixin from "@/mixins/base-mixin.js"; import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper"; +import { applicationConfig } from "../../constants/application-config"; +import { queryStrings } from "@/constants/query-strings"; +import { getQuerystringParameter } from "@/helpers/querystring-helper"; //define validation rules defineRule("year-required", required(errorMessages.YEAR_REQUIRED)); @@ -127,6 +130,12 @@ export default { }, async beforeRouteEnter(to, from, next) { + const log = getQuerystringParameter(queryStrings.LOG); + if (eval(log)) { + console.log("----------------- applicationConfig start -----------------"); + console.log(new Date() + JSON.stringify(applicationConfig)); + console.log("----------------- applicationConfig end -----------------"); + } // Call APIs const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); const experimentForLogging = store.getters.applicationUser.experiments.find( diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index e30663fea..12b9a99a2 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -83,7 +83,7 @@ export default { }; }, getTierOnePackagePrice(lineItems) { - let lineItemsToPrice = lineItems.filter((lineItem) => { + let lineItemsToPrice = lineItems?.filter((lineItem) => { return ( lineItem.partType != partTypeStrings.FRONT_WIPER && lineItem.partType != partTypeStrings.REAR_WIPER && @@ -95,7 +95,7 @@ export default { return totalPrice; }, filterOutFees(lineItems) { - const filteredLineItems = lineItems.filter((item) => { + const filteredLineItems = lineItems?.filter((item) => { return ( (!item.partType.includes("FEE") && !item.partType.includes("EARLY BIRD")) || (item.partType === "REPAIR FEE" && item.partNumber != "SUPPLIES-REPAIR") @@ -108,7 +108,7 @@ export default { }, getTotalPriceOfAllLineItemsAndChildParts(lineItems, includeTax) { let totalPrice = 0; - lineItems.forEach((lineItem) => { + lineItems?.forEach((lineItem) => { totalPrice += this.getTotalLineItemPrice(lineItem, includeTax); if (lineItem.childParts) { totalPrice += this.getTotalPriceOfAllLineItemsAndChildParts( @@ -139,14 +139,14 @@ export default { }, getAmountDue(lineItems, includeTax = true) { var amountDue = 0; - if (lineItems.glassParts) { + if (lineItems?.glassParts) { amountDue += this.getTotalPriceOfAllLineItemsAndChildParts( lineItems.glassParts, includeTax ); } - - if (lineItems.supportingItems) { + + if (lineItems?.supportingItems) { amountDue += this.getTotalPriceOfAllLineItemsAndChildParts( lineItems.supportingItems, includeTax @@ -162,14 +162,14 @@ export default { amountDue = order.policy.currentDeductible; } - if (lineItems.vaps) { + if (lineItems?.vaps) { amountDue += this.getTotalPriceOfAllLineItemsAndChildParts( lineItems.vaps, includeTax ); } - if (lineItems.promos) { + if (lineItems?.promos) { amountDue += this.getTotalPriceOfAllLineItemsAndChildParts( lineItems.promos, includeTax From 9cdf1022d0a04318852e1eeff22d45d09bac8428 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Wed, 2 Oct 2024 12:22:37 -0400 Subject: [PATCH 20/96] CSR-2242 CSR-2242 allow drop off to trigger ga event for shops displayed --- src/layouts/service-location/shop-question/shop-question.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/layouts/service-location/shop-question/shop-question.vue b/src/layouts/service-location/shop-question/shop-question.vue index d77a7eb04..08509eb40 100644 --- a/src/layouts/service-location/shop-question/shop-question.vue +++ b/src/layouts/service-location/shop-question/shop-question.vue @@ -167,7 +167,10 @@ export default { if (logFirstShopsDisplayed) { gaAction = this.GaActions.SHOPS_FIRST_DISPLAYED; } - if (this.selectedAppointmentType === AppointmentTypeStrings.IN_SHOP) { + if ( + this.selectedAppointmentType === AppointmentTypeStrings.IN_SHOP || + this.selectedAppointmentType === AppointmentTypeStrings.DROP_OFF + ) { var shops = mappedData.map((shop) => { if (shop.value.length > 5 && shop.value.startsWith("00")) { return shop.value.substring(1); From f13b2436692815c75f2c9e3c685d66e777757aa0 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 2 Oct 2024 15:27:50 -0400 Subject: [PATCH 21/96] CSR-2234: fix to enable BaseMixin ResetExternalParamsAndHideModal to work --- src/store/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/store/index.js b/src/store/index.js index 2b07d1dc1..670274c1a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -919,6 +919,7 @@ export const getters = { externalParameterServiceZip: (state) => externalParameterState?.serviceZip, externalParameterEstimate: (state) => externalParameterState?.estimate, externalParameterSource: (state) => externalParameterState?.source, + isExternalParameter: (state) => externalParameterState?.isExternalParameter, }; function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) { From 09f53773aef9bfa106f9f92076d96974fcb3c6b1 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 2 Oct 2024 15:28:59 -0400 Subject: [PATCH 22/96] CSR-2234: remove isExternalParameter from initialization setup --- src/store/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index 670274c1a..135f17541 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -3433,7 +3433,6 @@ async function resetScheduleIfUnavailable(context, order, pageNameToLog) { function createExternalParameterDefaultState() { // create default externalParameter state const externalParameterDefaultState = { - isExternalParameter: null, vehicle: { year: null, make: null, From 06d54dcb99f18065efae3cfac4baa45ee060d540 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 2 Oct 2024 15:30:09 -0400 Subject: [PATCH 23/96] CSR-2234: remove external param source bc it is no longer needed --- src/store/index.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 135f17541..a35b339b3 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -476,10 +476,6 @@ export const mutations = { externalParameterState.quote.servicePackage = servicePackage; saveExternalParameterState(externalParameterState); }, - updateExternalParameterSource(state, source) { - externalParameterState.source = source; - saveExternalParameterState(externalParameterState); - }, //RESET ExternalParameter MUTATIONS resetExternalParameterVehicleState(state) { externalParameterState.vehicle.year = null; @@ -510,10 +506,6 @@ export const mutations = { externalParameterState.quote.servicePackage = null; saveExternalParameterState(externalParameterState); }, - resetExternalParameterSourceState(state) { - externalParameterState.source = null; - saveExternalParameterState(externalParameterState); - }, resetIsExternalParameter(state) { externalParameterState.isExternalParameter = null; saveExternalParameterState(externalParameterState); @@ -918,7 +910,6 @@ export const getters = { externalParameterQuote: (state) => externalParameterState?.quote, externalParameterServiceZip: (state) => externalParameterState?.serviceZip, externalParameterEstimate: (state) => externalParameterState?.estimate, - externalParameterSource: (state) => externalParameterState?.source, isExternalParameter: (state) => externalParameterState?.isExternalParameter, }; @@ -2912,7 +2903,6 @@ export const actions = { context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_ESTIMATE_STATE); context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_SERVICEZIP_STATE); context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_QUOTE_STATE); - context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_SOURCE_STATE); context.commit(storeMutations.RESET_IS_EXTERNAL_PARAMETER); } }, @@ -3455,7 +3445,6 @@ function createExternalParameterDefaultState() { isInsurance: null, servicePackage: null, }, - source: null, }; // set to session storage saveExternalParameterState(externalParameterDefaultState); From 7b73a164ad20cbb9d1f194017592c6b61c0a99c5 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 2 Oct 2024 15:32:33 -0400 Subject: [PATCH 24/96] CSR-2234: refine quote page external param logic --- src/layouts/quote/quote.vue | 39 +++++++++++++++---------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index b778116e9..9bc8bace4 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -337,17 +337,10 @@ export default { experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL ); - if (!store.getters.externalParameterState?.isExternalParameter) { - // there are no external parameters + const isExternalParameter = store.getters.externalParameterState?.isExternalParameter; - if (internalThreshold) thresholdToUse = internalThreshold; - vm.isInsuranceSelected = getIsInsuranceSelectedValue( - vm.availableLineItems, - thresholdToUse - ); - baseMixin.methods.ResetExternalParamsAndHideModal(); - } else { - // there ARE external parameters + if (isExternalParameter !== undefined) { + // user is from an external source (either has value or is null) if (store.getters.externalParameterQuote.isInsurance == true) { // did user intentionally select insurance? @@ -361,26 +354,26 @@ export default { baseMixin.methods.ResetExternalParamsAndHideModal(); } } else { - // did user come from external source (LeadGen)? - let externalSource = store.getters.externalParameterSource - ? store.getters.externalParameterSource - : null; + const externalThreshold = experimentMixin.methods.getSettingValue( + experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL + ); + thresholdToUse = externalThreshold; - // Business logic to determine what "external" source is - if (externalSource?.includes("LeadGen")) { - const externalThreshold = experimentMixin.methods.getSettingValue( - experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL - ); - if (externalThreshold) thresholdToUse = externalThreshold; - } else { - if (internalThreshold) thresholdToUse = internalThreshold; - } vm.isInsuranceSelected = getIsInsuranceSelectedValue( vm.availableLineItems, thresholdToUse ); baseMixin.methods.ResetExternalParamsAndHideModal(); } + } else { + // there are no external parameters; use internal threshold + if (internalThreshold) thresholdToUse = internalThreshold; + + vm.isInsuranceSelected = getIsInsuranceSelectedValue( + vm.availableLineItems, + thresholdToUse + ); + baseMixin.methods.ResetExternalParamsAndHideModal(); } }); }, From 3d4ac1524e7535465930b9d39cd897c601667ecd Mon Sep 17 00:00:00 2001 From: CarlNation Date: Thu, 3 Oct 2024 08:30:55 -0400 Subject: [PATCH 25/96] CSR-2237 CSR-2237 show tax for itac and nocomp --- src/fmg-components/cart/cart.vue | 11 +++++++++-- src/layouts/payment-method/payment-method.vue | 4 +++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue index e6b66d4e6..f2799d7be 100644 --- a/src/fmg-components/cart/cart.vue +++ b/src/fmg-components/cart/cart.vue @@ -188,6 +188,8 @@ export default { insuranceCompanyName: String, showInsuranceCoverageAs: String, shouldHideRecalibration: Boolean, + isItac: Boolean, + isNoComp: Boolean, }, data() { return { @@ -1007,8 +1009,13 @@ export default { }, salesTax() { if (!this.lineItems || this.lineItems.length < 1) return; - - if (this.isInsurance && !this.showCoverageAsVerified) { + + if ( + this.isInsurance && + !this.showCoverageAsVerified && + !this.isItac && + !this.isNoComp + ) { return 0; } diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 6106e4008..9f8cee9ec 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -34,7 +34,9 @@ :insuranceDeductible="currentDeductible" :insuranceCompanyName="insuranceCompanyName" :showInsuranceCoverageAs="showInsuranceCoverageAs" - :shouldHideRecalibration="shouldHideRecalibration" /> + :shouldHideRecalibration="shouldHideRecalibration" + :isItac="isItac" + :isNocomp="isNocomp" />
From 11ac6f454368413978e92050982d8584ae61e94d Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Thu, 3 Oct 2024 08:57:50 -0400 Subject: [PATCH 26/96] CSR-2234: add new constants for external parameters --- src/constants/external-parameters.js | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/constants/external-parameters.js diff --git a/src/constants/external-parameters.js b/src/constants/external-parameters.js new file mode 100644 index 000000000..686e29235 --- /dev/null +++ b/src/constants/external-parameters.js @@ -0,0 +1,6 @@ +const externalParameterStatus = { + NOT_SET: null, + ACTIVE: 1, + INACTIVE: 0, +}; +export { externalParameterStatus }; \ No newline at end of file From 6cfba7e4310263c5b60bfe74aab631597ed2525f Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Thu, 3 Oct 2024 08:58:53 -0400 Subject: [PATCH 27/96] CSR-2234: restore original creation state of isExternalParameter var --- src/store/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index a35b339b3..533ad3ad1 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -42,6 +42,7 @@ import { coverageTypeEnum, } from "@/constants/insurance"; import { containsRecalParts } from "@/helpers/recal-helper"; +import { externalParameterStatus } from "@/constants/external-parameters"; // Export State const getDefaultState = () => { @@ -507,7 +508,7 @@ export const mutations = { saveExternalParameterState(externalParameterState); }, resetIsExternalParameter(state) { - externalParameterState.isExternalParameter = null; + externalParameterState.isExternalParameter = externalParameterStatus.INACTIVE; saveExternalParameterState(externalParameterState); }, @@ -3423,6 +3424,7 @@ async function resetScheduleIfUnavailable(context, order, pageNameToLog) { function createExternalParameterDefaultState() { // create default externalParameter state const externalParameterDefaultState = { + isExternalParameter: externalParameterStatus.NOT_SET, vehicle: { year: null, make: null, From b48a62b3fc8803b121a43fe34474450a8757c3f2 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Thu, 3 Oct 2024 08:59:55 -0400 Subject: [PATCH 28/96] CSR-2234: implement new externalParameter constants --- src/layouts/quote/quote.vue | 23 ++++++++++++----------- src/router/index.js | 7 ++++--- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 9bc8bace4..b18dc3dde 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -136,6 +136,8 @@ import { nextTick } from "vue"; import { packageNames } from "@/constants/package-names"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; import { containsRecalParts } from "@/helpers/recal-helper"; +import { externalParameterStatus } from "@/constants/external-parameters"; + defineRule("option-required", required(errorMessages.OPTION_REQUIRED)); const INSURANCE_TAB_TO_DISPLAY_THRESHOLD_DEFAULT = 300; @@ -339,9 +341,17 @@ export default { const isExternalParameter = store.getters.externalParameterState?.isExternalParameter; - if (isExternalParameter !== undefined) { - // user is from an external source (either has value or is null) + if (isExternalParameter === externalParameterStatus.NOT_SET) { + // there are no active or inactive external parameters; use internal threshold + if (internalThreshold) thresholdToUse = internalThreshold; + vm.isInsuranceSelected = getIsInsuranceSelectedValue( + vm.availableLineItems, + thresholdToUse + ); + baseMixin.methods.ResetExternalParamsAndHideModal(); + } else { + // user came from an external source if (store.getters.externalParameterQuote.isInsurance == true) { // did user intentionally select insurance? vm.isInsuranceSelected = true; @@ -365,15 +375,6 @@ export default { ); baseMixin.methods.ResetExternalParamsAndHideModal(); } - } else { - // there are no external parameters; use internal threshold - if (internalThreshold) thresholdToUse = internalThreshold; - - vm.isInsuranceSelected = getIsInsuranceSelectedValue( - vm.availableLineItems, - thresholdToUse - ); - baseMixin.methods.ResetExternalParamsAndHideModal(); } }); }, diff --git a/src/router/index.js b/src/router/index.js index 4c57921b7..9d4417ff8 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -10,6 +10,7 @@ import { getQuerystringParameter } from "@/helpers/querystring-helper"; import { getDeviceIdValue } from "@/helpers/heritage-integration/cookie-helper"; import { showFmgLoadingModal } from "@/helpers/loading-modal-helper"; import { fmgPageValues, funnelStartPageName } from "@/router/router-constants/fmgPage-values"; +import { externalParameterStatus } from "@/constants/external-parameters"; // Heritage integration import { isSavedSessionStillActive } from "@/helpers/heritage-integration/session-helper"; @@ -264,7 +265,7 @@ router.beforeEach(async (to, from, next) => { ); // If alert event is on the bus, then display the alert if (alertEvent !== undefined || unknownAlertEvent !== undefined) { - store.commit(storeMutations.UPDATE_IS_EXTERNAL_PARAMETER, false); + store.commit(storeMutations.UPDATE_IS_EXTERNAL_PARAMETER, externalParameterStatus.INACTIVE); } } // fromPaymentToConfirmation workaround for navigating from an iframe but @@ -540,7 +541,7 @@ async function DisplayPageError() { type: globalEventTypes.Danger, } ); - store.commit(storeMutations.UPDATE_IS_EXTERNAL_PARAMETER, false); + store.commit(storeMutations.UPDATE_IS_EXTERNAL_PARAMETER, externalParameterStatus.INACTIVE); baseMixin.methods.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE); const pageError = getQuerystringParameter(queryStrings.PAGE_ERROR); @@ -639,7 +640,7 @@ function updateExternalParameterState() { externalParameterModel && externalParameterStyle ) { - store.commit(storeMutations.UPDATE_IS_EXTERNAL_PARAMETER, true); + store.commit(storeMutations.UPDATE_IS_EXTERNAL_PARAMETER, externalParameterStatus.ACTIVE); store.commit(storeMutations.UPDATE_EXTERNAL_PARAMETER_YEAR, externalParameterYear); store.commit(storeMutations.UPDATE_EXTERNAL_PARAMETER_MAKE, externalParameterMake); store.commit(storeMutations.UPDATE_EXTERNAL_PARAMETER_MODEL, externalParameterModel); From 74749f4172df9d7646be2eb0b5569cd96654dd83 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 4 Oct 2024 05:17:05 -0400 Subject: [PATCH 29/96] CSR-1928 CSR-1928 use comma separator instead of slash --- src/layouts/service-location/shop-question/shop-question.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/service-location/shop-question/shop-question.vue b/src/layouts/service-location/shop-question/shop-question.vue index 08509eb40..a15d8bb0b 100644 --- a/src/layouts/service-location/shop-question/shop-question.vue +++ b/src/layouts/service-location/shop-question/shop-question.vue @@ -182,7 +182,7 @@ export default { this.pushEventToGA( this.GaCategories.SERVICE_LOCATION, gaAction, - shops.join("/"), + shops.join(","), true ); } From 13598aea946a36e76d8a3ead80aaea73b7bbc1df Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Fri, 4 Oct 2024 09:07:08 -0400 Subject: [PATCH 30/96] CSR-2150 | Make recal promos work --- src/store/index.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 29289db6e..be4a8784e 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2950,7 +2950,9 @@ export const actions = { async getRecalPartsAndSaveToLineItems(context, { pageNameToLog }) { // identify each part that needs recal - const glassParts = context.state.order?.lineItems?.glassParts ?? []; + const glassParts = context.state.order?.lineItems?.glassParts + ? deepClone(context.state.order.lineItems.glassParts) + : []; for (let i = 0; i < glassParts.length; i++) { // does this part need recal? @@ -2983,6 +2985,7 @@ export const actions = { } glassParts[i].childParts.push(...recalPartResponse.data.recalibrationParts); + context.dispatch(storeActions.SAVE_GLASS_PARTS, glassParts); } } } @@ -3181,7 +3184,10 @@ export function getArrayOfAllLineItems(lineItems) { let consolidatedLineItemsArray = []; if (lineItems.glassParts != null) - consolidatedLineItemsArray = [...consolidatedLineItemsArray, ...lineItems.glassParts]; + consolidatedLineItemsArray = [ + ...consolidatedLineItemsArray, + ...getFlattenedArrayOfLineItemsWithChildParts(lineItems.glassParts), + ]; if (lineItems.supportingItems != null) consolidatedLineItemsArray = [...consolidatedLineItemsArray, ...lineItems.supportingItems]; @@ -3269,6 +3275,9 @@ function addGuidToLineItemsIfNotAlreadyThere(lineItems) { if (!lineItem.id) { lineItem.id = crypto.randomUUID(); } + if (lineItem.childParts) { + addGuidToLineItemsIfNotAlreadyThere(lineItem.childParts); + } }); } From 48c6a56e96de9ec9dc568897b85b4b943d17b5a2 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Fri, 4 Oct 2024 09:44:02 -0400 Subject: [PATCH 31/96] CSR-2150 | Future proofing --- .../afterpay-modal-banner.vue | 6 +++--- src/store/index.js | 21 +++++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/layouts/quote/afterpay-modal-banner/afterpay-modal-banner.vue b/src/layouts/quote/afterpay-modal-banner/afterpay-modal-banner.vue index 512d0f577..bf9433301 100644 --- a/src/layouts/quote/afterpay-modal-banner/afterpay-modal-banner.vue +++ b/src/layouts/quote/afterpay-modal-banner/afterpay-modal-banner.vue @@ -30,7 +30,7 @@ import { splitCopyOnCMSPlaceHolder } from "@/helpers/cms-content-helper"; import baseMixin from "@/mixins/base-mixin.js"; import { getPromosThatMatchLineItemsOnOrder } from "@/helpers/promotions-helper"; -import { getArrayOfAllLineItems } from "@/store"; +import { getArrayOfAllLineItemsAndChildParts } from "@/store"; const INLINE_IMAGE_TOKEN = "custom:inlineImage"; const AFTERPAY_PRICE_TOKEN = "custom:afterpayPrice"; @@ -76,7 +76,7 @@ export default { return this.getCmsContent(this.cmsWidgetName, "SubheaderText"); }, afterpayPrice() { - let allLineItems = getArrayOfAllLineItems(this.lineItems); + let allLineItems = getArrayOfAllLineItemsAndChildParts(this.lineItems); if (this.lineItems.promos) { allLineItems = allLineItems?.filter((item) => item.partType !== "PROMO_DISCOUNT"); } @@ -91,7 +91,7 @@ export default { }); if (this.lineItems.promos) { - let allLineItems = getArrayOfAllLineItems(this.lineItems); + let allLineItems = getArrayOfAllLineItemsAndChildParts(this.lineItems); const promos = getPromosThatMatchLineItemsOnOrder( this.lineItems.promos, allLineItems diff --git a/src/store/index.js b/src/store/index.js index be4a8784e..6c4b7d8e2 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2625,7 +2625,7 @@ export const actions = { eon: order.eon, isRepair: order.damage.isRepair, glassToReplace: renameGlassToReplaceAttributes(order.damage.glassToReplace), - lineItemsOnOrder: getArrayOfAllLineItems(lineItemsToUse), + lineItemsOnOrder: getArrayOfAllLineItemsAndChildParts(lineItemsToUse), parentAccountNumber: useDefaultCashParentAccount ? applicationConfig.CASH_PARENT_ACCOUNT_NUMBER : order.payment.parentAccountNumber, @@ -2697,7 +2697,7 @@ export const actions = { eon: order.eon, isRepair: order.damage.isRepair, glassToReplace: renameGlassToReplaceAttributes(order.damage.glassToReplace), - lineItemsOnOrder: getArrayOfAllLineItems(lineItemsToUse), + lineItemsOnOrder: getArrayOfAllLineItemsAndChildParts(lineItemsToUse), parentAccountNumber: useDefaultCashParentAccount ? applicationConfig.CASH_PARENT_ACCOUNT_NUMBER : order.payment.parentAccountNumber, @@ -3180,7 +3180,7 @@ export function mapTaxedLineItemsToStoreFormat(availableLineItems, storeLineItem return lineItems; } -export function getArrayOfAllLineItems(lineItems) { +export function getArrayOfAllLineItemsAndChildParts(lineItems) { let consolidatedLineItemsArray = []; if (lineItems.glassParts != null) @@ -3190,13 +3190,22 @@ export function getArrayOfAllLineItems(lineItems) { ]; if (lineItems.supportingItems != null) - consolidatedLineItemsArray = [...consolidatedLineItemsArray, ...lineItems.supportingItems]; + consolidatedLineItemsArray = [ + ...consolidatedLineItemsArray, + ...getFlattenedArrayOfLineItemsWithChildParts(lineItems.supportingItems), + ]; if (lineItems.vaps != null) - consolidatedLineItemsArray = [...consolidatedLineItemsArray, ...lineItems.vaps]; + consolidatedLineItemsArray = [ + ...consolidatedLineItemsArray, + ...getFlattenedArrayOfLineItemsWithChildParts(lineItems.vaps), + ]; if (lineItems.promos != null) - consolidatedLineItemsArray = [...consolidatedLineItemsArray, ...lineItems.promos]; + consolidatedLineItemsArray = [ + ...consolidatedLineItemsArray, + ...getFlattenedArrayOfLineItemsWithChildParts(lineItems.promos), + ]; return consolidatedLineItemsArray; } From 9fa6a4d6693cf47e8081c986ae9dab3f005d8a30 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 4 Oct 2024 10:57:31 -0400 Subject: [PATCH 32/96] set isGlass to false for adas part type set isGlass to false for adas part type now that they are child parts --- src/store/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index c89e04a14..3af0ec006 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -3216,7 +3216,11 @@ function getFlattenedLineItemsWithGlassPartTag(lineItems) { return { partNumber: lineItem.partNumber, partType: lineItem.partType, - isGlassPart: true, + isGlassPart: + lineItem.partType == partTypeStrings.RECALIBRATION || + lineItem.partType == partTypeStrings.ADAS_RECALIBRATION + ? false + : true, }; }); From c2dc235fb5ddf19afb35bb0c3312a00c58e185d8 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 4 Oct 2024 15:22:02 -0400 Subject: [PATCH 33/96] CSR-2237 CSR-2237 show tax for itac and nocomp --- src/layouts/confirmation/confirmation.vue | 4 +++- src/layouts/payment/payment.vue | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index dc3cc8085..1d77585b3 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -64,7 +64,9 @@ :insuranceDeductible="currentDeductible" :insuranceCompanyName="insuranceCompanyName" :showInsuranceCoverageAs="showInsuranceCoverageAs" - :shouldHideRecalibration="shouldHideRecalibration" /> + :shouldHideRecalibration="shouldHideRecalibration" + :isItac="isItac" + :isNoComp="isNoComp" />
diff --git a/src/layouts/payment/payment.vue b/src/layouts/payment/payment.vue index 64989ec66..de74071c2 100644 --- a/src/layouts/payment/payment.vue +++ b/src/layouts/payment/payment.vue @@ -57,7 +57,9 @@ recyclingModalCmsWidgetName="RecycleModal" :insuranceDeductible="currentDeductible" :insuranceCompanyName="insuranceCompanyName" - :showInsuranceCoverageAs="showInsuranceCoverageAs" /> + :showInsuranceCoverageAs="showInsuranceCoverageAs" + :isItac="isItac" + :isNocomp="isNocomp" />
From ca4f6a2bd6c5c8279ba7992cf538e4828d11da9b Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 7 Oct 2024 06:21:15 -0400 Subject: [PATCH 34/96] CSR-2243 Not actually related to CSR-2243 but found while debugging that issue. We set isGlassPart true for all items in that collection, even child parts like recal, molding and clips. Micro service team's latest changes is more strict with this property and returning a 404 error and then mule returns a 500 internal server error. --- src/store/index.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 5baf2a3a5..fedea9fd4 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -3201,14 +3201,16 @@ export function getArrayOfAllLineItemsAndChildParts(lineItems) { return consolidatedLineItemsArray; } -function getFlattenedArrayOfLineItemsWithChildParts(lineItems) { +function getFlattenedArrayOfLineItemsWithChildParts(lineItems, childPartRecursiveCall = false) { let flattenedArray = []; lineItems?.forEach((lineItem) => { + // this assumes childparts will never be a glass part + lineItem.isChildPart = childPartRecursiveCall; flattenedArray.push(lineItem); if (lineItem.childParts) { flattenedArray = [ ...flattenedArray, - ...getFlattenedArrayOfLineItemsWithChildParts(lineItem.childParts), + ...getFlattenedArrayOfLineItemsWithChildParts(lineItem.childParts, true), ]; } }); @@ -3231,11 +3233,7 @@ function getFlattenedLineItemsWithGlassPartTag(lineItems) { return { partNumber: lineItem.partNumber, partType: lineItem.partType, - isGlassPart: - lineItem.partType == partTypeStrings.RECALIBRATION || - lineItem.partType == partTypeStrings.ADAS_RECALIBRATION - ? false - : true, + isGlassPart: lineItem.isChildPart ? false : true, }; }); From 433ba2cd472517940ae8f628ea234da653409d8e Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 7 Oct 2024 08:28:03 -0400 Subject: [PATCH 35/96] CSR-2243 fix tests --- src/store/store.spec.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 9c546d3be..4a1cb6173 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -5,7 +5,6 @@ import { storeActions } from "@/constants/store-actions"; import { experimentTriggers } from "@/constants/experiments"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { AppointmentTypeStrings } from "@/constants/schedule-constants"; -import { coverageStatus } from "../constants/insurance"; // Mock global method globalMethods.callHttpClient = jest.fn(); @@ -2935,7 +2934,7 @@ describe("Actions", () => { // Arrange const context = state; const promoCode = "testPromo"; - const lineItemsToUse = { vaps: [{ partNumber: 1 }], promos: [2] }; + const lineItemsToUse = { vaps: [{ partNumber: 1 }], promos: [{ promoCode: "1wiper0" }] }; const addableVaps = [{ partNumber: "addableVap" }]; context["getters"] = { @@ -2999,7 +2998,7 @@ describe("Actions", () => { { partNumber: "SBB22", id: "GUID1" }, { partNumber: "SBB22", id: "GUID2" }, ], - promos: [2], + promos: [{ promoCode: "1wiper0" }], }; const addableVaps = [{ partNumber: "SBB22" }, { partNumber: "SBB22" }]; @@ -3059,7 +3058,7 @@ describe("Actions", () => { // Arrange const context = state; const promoCode = "testPromo"; - const lineItemsToUse = { vaps: [{ partNumber: 1 }], promos: [2] }; + const lineItemsToUse = { vaps: [{ partNumber: 1 }], promos: [{ promoCode: "1wiper0" }] }; const addableVaps = [{ partNumber: "addableVap" }]; context["getters"] = { @@ -3140,7 +3139,7 @@ describe("Actions", () => { referralSequenceNumber: "test", lineItems: { vaps: [{ partNumber: 1 }], - promos: [2], + promos: [{ promoCode: "1wiper0" }], serverData: "test", }, }, @@ -3152,7 +3151,7 @@ describe("Actions", () => { crypto.randomUUID = jest.fn(() => "GUID"); - const expectedLineItemsOnOrder = [{ partNumber: 1, id: "GUID" }, 2]; + const expectedLineItemsOnOrder = [{ partNumber: 1, isChildPart: false, id: "GUID" }, { promoCode: "1wiper0", isChildPart: false }]; // Act actions.validateOrderPromoAndSaveServerData(context, { @@ -3200,7 +3199,7 @@ describe("Actions", () => { referralSequenceNumber: "test", lineItems: { vaps: [{ partNumber: 1 }], - promos: [2], + promos: [{ promoCode: "1wiper0" }], serverData: "test", }, }, @@ -3258,7 +3257,7 @@ describe("Actions", () => { referralSequenceNumber: "test", lineItems: { vaps: [{ partNumber: 1 }], - promos: [2], + promos: [{ promoCode: "1wiper0" }], serverData: "test", }, }, @@ -3350,9 +3349,9 @@ describe("Actions", () => { const context = state; context.commit = jest.fn(() => {}); - const activePromosToUse = [{ promoCode: "providedPromo" }]; + const activePromosToUse = [{ promoCode: "providedPromo", isChildPart: false }]; const inactivePromosToUse = ["providedInactivePromo"]; - const vapsProvided = [{ id: 123 }]; + const vapsProvided = [{ id: 123, isChildPart: false }]; const lineItemsToUse = { vaps: vapsProvided }; context["getters"] = { @@ -3440,8 +3439,8 @@ describe("Actions", () => { referralSequenceNumber: "test", lineItems: { serverData: "test", - promos: [{ promoCode: "test" }], - vaps: [{ partNumber: "testVap", id: "providedId" }], + promos: [{ promoCode: "test", isChildPart: false }], + vaps: [{ partNumber: "testVap", isChildPart:false, id: "providedId" }], }, }, }; From 4814b0ce39c7a1b08a0e75fdc3ff95f38ea8f207 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Mon, 7 Oct 2024 11:04:53 -0400 Subject: [PATCH 36/96] CSR-2234: fix unit tests --- src/layouts/quote/quote.spec.js | 32 +++++++++++++++++++++----------- src/layouts/quote/quote.vue | 5 ++--- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js index d9c1ffabf..c83801693 100644 --- a/src/layouts/quote/quote.spec.js +++ b/src/layouts/quote/quote.spec.js @@ -65,6 +65,24 @@ jest.mock("@/mixins/base-mixin", () => ({ }, })); +const mockExperimentSettings = experimentSettings; + +jest.mock("@/mixins/experiment-mixin.js", () => ({ + methods: { + getSettingValue(settingName) { + if (settingName === mockExperimentSettings.SERVICE_PACKAGE_DISCOUNT) { + return true; + } + if (settingName === mockExperimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL) { + return 300; + } else if (settingName === mockExperimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL) { + return 500; + } + return "test"; + }, + }, +})); + const mockMixin = { methods: { filterOutFees: jest.fn().mockImplementation(() => { @@ -73,12 +91,6 @@ const mockMixin = { isFormValid: jest.fn().mockImplementation(() => { return true; }), - getSettingValue: jest.fn((settingName) => { - if (settingName === experimentSettings.SERVICE_PACKAGE_DISCOUNT) { - return true; - } - return false; - }), }, }; let mockTierOnePrice = 501; @@ -261,7 +273,7 @@ describe("quote.vue", () => { }; const { wrapper } = setupMocks({}); - //mock this to avoid needing to populate this.$route in an unrelated test + //mock this to avoid needing to populate this.$route in an unrelated test wrapper.vm.getDefaultIsInsuranceSelectedValue = jest.fn(); //Act @@ -309,7 +321,7 @@ describe("quote.vue", () => { wrapper.vm.$route = { query: { isInsurance: "false" } }; - const isServicePackageDiscount = mockMixin.methods.getSettingValue( + const isServicePackageDiscount = experimentMixin.methods.getSettingValue( experimentSettings.SERVICE_PACKAGE_DISCOUNT ); @@ -701,7 +713,7 @@ describe("quote.vue", () => { inactivePromos: [], }, }, - externalParameterState: { isExternalParameter: true }, + externalParameterState: { isExternalParameter: 1 }, externalParameterQuote: { isInsurance: true, servicePackage: "glassonly", @@ -758,8 +770,6 @@ function setupMocks({ customMountOptions }) { baseMixin.methods.ResetExternalParamsAndHideModal = jest.fn(); baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true); mountOptions.global.mocks["$store"] = store; - store.getters.experimentSettings = "test value"; - mountOptions["attachTo"] = document.body; const wrapper = shallowMount(quote, mountOptions); diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index b18dc3dde..7f3c017d7 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -338,7 +338,6 @@ export default { let internalThreshold = experimentMixin.methods.getSettingValue( experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL ); - const isExternalParameter = store.getters.externalParameterState?.isExternalParameter; if (isExternalParameter === externalParameterStatus.NOT_SET) { @@ -352,7 +351,7 @@ export default { baseMixin.methods.ResetExternalParamsAndHideModal(); } else { // user came from an external source - if (store.getters.externalParameterQuote.isInsurance == true) { + if (store.getters.externalParameterQuote?.isInsurance == true) { // did user intentionally select insurance? vm.isInsuranceSelected = true; vm.servicePackage = store.getters.externalParameterQuote.servicePackage; @@ -571,7 +570,7 @@ export default { } }); this.$nextTick(() => { - const availablePackageNames = this.$refs.servicePackage.servicePackageAnswers; + const availablePackageNames = this.$refs.servicePackage?.servicePackageAnswers; var eventLabel = ""; availablePackageNames?.forEach((tier) => { if (tier) { From eb09eb9a7ce62453c89073c43ba8dcbf643ca521 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Wed, 9 Oct 2024 13:06:27 +0530 Subject: [PATCH 37/96] CSR-1629 Added event names to product array, ecommerce cart and CJ pixel gtm data to data layer. --- src/mixins/analytics-mixin.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index e0517080e..bbf365068 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -439,6 +439,7 @@ export default { } } pushToDataLayerIfDefined({ + event: "productArray", productArray: { coupon: coupon, discount: discount.toFixed(2), @@ -537,7 +538,11 @@ export default { ); } pushToDataLayerIfDefined({ - eCommerceCart: { products: combinedLineItems, subTotal: parseInt(subtotal) }, + event: "eCommerceCart", + eCommerceCart: { + products: combinedLineItems, + subTotal: parseInt(subtotal), + }, }); } }, @@ -625,6 +630,7 @@ export default { } } pushToDataLayerIfDefined({ + event: "commissionJunctionGtmData", commissionJunctionGtmData: { cj_commission_junction_event: cjEvent, cj_referral_sequence_number: refSequenceNum, From 39ac9c1c192276bfecae36ad68b69bd2f2deee30 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Wed, 9 Oct 2024 15:51:20 +0530 Subject: [PATCH 38/96] CSR-1629 changing the order of CJ events --- src/router/index.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index 266ccb855..a8eb4abc2 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -315,12 +315,12 @@ router.afterEach(async (to, from) => { analyticsMixin.methods.pushOrderToDataLayer(); if (to.query.fmgPage == fmgPageValues.CONFIRMATION) { - //Push Product Array to Data Layer - analyticsMixin.methods.pushProductArrayToDataLayer(); - //Push Ecommerce Cart to Data Layer analyticsMixin.methods.pushECommerceCartToDataLayer(); + //Push Product Array to Data Layer + analyticsMixin.methods.pushProductArrayToDataLayer(); + //Push Commission Junction Gtm Data To Data Layer analyticsMixin.methods.pushCommissionJunctionGtmDataToDataLayer(); } @@ -683,10 +683,7 @@ function updateExternalParameterState() { ); } if (externalParameterSource) { - store.commit( - storeMutations.UPDATE_EXTERNAL_PARAMETER_SOURCE, - externalParameterSource - ); + store.commit(storeMutations.UPDATE_EXTERNAL_PARAMETER_SOURCE, externalParameterSource); } } From 000baf14eea9b37b57be894fd9b6ab379e54a573 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 9 Oct 2024 07:41:05 -0400 Subject: [PATCH 39/96] CSR-2179-again: restore missing recal bullets et al changes --- src/layouts/quote/quote.vue | 9 +++------ .../service-package-question.vue | 7 +++++-- src/mixins/base-mixin.js | 4 ++-- src/store/index.js | 8 +++++++- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 6a0a5de24..7722e2c09 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -71,7 +71,7 @@ cmsWidgetName="quoteDisclaimer" justifyText="left" typeStyle="caption" - class="mt-6" /> + class="mt-6 quote-disclaimer" /> @@ -393,7 +393,7 @@ export default { return Object.assign({}, this.lineItems); }, isRecalibrationOnOrder() { - return containsRecalParts(this.lineItems); + return store.getters.isRecalibrationOnOrder; }, isServicePackageDiscountOnOrder() { return containsLineItemWithPartType( @@ -408,10 +408,7 @@ export default { ); }, shouldHideRecalibration() { - return ( - this.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE)?.toLowerCase() === - "true" && this.isRecalibrationOnOrder - ); + return store.getters.shouldHideRecalibration; }, showAfterpayBanner() { return ( diff --git a/src/layouts/quote/service-package-question/service-package-question.vue b/src/layouts/quote/service-package-question/service-package-question.vue index afd592e72..2a544e8ce 100644 --- a/src/layouts/quote/service-package-question/service-package-question.vue +++ b/src/layouts/quote/service-package-question/service-package-question.vue @@ -201,6 +201,9 @@ export default { this.nullSafeAvailableLineItems ); }, + showRecalInServicePackages() { + return this.isRecalibrationOnOrder && !this.shouldHideRecalibration; + }, }, methods: { processIfStatements, @@ -357,8 +360,8 @@ export default { }, getCustomValueFromString(str) { switch (str) { - case "isRecalibrationOnOrder": - return this.isRecalibrationOnOrder; + case "showRecalInServicePackages": + return this.showRecalInServicePackages; case "frontWipersApplicableForTierTwo": return this.frontWipersApplicableForTierTwo; case "rearWiperApplicableForTierTwo": diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 12b9a99a2..b6d3e0074 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -97,8 +97,8 @@ export default { filterOutFees(lineItems) { const filteredLineItems = lineItems?.filter((item) => { return ( - (!item.partType.includes("FEE") && !item.partType.includes("EARLY BIRD")) || - (item.partType === "REPAIR FEE" && item.partNumber != "SUPPLIES-REPAIR") + (!item?.partType?.includes("FEE") && !item?.partType?.includes("EARLY BIRD")) || + (item?.partType === "REPAIR FEE" && item?.partNumber != "SUPPLIES-REPAIR") ); }); return filteredLineItems; diff --git a/src/store/index.js b/src/store/index.js index f100a09eb..65c1d64d4 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -43,6 +43,8 @@ import { } from "@/constants/insurance"; import { containsRecalParts } from "@/helpers/recal-helper"; import { externalParameterStatus } from "@/constants/external-parameters"; +import { experimentSettings } from "@/constants/experiments"; +import experimentMixin from "@/mixins/experiment-mixin.js"; // Export State const getDefaultState = () => { @@ -807,6 +809,10 @@ export const getters = { return false; }, + shouldHideRecalibration: (state) => { + return (experimentMixin.methods.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE) + ?.toLowerCase() === "true" && getters.isRecalibrationOnOrder); + }, areRearWipersOnOrder: (state) => { return !!state.order.lineItems.vaps?.some( (vap) => vap.partType.toUpperCase() === partTypeStrings.REAR_WIPER.toUpperCase() @@ -908,6 +914,7 @@ export const getters = { .filter((x) => !!x.isActive) .map((x) => x.settings) .reduce((r, c) => Object.assign(r, c), {}) ?? {}, + isVerifiedAndDeductibleZeroConfirmed: (state) => { // used as a CMS variable on /payment-method, needed for FunnelSubHeaderWidget on cart pages if ( @@ -917,7 +924,6 @@ export const getters = { ) { return true; } - return false; }, requiresVerifiedRedirecting: (state) => { From 4d6f3d3fa9facafa065e65c6cf500dc1c7dcd9b8 Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Wed, 9 Oct 2024 07:42:27 -0400 Subject: [PATCH 40/96] CSR-2179-again: update unit test --- .../service-package-question-test-helper.js | 54 +++++++++---------- .../service-package-question.spec.js | 2 + 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/layouts/quote/service-package-question/service-package-question-test-helper.js b/src/layouts/quote/service-package-question/service-package-question-test-helper.js index 36f938a7e..a352b08d6 100644 --- a/src/layouts/quote/service-package-question/service-package-question-test-helper.js +++ b/src/layouts/quote/service-package-question/service-package-question-test-helper.js @@ -31,7 +31,7 @@ export const mockProcessedCmsContent = { HeaderText: "Economy service", SubheaderText: "", BodyText: - "
  • New replacement windshield
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", + "
  • New replacement windshield
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", Image: "", FooterText: "{if:custom:frontWipersApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{else}{if:custom:rearWiperApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{end}{end}", @@ -40,7 +40,7 @@ export const mockProcessedCmsContent = { HeaderText: "Standard service", SubheaderText: "MOST POPULAR", BodyText: - "
  • New replacement windshield
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", + "
  • New replacement windshield
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", Image: "", FooterText: "", }, @@ -48,7 +48,7 @@ export const mockProcessedCmsContent = { HeaderText: "Premium service", SubheaderText: "", BodyText: - "
  • New replacement windshield
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", + "
  • New replacement windshield
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", Image: "", FooterText: "", }, @@ -58,7 +58,7 @@ export const mockProcessedCmsContent = { HeaderText: "Economy service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", Image: "", FooterText: "{if:custom:frontWipersApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{else}{if:custom:rearWiperApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{end}{end}", @@ -67,7 +67,7 @@ export const mockProcessedCmsContent = { HeaderText: "Standard service", SubheaderText: "MOST POPULAR", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", Image: "", FooterText: "", }, @@ -75,7 +75,7 @@ export const mockProcessedCmsContent = { HeaderText: "Premium service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", Image: "", FooterText: "", }, @@ -85,7 +85,7 @@ export const mockProcessedCmsContent = { HeaderText: "Economy service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", Image: "", FooterText: "{if:custom:frontWipersApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{else}{if:custom:rearWiperApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{end}{end}", @@ -94,7 +94,7 @@ export const mockProcessedCmsContent = { HeaderText: "Standard service", SubheaderText: "MOST POPULAR", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", Image: "", FooterText: "", }, @@ -102,7 +102,7 @@ export const mockProcessedCmsContent = { HeaderText: "Premium service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", Image: "", FooterText: "", }, @@ -112,7 +112,7 @@ export const mockProcessedCmsContent = { HeaderText: "Economy service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", Image: "", FooterText: "{if:custom:frontWipersApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{else}{if:custom:rearWiperApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{end}{end}", @@ -121,7 +121,7 @@ export const mockProcessedCmsContent = { HeaderText: "Standard service", SubheaderText: "MOST POPULAR", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", Image: "", FooterText: "", }, @@ -129,7 +129,7 @@ export const mockProcessedCmsContent = { HeaderText: "Premium service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", Image: "", FooterText: "", }, @@ -139,7 +139,7 @@ export const mockProcessedCmsContent = { HeaderText: "Economy service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", Image: "", FooterText: "{if:custom:frontWipersApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{else}{if:custom:rearWiperApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{end}{end}", @@ -148,7 +148,7 @@ export const mockProcessedCmsContent = { HeaderText: "Standard service", SubheaderText: "MOST POPULAR", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", Image: "", FooterText: "", }, @@ -156,7 +156,7 @@ export const mockProcessedCmsContent = { HeaderText: "Premium service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", Image: "", FooterText: "", }, @@ -166,7 +166,7 @@ export const mockProcessedCmsContent = { HeaderText: "Economy service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", Image: "", FooterText: "{if:custom:frontWipersApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{else}{if:custom:rearWiperApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{end}{end}", @@ -175,7 +175,7 @@ export const mockProcessedCmsContent = { HeaderText: "Standard service", SubheaderText: "MOST POPULAR", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", Image: "", FooterText: "", }, @@ -183,7 +183,7 @@ export const mockProcessedCmsContent = { HeaderText: "Premium service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", Image: "", FooterText: "", }, @@ -193,7 +193,7 @@ export const mockProcessedCmsContent = { HeaderText: "Economy service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", Image: "", FooterText: "{if:custom:frontWipersApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{else}{if:custom:rearWiperApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{end}{end}", @@ -202,7 +202,7 @@ export const mockProcessedCmsContent = { HeaderText: "Standard service", SubheaderText: "MOST POPULAR", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", Image: "", FooterText: "", }, @@ -210,7 +210,7 @@ export const mockProcessedCmsContent = { HeaderText: "Premium service", SubheaderText: "", BodyText: - "
  • New replacement glass
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", + "
  • New replacement glass
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", Image: "", FooterText: "", }, @@ -220,7 +220,7 @@ export const mockProcessedCmsContent = { HeaderText: "Economy service", SubheaderText: "", BodyText: - "
  • New replacement windshield
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", + "
  • New replacement windshield
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", Image: "", FooterText: "{if:custom:frontWipersApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{else}{if:custom:rearWiperApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{end}{end}", @@ -229,7 +229,7 @@ export const mockProcessedCmsContent = { HeaderText: "Standard service", SubheaderText: "MOST POPULAR", BodyText: - "
  • New replacement windshield
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", + "
  • New replacement windshield
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", Image: "", FooterText: "", }, @@ -237,7 +237,7 @@ export const mockProcessedCmsContent = { HeaderText: "Premium service", SubheaderText: "", BodyText: - "
  • New replacement windshield
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", + "
  • New replacement windshield
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", Image: "", FooterText: "", }, @@ -247,7 +247,7 @@ export const mockProcessedCmsContent = { HeaderText: "Economy service", SubheaderText: "", BodyText: - "
  • New replacement windshield
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", + "
  • New replacement windshield
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
", Image: "", FooterText: "{if:custom:frontWipersApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{else}{if:custom:rearWiperApplicableForTierTwo}New wiper blades are not included with Economy service. Because chips can disrupt the glass surface, we recommend new wipers after a repair.{end}{end}", @@ -256,7 +256,7 @@ export const mockProcessedCmsContent = { HeaderText: "Standard service", SubheaderText: "MOST POPULAR", BodyText: - "
  • New replacement windshield
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", + "
  • New replacement windshield
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierTwo}{if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierTwo}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
", Image: "", FooterText: "", }, @@ -264,7 +264,7 @@ export const mockProcessedCmsContent = { HeaderText: "Premium service", SubheaderText: "", BodyText: - "
  • {if:custom:badCustomValue}DO NOT SHOW{end}New replacement windshield
  • Expert installation{if:custom:isRecalibrationOnOrder} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", + "
  • {if:custom:badCustomValue}DO NOT SHOW{end}New replacement windshield
  • Expert installation{if:custom:showRecalInServicePackages} and {textLink:EstimateRecalModal,recalibration}{end}
  • Nationwide lifetime warranty
  • {if:custom:frontWipersApplicableForTierThree}{if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateFrontWiperModal,front wiper blades}{else}New {textLink:EstimateFrontWiperModal,wiper blades}{end}{end}
  • {if:custom:rearWiperApplicableForTierThree}New {textLink:EstimateRearWiperModal,rear wiper blade}{end}
  • {if:custom:rainDefenseApplicableForTierThree}{textLink:EstimateRainDefenseModal,Rain Defense}™ treatment{end}
", Image: "", FooterText: "", }, diff --git a/src/layouts/quote/service-package-question/service-package-question.spec.js b/src/layouts/quote/service-package-question/service-package-question.spec.js index a23d1ead6..e24b77f6a 100644 --- a/src/layouts/quote/service-package-question/service-package-question.spec.js +++ b/src/layouts/quote/service-package-question/service-package-question.spec.js @@ -476,6 +476,8 @@ describe("service-package-question.vue, matching business rules for package disp mockProps.availableLineItems.push(driverFrontWiperLineItem); mockProps.availableLineItems.push(passengerFrontWiperLineItem); mockProps.isRecalibrationOnOrder = true; + mockProps.shouldHideRecalibration = false; + mockProps.showRecalInServicePackages = true; Object.assign(processedCmsContent, mockProcessedCmsContent[packageNameKey]); const wrapper = setupMocks({ mountOptionsMockData: { From 94a7ce5f47048925727089a40a430883ff90e430 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Thu, 10 Oct 2024 14:49:12 -0400 Subject: [PATCH 41/96] CSR-2244 | Send isInsurance to promo endpoints --- src/store/index.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 65c1d64d4..d744175c9 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -810,8 +810,11 @@ export const getters = { return false; }, shouldHideRecalibration: (state) => { - return (experimentMixin.methods.getSettingValue(experimentSettings.RECAL_PRICE_REMOVE) - ?.toLowerCase() === "true" && getters.isRecalibrationOnOrder); + return ( + experimentMixin.methods + .getSettingValue(experimentSettings.RECAL_PRICE_REMOVE) + ?.toLowerCase() === "true" && getters.isRecalibrationOnOrder + ); }, areRearWipersOnOrder: (state) => { return !!state.order.lineItems.vaps?.some( @@ -2622,6 +2625,7 @@ export const actions = { carId: order.vehicle.carId, correlationId: order.referralCorrelationId, eon: order.eon, + isInsurance: order.payment.isInsurance, isRepair: order.damage.isRepair, glassToReplace: renameGlassToReplaceAttributes(order.damage.glassToReplace), lineItemsOnOrder: getArrayOfAllLineItemsAndChildParts(lineItemsToUse), @@ -2694,6 +2698,7 @@ export const actions = { carId: order.vehicle.carId, correlationId: order.referralCorrelationId, eon: order.eon, + isInsurance: order.payment.isInsurance, isRepair: order.damage.isRepair, glassToReplace: renameGlassToReplaceAttributes(order.damage.glassToReplace), lineItemsOnOrder: getArrayOfAllLineItemsAndChildParts(lineItemsToUse), From 0f9697690f62465cf7a679ba0e73b397e36c2e95 Mon Sep 17 00:00:00 2001 From: Sneha Date: Fri, 11 Oct 2024 12:00:04 +0530 Subject: [PATCH 42/96] CSR-2201 Updating session sequence number --- src/global-methods.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/global-methods.js b/src/global-methods.js index 6afeef53d..22512fe41 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -6,6 +6,7 @@ import store from "@/store"; import { applicationConfig } from "@/constants/application-config.js"; import { GaCategories, GaActions, GaLabels } from "@/constants/analytics"; +import { getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper"; import { headerKeys } from "@/constants/header-keys"; import axiosResponseInterceptorMessages from "@/constants/axios-response-interceptor-messages.js"; @@ -65,7 +66,7 @@ export default { const headers = { [headerKeys.EXPERIMENT]: JSON.stringify(store.getters.experimentSettings), [headerKeys.APPLICATION_NAME]: applicationConfig.APPLICATION_NAME, - [headerKeys.SESSION_SEQUENCE_NUMBER]: store.getters.applicationUser?.savedSessionId, + [headerKeys.SESSION_SEQUENCE_NUMBER]: getSessionKeyValue(), [headerKeys.REFERRAL_SEQUENCE_NUMBER]: order?.referralSequenceNumber, [headerKeys.TRANSACTION_ID]: crypto.randomUUID(), [headerKeys.EON]: order?.eon, From c07bfd7e179f1ee4ef24ed71119792a9a8cf0739 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 11 Oct 2024 18:31:09 -0400 Subject: [PATCH 43/96] allow sys to return to localhost --- src/helpers/heritage-integration/navigation-helper.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 00687155b..e510959db 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -134,6 +134,8 @@ export async function navigateToHeritageFunnel({ shouldSaveSession, pageNameToLo } if ( + (process.env.VUE_APP_HERITAGE_FUNNEL.includes("fixmyglasstest") && + process.env.VUE_APP_CURRENT_ENVIRONMENT === "Localhost") || (process.env.VUE_APP_HERITAGE_FUNNEL.includes("fixmyglassdev") && process.env.VUE_APP_CURRENT_ENVIRONMENT === "Localhost") || (process.env.VUE_APP_HERITAGE_FUNNEL.includes("localhost") && From ae8788e98e52242bfe1e795c271c0964f1cec233 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Sat, 12 Oct 2024 20:29:45 -0400 Subject: [PATCH 44/96] CSR-2237 CSR-2237 typo in isNoComp field preventing tax from computing --- src/layouts/payment-method/payment-method.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/payment-method/payment-method.vue b/src/layouts/payment-method/payment-method.vue index 9f8cee9ec..194243d38 100644 --- a/src/layouts/payment-method/payment-method.vue +++ b/src/layouts/payment-method/payment-method.vue @@ -36,7 +36,7 @@ :showInsuranceCoverageAs="showInsuranceCoverageAs" :shouldHideRecalibration="shouldHideRecalibration" :isItac="isItac" - :isNocomp="isNocomp" /> + :isNoComp="isNoComp" />
From 1c55729af5e465a1f1aeb21674ac5d62c57c5528 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 14 Oct 2024 15:50:25 -0400 Subject: [PATCH 45/96] CSR-2253 CSR-2253 default option threshold on save quote email --- src/layouts/quote/quote.vue | 53 ++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 7722e2c09..83386e973 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -299,8 +299,9 @@ export default { const getIsInsuranceSelectedValue = (availableLineItems, insuranceThreshold) => { const serviceLocationState = store.getters.order.serviceLocation.state; - // Override if coming back from QuoteDetails. Remove override after Quote release - const isInsuranceOverrideValue = to.query?.isInsurance; + + // usually true when returning from heritage but can be false when returning from heritage on a save quote + const isInsuranceFromQueryString = to.query?.isInsurance; const defaultIsInsuranceSelectedValue = store.getters.order.payment.isInsurance; const hideRecalCost = experimentMixin.methods @@ -311,34 +312,42 @@ export default { if ( serviceLocationState != null && payWithInsuranceStates.find((item) => item === serviceLocationState) - ) + ) { return true; - else if (isInsuranceOverrideValue != null) { - return isInsuranceOverrideValue == "true"; - } else if (defaultIsInsuranceSelectedValue != null) { - return defaultIsInsuranceSelectedValue; - } else { - if (availableLineItems) { - const lineItemsForCalculatingPrice = hideRecalCost - ? baseMixin.methods.filterOutFees( - baseMixin.methods.filterOutRecalibration(availableLineItems) // Strip out recal before filtering out fees - ) - : baseMixin.methods.filterOutFees(availableLineItems); - - return ( - baseMixin.methods.getTierOnePackagePrice(lineItemsForCalculatingPrice) > - insuranceThreshold - ); // compare base price vs arbitrary threshold (representing insurance price) - } else { - return null; - } } + + if (defaultIsInsuranceSelectedValue != null) { + return defaultIsInsuranceSelectedValue; + } + + if (availableLineItems) { + const lineItemsForCalculatingPrice = hideRecalCost + ? baseMixin.methods.filterOutFees( + baseMixin.methods.filterOutRecalibration(availableLineItems) // Strip out recal before filtering out fees + ) + : baseMixin.methods.filterOutFees(availableLineItems); + + if (isInsuranceFromQueryString != null) { + if (isInsuranceFromQueryString == "true") { + return true; + } + } + + return ( + baseMixin.methods.getTierOnePackagePrice(lineItemsForCalculatingPrice) > + insuranceThreshold + ); // compare base price vs arbitrary threshold (representing insurance price) + } + + return null; }; + let thresholdToUse = INSURANCE_TAB_TO_DISPLAY_THRESHOLD_DEFAULT; let internalThreshold = experimentMixin.methods.getSettingValue( experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL ); const isExternalParameter = store.getters.externalParameterState?.isExternalParameter; + console.log("parm:" + isExternalParameter); if (isExternalParameter === externalParameterStatus.NOT_SET) { // there are no active or inactive external parameters; use internal threshold From b383418c5b76eedc06203e6c95e1bbee0d162c4b Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 14 Oct 2024 15:52:04 -0400 Subject: [PATCH 46/96] remove console.log remove console.log --- src/layouts/quote/quote.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 83386e973..61f966a3f 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -347,7 +347,6 @@ export default { experimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL ); const isExternalParameter = store.getters.externalParameterState?.isExternalParameter; - console.log("parm:" + isExternalParameter); if (isExternalParameter === externalParameterStatus.NOT_SET) { // there are no active or inactive external parameters; use internal threshold From ff104643032afe4a6b1692981f358f8daeec36c5 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 15 Oct 2024 07:05:18 -0400 Subject: [PATCH 47/96] CSR-2253 CSR-2253 --- src/layouts/quote/quote.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js index c83801693..24b37d376 100644 --- a/src/layouts/quote/quote.spec.js +++ b/src/layouts/quote/quote.spec.js @@ -376,7 +376,7 @@ describe("quote.vue", () => { //Assert expect(wrapper.vm.isInsuranceSelected).toBe(true); }); - test("should default to cash if query param 'isInsurance' is false", async () => { + test("should use amount threshold if query param 'isInsurance' is false", async () => { //Arrange store.getters = { lineItems: { @@ -403,6 +403,7 @@ describe("quote.vue", () => { settingName: "SERVICE_PACKAGE_DISCOUNT", }, }; + mockTierOnePrice = 200; const { wrapper } = setupMocks({}); //Act From ee79be8396acaa830b60e40c88549a09fd564dda Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 15 Oct 2024 09:36:30 -0400 Subject: [PATCH 48/96] CSR-2253 CSR-2253 if we're loading a session and we do not have a provider number yet, then set isInsurance to null so that a service package is not selected by default on the quote page. --- src/constants/external-parameters.js | 2 +- src/layouts/quote/quote.spec.js | 10 +++++++--- src/router/index.js | 5 ++++- src/store/index.js | 12 +++++++++++- src/store/store.spec.js | 17 +++++++++++++---- 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/constants/external-parameters.js b/src/constants/external-parameters.js index 686e29235..b0adaf836 100644 --- a/src/constants/external-parameters.js +++ b/src/constants/external-parameters.js @@ -3,4 +3,4 @@ const externalParameterStatus = { ACTIVE: 1, INACTIVE: 0, }; -export { externalParameterStatus }; \ No newline at end of file +export { externalParameterStatus }; diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js index 24b37d376..778ce0ce8 100644 --- a/src/layouts/quote/quote.spec.js +++ b/src/layouts/quote/quote.spec.js @@ -73,9 +73,13 @@ jest.mock("@/mixins/experiment-mixin.js", () => ({ if (settingName === mockExperimentSettings.SERVICE_PACKAGE_DISCOUNT) { return true; } - if (settingName === mockExperimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL) { + if ( + settingName === mockExperimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL + ) { return 300; - } else if (settingName === mockExperimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL) { + } else if ( + settingName === mockExperimentSettings.INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL + ) { return 500; } return "test"; @@ -273,7 +277,7 @@ describe("quote.vue", () => { }; const { wrapper } = setupMocks({}); - //mock this to avoid needing to populate this.$route in an unrelated test + //mock this to avoid needing to populate this.$route in an unrelated test wrapper.vm.getDefaultIsInsuranceSelectedValue = jest.fn(); //Act diff --git a/src/router/index.js b/src/router/index.js index 99d63f00d..bc7a5f50a 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -265,7 +265,10 @@ router.beforeEach(async (to, from, next) => { ); // If alert event is on the bus, then display the alert if (alertEvent !== undefined || unknownAlertEvent !== undefined) { - store.commit(storeMutations.UPDATE_IS_EXTERNAL_PARAMETER, externalParameterStatus.INACTIVE); + store.commit( + storeMutations.UPDATE_IS_EXTERNAL_PARAMETER, + externalParameterStatus.INACTIVE + ); } } // fromPaymentToConfirmation workaround for navigating from an iframe but diff --git a/src/store/index.js b/src/store/index.js index d744175c9..d865f756c 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -680,7 +680,17 @@ export const mutations = { sessionInformation.order.serviceLocation.provider?.address?.zipCodeCtu; state.order.serviceLocation.techNotes = sessionInformation.order.serviceLocation.techNotes; - state.order.payment.isInsurance = sessionInformation.order.payment.isInsurance; + // if we're loading a session and we do not have a provider number yet, then set isInsurance to null so that + // a service package is not selected by default on the quote page. + if ( + !sessionInformation.order.payment.isInsurance && + !sessionInformation.order.serviceLocation.provider?.providerNumer + ) { + state.order.payment.isInsurance = null; + } else { + state.order.payment.isInsurance = sessionInformation.order.payment.isInsurance; + } + state.order.payment.insuranceCoverage.isVerified = coverageStatusValue(sessionInformation?.order.insuranceCoverage.coverageStatus) === coverageStatus.VERIFIED diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 4a1cb6173..313e7e37f 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -2934,7 +2934,10 @@ describe("Actions", () => { // Arrange const context = state; const promoCode = "testPromo"; - const lineItemsToUse = { vaps: [{ partNumber: 1 }], promos: [{ promoCode: "1wiper0" }] }; + const lineItemsToUse = { + vaps: [{ partNumber: 1 }], + promos: [{ promoCode: "1wiper0" }], + }; const addableVaps = [{ partNumber: "addableVap" }]; context["getters"] = { @@ -3058,7 +3061,10 @@ describe("Actions", () => { // Arrange const context = state; const promoCode = "testPromo"; - const lineItemsToUse = { vaps: [{ partNumber: 1 }], promos: [{ promoCode: "1wiper0" }] }; + const lineItemsToUse = { + vaps: [{ partNumber: 1 }], + promos: [{ promoCode: "1wiper0" }], + }; const addableVaps = [{ partNumber: "addableVap" }]; context["getters"] = { @@ -3151,7 +3157,10 @@ describe("Actions", () => { crypto.randomUUID = jest.fn(() => "GUID"); - const expectedLineItemsOnOrder = [{ partNumber: 1, isChildPart: false, id: "GUID" }, { promoCode: "1wiper0", isChildPart: false }]; + const expectedLineItemsOnOrder = [ + { partNumber: 1, isChildPart: false, id: "GUID" }, + { promoCode: "1wiper0", isChildPart: false }, + ]; // Act actions.validateOrderPromoAndSaveServerData(context, { @@ -3440,7 +3449,7 @@ describe("Actions", () => { lineItems: { serverData: "test", promos: [{ promoCode: "test", isChildPart: false }], - vaps: [{ partNumber: "testVap", isChildPart:false, id: "providedId" }], + vaps: [{ partNumber: "testVap", isChildPart: false, id: "providedId" }], }, }, }; From d5378109c623aeabd6caf35698f6500406b84399 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Tue, 15 Oct 2024 17:02:03 -0400 Subject: [PATCH 49/96] Update calls for service location page --- src/helpers/recal-helper.js | 8 ++++++++ src/store/index.js | 35 +++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/helpers/recal-helper.js b/src/helpers/recal-helper.js index fa33e7849..c73755e8f 100644 --- a/src/helpers/recal-helper.js +++ b/src/helpers/recal-helper.js @@ -50,3 +50,11 @@ export function getItemsWithoutRecalParts(lineItems) { return childrenFiltered; } + +export function getTopLevelPartsWithRecal(lineItems) { + if (!lineItems) { + return null; + } + + return lineItems.filter((li) => isRecalPartOrHasChildRecalPart(li)); +} diff --git a/src/store/index.js b/src/store/index.js index d865f756c..437776755 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -41,7 +41,7 @@ import { coverageTypeValue, coverageTypeEnum, } from "@/constants/insurance"; -import { containsRecalParts } from "@/helpers/recal-helper"; +import { containsRecalParts, getTopLevelPartsWithRecal } from "@/helpers/recal-helper"; import { externalParameterStatus } from "@/constants/external-parameters"; import { experimentSettings } from "@/constants/experiments"; import experimentMixin from "@/mixins/experiment-mixin.js"; @@ -1622,16 +1622,19 @@ export const actions = { }, getServiceabilityDetails(context, { payload: { serviceZipCode }, pageNameToLog }) { - const lineItemsWithOnlyPartNumbers = context.getters.order.lineItems.supportingItems?.map( + const escapeRecalibrationType = (rt) => rt.split("&").join("%26"); + + const partialLineItemsObjects = context.getters.order.lineItems.glassParts?.map( (lineItem) => ({ partNumber: lineItem.partNumber, + recalibrationType: lineItem.recalibrationType ? escapeRecalibrationType(lineItem.recalibrationType) : undefined, }) ); var lineItems = null; - if (lineItemsWithOnlyPartNumbers) { + if (partialLineItemsObjects) { lineItems = buildQueryStringParameterFromArrayOfComplexObjects( - lineItemsWithOnlyPartNumbers, + partialLineItemsObjects, "lineItems" ); } @@ -1646,7 +1649,12 @@ export const actions = { "glassPieces" ); - var endPoint = `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}`; + const parentAccountNumber = + context.getters.order.payment.parentAccountNumber ?? + applicationConfig.CASH_PARENT_ACCOUNT_NUMBER; + const referralSequenceNumber = context.getters.order.referralSequenceNumber; + + var endPoint = `${endpoints.GetServiceabilityDetails.url}?zip=${serviceZipCode}&carId=${carId}&parentAccountNumber=${parentAccountNumber}&referralSequenceNumber=${referralSequenceNumber}`; if (lineItems) { endPoint += `&${lineItems}`; } @@ -1665,11 +1673,26 @@ export const actions = { getProviders(context, { payload: { serviceZipCode }, pageNameToLog }) { const damageType = context.getters.damage.isRepair ? "Repair" : "Replace"; + const accountNumber = + context.getters.order.payment.parentAccountNumber ?? + applicationConfig.CASH_PARENT_ACCOUNT_NUMBER; + const carId = context.getters.order.vehicle.carId; + const partsWithRecal = getTopLevelPartsWithRecal( + context.getters.order.lineItems.glassParts + ); + const windshieldPartWithRecal = partsWithRecal?.length > 0 ? partsWithRecal[0] : null; + const shopRadiusInMiles = 100; + let url = `${endpoints.GetProviders.url}/${serviceZipCode}/${damageType}/${shopRadiusInMiles}/${accountNumber}/true/${carId}`; + + if (windshieldPartWithRecal) { + url += `/${windshieldPartWithRecal.partNumber}`; + } + return globalMethods.callHttpClient({ method: endpoints.GetProviders.method, - endpoint: `${endpoints.GetProviders.url}/${serviceZipCode}/${damageType}/${shopRadiusInMiles}`, + endpoint: url, logApiCall: true, pageNameToLog: pageNameToLog, }); From b8c17ca75f1f5adc0370c399e642840ba37eeec1 Mon Sep 17 00:00:00 2001 From: Chloe Herd Date: Wed, 16 Oct 2024 15:32:59 -0400 Subject: [PATCH 50/96] Update quote page spacing --- .../service-package-radio/service-package-radio.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue b/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue index b0e10df95..4a7fd38d4 100644 --- a/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue +++ b/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue @@ -78,7 +78,7 @@ @@ -138,7 +138,7 @@ export default { From 2197ef8e6104ddff0bf1378c09dfad94c7c255b6 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Fri, 18 Oct 2024 13:29:44 -0400 Subject: [PATCH 55/96] Remove commented code. --- .../service-package-radio.vue | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue b/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue index 59837b94d..f873b3fc1 100644 --- a/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue +++ b/src/layouts/quote/service-package-question/service-package-radio/service-package-radio.vue @@ -1,8 +1,4 @@