From ccc3feb15ef22a8ffd00299d2015236089b6f9b3 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Fri, 24 Jan 2025 13:50:40 -0500 Subject: [PATCH 1/3] CASH-160 CASH-160 promo code lost coming from content site /cjrepair. Added all passed querystring keys to the redirect to return-user so they're not lost. --- src/helpers/querystring-helper.js | 14 ++++++++++++++ src/router/index.js | 11 +++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/helpers/querystring-helper.js b/src/helpers/querystring-helper.js index 38583b1ae..8c40c91b7 100644 --- a/src/helpers/querystring-helper.js +++ b/src/helpers/querystring-helper.js @@ -8,3 +8,17 @@ export function getQuerystringParameter(key) { return lowerCaseParams.get(key) ? lowerCaseParams.get(key) : null; } + +// if you add the fmgPage to the querystringobject before calling, then pass true for skipFmgPageName +export function buildQuerystringObject(qso, skipFmgPageName=false) { + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + + for (const [name, value] of urlParams) { + if (name.toLowerCase() === "fmgpage" && skipFmgPageName) { + continue; + } + qso[name] = value; + } + return qso; +} \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index d956af773..73a8545f3 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -6,7 +6,7 @@ import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js" import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; import { queryStrings } from "@/constants/query-strings"; -import { getQuerystringParameter } from "@/helpers/querystring-helper"; +import { getQuerystringParameter, buildQuerystringObject } 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"; @@ -108,14 +108,13 @@ const routes = [ var qso = { fmgPage: fmgPageValues.RETURN_USER, }; - const lg = getQuerystringParameter(queryStrings.LOG); - if (lg) { - qso[queryStrings.LOG] = true; - } + + const newQueryString = buildQuerystringObject(qso, true); + log(" -- returnUser add querystring: " + JSON.stringify(newQueryString)); router.push({ path: "/", - query: Object.assign({}, qso), + query: Object.assign({}, newQueryString), }); return; } From 2a97b02b040637c4a8a73493a1daa1e49eda82c1 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Mon, 27 Jan 2025 17:30:40 +0530 Subject: [PATCH 2/3] CASH-57 Remove zip code matching condition causing zip code state validation --- .../mobile-location-modal-questions.vue | 79 ++++++++----------- 1 file changed, 34 insertions(+), 45 deletions(-) diff --git a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue index 84087cb6e..d88bd53e2 100644 --- a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue +++ b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue @@ -241,57 +241,46 @@ export default { this.displayMismatchStateAndZipAlert = false; }, async setMobileLocation() { - if ( - this.internalModel.addressQuestions.zipCode !== - this.modelValue.addressQuestions.zipCode - ) { - this.resetAlerts(); - // Validate the Zip Code - const zipCodeData = await this.getZipCodeData( - this.internalModel.addressQuestions.zipCode, + this.resetAlerts(); + // Validate the Zip Code + const zipCodeData = await this.getZipCodeData( + this.internalModel.addressQuestions.zipCode, + "service-location" + ); + + if (!zipCodeData.isValid) { + this.displayInvalidZipAlert = true; + this.resetModalButtonStyle(); + } else if (zipCodeData.state != this.internalModel.addressQuestions.state) { + this.displayMismatchStateAndZipAlert = true; + this.resetModalButtonStyle(); + } else { + // retrieve mobile fee part + const serviceZipCode = this.internalModel.addressQuestions.zipCode; + const mobileFeePart = await getPricedMobileFeePart( + serviceZipCode, "service-location" ); - if (!zipCodeData.isValid) { - this.displayInvalidZipAlert = true; - this.resetModalButtonStyle(); - } else if (zipCodeData.state != this.internalModel.addressQuestions.state) { - this.displayMismatchStateAndZipAlert = true; - this.resetModalButtonStyle(); - } else { - // retrieve mobile fee part - const serviceZipCode = this.internalModel.addressQuestions.zipCode; - const mobileFeePart = await getPricedMobileFeePart( - serviceZipCode, - "service-location" - ); + // retrieve serviceability details + const serviceabilityDetails = await getServiceabilityDetails( + serviceZipCode, + null, + "service-location" + ); - // retrieve serviceability details - const serviceabilityDetails = await getServiceabilityDetails( - serviceZipCode, - null, - "service-location" - ); + const billToAccountNumber = await getBillToAccountNumber( + this.internalModel.zipCodeCtu + ); - const billToAccountNumber = await getBillToAccountNumber( - this.internalModel.zipCodeCtu - ); + // update content related to service zip code + this.$emit("updated-mobile-fee-part", mobileFeePart); + this.$emit("updated-serviceability", serviceabilityDetails.data); + this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase); + this.$emit("updated-mobile-ctu", zipCodeData.zipCodeCtu); + this.$emit("updated-bill-to-account-number", billToAccountNumber); - // update content related to service zip code - this.$emit("updated-mobile-fee-part", mobileFeePart); - this.$emit("updated-serviceability", serviceabilityDetails.data); - this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase); - this.$emit("updated-mobile-ctu", zipCodeData.zipCodeCtu); - this.$emit("updated-bill-to-account-number", billToAccountNumber); - - // update the page level model - this.$emit("update:modelValue", this.internalModel); - - //Page advance to Schedule page - this.$emit("mobileLocationSelected"); - } - } else { - // Update the page level model + // update the page level model this.$emit("update:modelValue", this.internalModel); //Page advance to Schedule page From c5ad651546aebfdf8e63ce95b9f5e2a1a94e5a5a Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 27 Jan 2025 13:50:21 -0500 Subject: [PATCH 3/3] CASH-109 CASH-109 do not use the funnel session cookie as it will be deleted when the browser closes. instead, look at vuex and make sure they at least have a vehicle year to determine if they have visited the site before. --- src/fmg-components/nav-bar/nav-bar.vue | 8 ++++---- src/layouts/quote/quote.vue | 2 +- src/layouts/vehicle-parts/vehicle-parts.vue | 2 +- src/mixins/analytics-mixin.js | 10 ++-------- src/router/index.js | 19 ++++++++----------- 5 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/fmg-components/nav-bar/nav-bar.vue b/src/fmg-components/nav-bar/nav-bar.vue index 6f981f9e0..f23ecd244 100644 --- a/src/fmg-components/nav-bar/nav-bar.vue +++ b/src/fmg-components/nav-bar/nav-bar.vue @@ -97,16 +97,16 @@ export default { document.onkeydown = function (e) { return false; }; - // check session expired and initSession to recreate cookies - if (analyticsMixin.methods.sessionExpired()) { + // check session expired and initSession to recreate cookies + if (analyticsMixin.methods.sessionExpired()) { this.routeReturnUser(); } else { this.$emit("ForwardClicked"); } }, linkClick() { - // check session expired and initSession to recreate cookies - if (analyticsMixin.methods.sessionExpired()) { + // check session expired and initSession to recreate cookies + if (analyticsMixin.methods.sessionExpired()) { this.routeReturnUser(); } else { this.$emit("BackClicked"); diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index f3590cbc3..860aaf087 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -298,7 +298,7 @@ export default { // to restore, uncomment the 2 lines below // vm.showSaveProgressPopup = showSaveProgressPopup; // vm.showSaveProgressModal = showSaveProgressModal; - + vm.addableVaps = addableVaps; vm.lineItems = lineItems; vm.availableLineItems = pricingResults; diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index 43f66c376..832589043 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -97,7 +97,7 @@ export default { // turned off Save Your Progress for 1/23/25 release // to restore, uncomment line below // vm.showSaveProgressModal = !(emailFromStore?.length > 0); - + // Glass Part Question dynamic component Object.keys(vm.$refs) .filter((r) => r.includes(vm.RefPrefix) && vm.$refs[r][0] !== undefined) diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 1c70722a1..9bb8f0cda 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -712,16 +712,10 @@ export default { return !areAllSessionCookiesSet(); }, - // sessionExpired is true when one of the analytics cookies(sid, dxdev) has expired but we still have the funnelSessionInfo cookie + // sessionExpired is true when one of the analytics cookies(sid, dxdev) has expired but we still have the vehicle year in vuex sessionExpired() { const fromHeritage = getQuerystringParameter(queryStrings.FROM_HERITAGE) === "true"; - const funnelCookieLastTouched = getFunnelCookie()?.LastTouched; - if ( - this.noSession() && - !fromHeritage && - funnelCookieLastTouched !== null && - funnelCookieLastTouched !== undefined - ) { + if (this.noSession() && !fromHeritage && store.getters.order.vehicle?.year > 0) { return true; } else { return false; diff --git a/src/router/index.js b/src/router/index.js index 49d3b0e4f..adbb2d022 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -57,7 +57,7 @@ const routes = [ log(` --from.redirectedFrom:>${JSON.stringify(from.redirectedFrom)}<`, ""); await analyticsMixin.methods.validateSession(); - + // after session is validated, remove the fromHeritage querystring if it exists so session expiration works if (to.query) { delete to.query[queryStrings.FROM_HERITAGE]; @@ -100,14 +100,12 @@ const routes = [ } // On entering the funnel "fresh", read cookie information, decide what to do next. else if (from.redirectedFrom === undefined || fromReturnUser) { - // if entering the funnel from the content site, check and see if there is already a funnel cookie. + // if entering the funnel from the content site, check and see if there is already a vehicle year in vuex. // if so, send them to return-user page. - const funnelCookieLastTouched = getFunnelCookie()?.LastTouched; if ( fromContentSite && - funnelCookieLastTouched !== null && - funnelCookieLastTouched !== undefined && - !toReturnUserPage + !toReturnUserPage && + store.getters.order.vehicle?.year > 0 ) { log(" --from content site navigate to return user"); var qso = { @@ -178,8 +176,7 @@ const routes = [ // clear part related state because heritage selected a new vehicle if ( to.query.fmgPage === fmgPageValues.VEHICLE && - eval(getFunnelCookie()?.HasDelayedClaimRegistration && - !fromReturnUser) + eval(getFunnelCookie()?.HasDelayedClaimRegistration && !fromReturnUser) ) { store.commit(storeMutations.RESET_GLASS_PARTS_STATE); } @@ -187,7 +184,7 @@ const routes = [ // if coming from the return user page, clear the destination page so implicit navigation runs log(" --to.query ", JSON.stringify(to.query)); if (fromReturnUser && to.query) { - log( " --clear to.query"); + log(" --clear to.query"); delete to.query[queryStrings.FMG_PAGE]; //to.query[queryStrings.FMG_PAGE] = ""; @@ -571,7 +568,7 @@ async function navigate( const pageError = getQuerystringParameter(queryStrings.PAGE_ERROR); const logQs = getQuerystringParameter(queryStrings.LOG); baseMixin.methods.dispatchStoreAction(storeActions.SAVE_LOGGING_OPTION, logQs, false); - + log("------------- router index.js navigate start -----------------"); log(" --scenario: ", scenario); log(" --isSavingNavigation: ", isSavingNavigation); @@ -636,7 +633,7 @@ function getNavigationMap(scenario, currentRoute) { function log(message, data) { const log = getQuerystringParameter(queryStrings.LOG); baseMixin.methods.dispatchStoreAction(storeActions.SAVE_LOGGING_OPTION, log, false); - + data = data ?? ""; const outData = typeof data === "object" ? JSON.stringify(data) : data;