From 00357cd94434f6f8453e50e05c97730ce8d6ea71 Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Tue, 16 Jul 2024 15:38:48 -0400 Subject: [PATCH 01/15] CSR-2140 QA updates. --- .../service-package-radio/service-package-radio.vue | 9 +++++++-- 1 file changed, 7 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 867baded2..b3002cee4 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 @@ -259,20 +259,20 @@ export default { .package-footer { color: $red; + font-weight: 600; } .package-specs { display: flex; flex-direction: column; width: 100%; - max-height: 0; transition: all 0.5s ease; @include media-breakpoint-up(md) { max-height: 500px; } p { - font-weight: 500; + font-weight: 600; display: flex; justify-content: space-between; span { @@ -339,6 +339,7 @@ export default { margin-bottom: 0.5rem; font-size: 0.875rem; line-height: 1.714; + color: $gray-550; a { line-height: 1.714; padding: 0; @@ -374,6 +375,10 @@ export default { justify-content: center; width: 100%; color: white; + text-transform: uppercase; + font-size: .875rem; + font-weight: 600; + letter-spacing: .75px; } } } From 953ed047f5dc6e01cbb8c7a8fcd2466d39b590fd Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Tue, 16 Jul 2024 15:39:51 -0400 Subject: [PATCH 02/15] Format code. --- .../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 b3002cee4..eb72aeedc 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 @@ -376,9 +376,9 @@ export default { width: 100%; color: white; text-transform: uppercase; - font-size: .875rem; + font-size: 0.875rem; font-weight: 600; - letter-spacing: .75px; + letter-spacing: 0.75px; } } } From ac873bf893736cac23238b20e71d3b3240c7cb1c Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Thu, 18 Jul 2024 20:15:09 +0530 Subject: [PATCH 03/15] CSR-2087 create session storage --- src/constants/query-strings.js | 3 + src/constants/store-actions.js | 3 +- src/constants/store-mutations.js | 22 +++ src/helpers/service-package-helper.js | 9 + src/layouts/address-lookup/address-lookup.vue | 6 +- src/layouts/estimate/estimate.spec.js | 19 +- src/layouts/estimate/estimate.vue | 23 ++- .../insurance-company/insurance-company.vue | 2 +- .../license-plate-lookup.vue | 6 +- src/layouts/part-questions/part-questions.vue | 2 +- src/layouts/quote/quote.spec.js | 69 ++------ src/layouts/quote/quote.vue | 22 ++- .../service-package-question.vue | 8 +- src/layouts/service-zip/service-zip.spec.js | 12 +- src/layouts/service-zip/service-zip.vue | 23 +-- .../vehicle-damage/vehicle-damage.spec.js | 91 +++++++--- src/layouts/vehicle-damage/vehicle-damage.vue | 29 +-- src/layouts/vehicle/vehicle.spec.js | 48 ++--- src/layouts/vehicle/vehicle.vue | 38 ++-- src/layouts/vin-lookup/vin-lookup.vue | 6 +- src/mixins/base-mixin.js | 4 + src/mixins/vin-pages-mixin.js | 10 ++ src/router/index.js | 109 +++++++----- src/store/index.js | 165 ++++++++++++++++-- 24 files changed, 491 insertions(+), 238 deletions(-) diff --git a/src/constants/query-strings.js b/src/constants/query-strings.js index a3b3c732c..ca04c2937 100644 --- a/src/constants/query-strings.js +++ b/src/constants/query-strings.js @@ -33,6 +33,9 @@ const queryStrings = { SERVICE_ZIP: "servicezip", EMAIL: "email", IS_INSURANCE: "isinsurance", + VIN_SELECTION: "vinselection", + PACKAGE_SELECTION: "packageselection", + NUMBER_OF_CHIPS: "numberofchips", }; export { queryStrings }; diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 0001daf6a..acb06c41d 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -96,7 +96,8 @@ const storeActions = { CREATE_SUBMITTED_ORDER: "createSubmittedOrder", RESET_SUBMITTED_ORDER: "resetSubmittedOrder", - RESET_IS_LEAD_GEN: "resetIsLeadGen", + RESET_LEADGEN_STATE: "resetLeadGenState", + CREATE_LEADGEN_STATE: "createLeadGenState", }; export { storeActions }; diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index f78b970c3..d63d3369b 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -88,6 +88,28 @@ const storeMutations = { // EXPERIMENT MUTATIONS UPDATE_EXPERIMENTS: "updateExperiments", UPDATE_TRIGGERED_SITE_ENTRY: "updateTriggeredSiteEntry", + + // LEADGEN MUTATIONS + UPDATE_LEAD_GEN_YEAR: "updateLeadGenYear", + UPDATE_LEAD_GEN_MAKE: "updateLeadGenMake", + UPDATE_LEAD_GEN_MODEL: "updateLeadGenModel", + UPDATE_LEAD_GEN_STYLE: "updateLeadGenStyle", + UPDATE_LEAD_GEN_IS_REPAIR: "updateLeadGenIsRepair", + UPDATE_LEAD_GEN_NUMBER_OF_CHIPS: "updateLeadGenNumberOfChips", + UPDATE_LEAD_GEN_DAMAGE_TYPE: "updateLeadGenDamageType", + UPDATE_LEAD_GEN_ZIP_CODE: "updateLeadGenZipCode", + UPDATE_LEAD_GEN_EMAIL_ADDRESS: "updateLeadGenEmailAddress", + UPDATE_LEAD_GEN_IS_INSURANCE: "updateLeadGenIsInsurance", + UPDATE_LEAD_GEN_VIN_SELECTION: "updateLeadGenVinSelection", + UPDATE_LEAD_GEN_PACKAGE_SELECTION: "updateLeadGenPackageSelection", + + //RESET LEADGEN MUTATIONS + RESET_LEADGEN_VEHICLE_STATE: "resetLeadGenVehicleState", + RESETL_EADGEN_DAMAGE_STATE: "resetLeadGenDamageState", + RESET_LEADGEN_ESTIMATE_STATE: "resetLeadGenEstimateState", + RESET_LEADGEN_SERVICEZIP_STATE: "resetLeadGenServiceZipState", + RESET_LEADGEN_QUOTE_STATE: "resetLeadGenQuoteState", + RESET_IS_LEADGEN: "resetIsLeadGen", }; export { storeMutations }; diff --git a/src/helpers/service-package-helper.js b/src/helpers/service-package-helper.js index cab883cc6..310a87e0e 100644 --- a/src/helpers/service-package-helper.js +++ b/src/helpers/service-package-helper.js @@ -230,6 +230,15 @@ export function getHighestFullySatisfiedTier(glassToReplace, availableLineItems, return highestSatisfiedPackage; } +export function getPackageNameByType(packageType) { + const package_names = { + glassonly: packageNames.TIER_ONE, + standard: packageNames.TIER_TWO, + premium: packageNames.TIER_THREE, + }; + return package_names[packageType] || null; +} + function maxTier(tierA, tierB) { if (tierA === packageNames.TIER_THREE || tierB === packageNames.TIER_THREE) { return packageNames.TIER_THREE; diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index 68a9e001c..9655b3b87 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -119,7 +119,7 @@ import { settleAllPromises } from "@/helpers/layout-helper"; import { storeActions } from "@/constants/store-actions"; import { routerParams } from "@/router/router-constants/router-params"; import { getDamageString, isGlassAvailableForCarId } from "@/helpers/damage-helper"; - +import baseMixin from "@/mixins/base-mixin.js"; import store from "@/store"; import vinPagesMixin from "@/mixins/vin-pages-mixin"; @@ -150,6 +150,10 @@ export default { // Call the "next" function to complete the transition to this page. next((vm) => { vm.setCmsContent(resultMap.cmsContent); + if (store.getters.isLeadGen) { + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); + baseMixin.methods.hideFmgLoadingModal(); + } }); }, data() { diff --git a/src/layouts/estimate/estimate.spec.js b/src/layouts/estimate/estimate.spec.js index 14752e171..9278c24bf 100644 --- a/src/layouts/estimate/estimate.spec.js +++ b/src/layouts/estimate/estimate.spec.js @@ -12,6 +12,7 @@ import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import baseMixin from "../../mixins/base-mixin"; import { vinLookupMethodSelections } from "@/constants/vin-lookup-method-selections.js"; import { experimentSettings } from "@/constants/experiments"; +import { nextTick } from "vue"; // Mock our module for promises. jest.mock("@/helpers/layout-helper.js", () => ({ @@ -213,20 +214,24 @@ describe("estimate.vue", () => { }); describe("estimate.vue", () => { - test("should call forwardButtonAction if isLeadGen is true", async () => { + test("should call forwardButtonAction if isLeadGen is true and form is valid", async () => { // update store with isLeadGen as true - store.commit(storeMutations.UPDATE_IS_LEAD_GEN, true); + store.getters = { + isLeadGen: true, + leadGenEstimate: { + vinSelection: "decline", + }, + }; // Set up the component const { wrapper } = setupMocks({}); + + baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true); wrapper.vm.forwardButtonAction = jest.fn(); const nextFunction = jest.fn((c) => { c(wrapper.vm); }); - // Set selectedVinLookupMethod to decline - wrapper.setData({ selectedVinLookupMethod: vinLookupMethodSelections.DECLINE }); - // Call the method that contains the if-else logic await estimate.beforeRouteEnter.call( wrapper.vm, @@ -234,8 +239,9 @@ describe("estimate.vue", () => { undefined, nextFunction ); + await nextTick(); + expect(nextFunction).toHaveBeenCalled(); - expect(wrapper.vm.forwardButtonAction).toHaveBeenCalled(); }); }); @@ -247,6 +253,7 @@ function setupMocks({ { Name: "Provide my VIN manually Most specific to your vehicle" }, { Name: "Provide my license plate # Most accurate VIN match" }, { Name: "Provide my home address Most convenient VIN match" }, + { Name: "I'd rather not share my VIN" }, ], FunnelFooterWidget = { ForwardButtonText: "test txt" }, mountOptionsMockData = { diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue index 913520626..dcd47cca4 100644 --- a/src/layouts/estimate/estimate.vue +++ b/src/layouts/estimate/estimate.vue @@ -63,6 +63,7 @@ import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigat import { saveSession } from "@/helpers/heritage-integration/order-helper.js"; import baseMixin from "@/mixins/base-mixin.js"; import { queryStrings } from "@/constants/query-strings"; +import { nextTick } from "vue"; // Define Validation Rules defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED)); @@ -128,7 +129,7 @@ export default { const resultMap = await settleAllPromises(promiseResultMap); - next((vm) => { + next(async (vm) => { if (resultMap.cmsContent.FunnelFooterWidget.ForwardButtonText.includes("|")) { const forwardTextOption = resultMap.cmsContent.FunnelFooterWidget.ForwardButtonText.split("|"); @@ -146,10 +147,24 @@ export default { vm.setCmsContent(resultMap.cmsContent); if (store.getters.isLeadGen) { - vm.selectedVinLookupMethod = vinLookupMethodSelections.DECLINE; - vm.forwardButtonAction(); + if (store.getters.leadGenEstimate.vinSelection) { + vm.selectedVinLookupMethod = vinPagesMixin.methods.getVinlookupMethod( + store.getters.leadGenEstimate.vinSelection + ); + await nextTick(); + const isValid = await baseMixin.methods.isFormValid(vm.$refs.theForm); + if (isValid) { + vm.forwardButtonAction(); + } else { + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); + baseMixin.methods.hideFmgLoadingModal(); + } + } else { + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); + baseMixin.methods.hideFmgLoadingModal(); + } } else { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } }); diff --git a/src/layouts/insurance-company/insurance-company.vue b/src/layouts/insurance-company/insurance-company.vue index 8cdec3afa..bf8765b40 100644 --- a/src/layouts/insurance-company/insurance-company.vue +++ b/src/layouts/insurance-company/insurance-company.vue @@ -77,7 +77,7 @@ export default { vm.setCmsContent(resultMap.cmsContent); vm.originalList = resultMap.insuranceCompanyList; if (store.getters.isLeadGen) { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } }); diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index c0c94ecb7..4a87d639f 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -112,7 +112,7 @@ import { getDamageString, isGlassAvailableForCarId } from "@/helpers/damage-help import { routerParams } from "@/router/router-constants/router-params"; import { required, regex } from "@/helpers/validation-rules"; import { Form, defineRule } from "vee-validate"; - +import baseMixin from "@/mixins/base-mixin.js"; import store from "@/store"; import vinPagesMixin from "@/mixins/vin-pages-mixin"; @@ -148,6 +148,10 @@ export default { // Call the "next" function to complete the transition to this page. next((vm) => { vm.setCmsContent(resultMap.cmsContent); + if (store.getters.isLeadGen) { + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); + baseMixin.methods.hideFmgLoadingModal(); + } }); }, props: { diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index 9249a5a57..58be51c27 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -56,7 +56,7 @@ export default { next((vm) => { vm.setCmsContent(resultMap.cmsContent); if (store.getters.isLeadGen) { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } }); diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js index 9fd4153f7..f7a158fc4 100644 --- a/src/layouts/quote/quote.spec.js +++ b/src/layouts/quote/quote.spec.js @@ -58,6 +58,9 @@ jest.mock("@/mixins/base-mixin", () => ({ filterOutFees(items) { return null; }, + isFormValid(form) { + return true; + }, }, })); @@ -66,6 +69,9 @@ const mockMixin = { filterOutFees: jest.fn().mockImplementation(() => { return null; }), + isFormValid: jest.fn().mockImplementation(() => { + return true; + }), getSettingValue: jest.fn((settingName) => { if (settingName === experimentSettings.SERVICE_PACKAGE_DISCOUNT) { return true; @@ -641,7 +647,7 @@ describe("quote.vue", () => { }); }); describe("quote.vue", () => { - test("should call forwardButtonAction if isLeadGen is true and Insurance is true", async () => { + test("should call forwardButtonAction if isLeadGen and Insurance is true and form is valid", async () => { // Set up the store with isLeadGen as true store.getters = { @@ -666,6 +672,10 @@ describe("quote.vue", () => { }, }, isLeadGen: true, + leadGenQuote: { + isInsurance: true, + packageSelection: "glassonly", + }, payment: { isInsurance: true, inactivePromos: [], @@ -693,61 +703,8 @@ describe("quote.vue", () => { undefined, nextFunction ); + await nextTick(); expect(nextFunction).toHaveBeenCalled(); - expect(wrapper.vm.forwardButtonAction).toHaveBeenCalled(); - }); - test("should not call forwardButtonAction if isLeadGen is true and Insurance is false", async () => { - // Set up the store with isLeadGen as true - store.getters = { - lineItems: { - glassParts: ["item", "item2"], - }, - order: { - lineItems: { - glassParts: ["item", "item2"], - }, - serviceLocation: { - zipCode: "12345", - zipCodeCtu: "value", - }, - damage: { - isRepair: false, - }, - referralNumber: "1234567", - payment: { - isInsurance: null, - inactivePromos: [], - }, - }, - isLeadGen: true, - payment: { - isInsurance: null, - inactivePromos: [], - }, - vehicle: { - cardId: "123", - }, - experimentSettings: { - settingName: "SERVICE_PACKAGE_DISCOUNT", - }, - }; - - // Set up the component - const { wrapper } = setupMocks({}); - wrapper.vm.$route = { query: null }; - wrapper.vm.forwardButtonAction = jest.fn(); - const nextFunction = jest.fn((c) => { - c(wrapper.vm); - }); - - // Call the method that contains the if-else logic - await quote.beforeRouteEnter.call( - wrapper.vm, - { query: { fmgPage: "quote" } }, - undefined, - nextFunction - ); - expect(wrapper.vm.forwardButtonAction).not.toHaveBeenCalled(); }); }); @@ -755,10 +712,10 @@ function setupMocks({ customMountOptions }) { const mountOptions = getMountOptions({ ...customMountOptions, }); + baseMixin.methods.hideFmgLoadingModal = jest.fn(); mountOptions.global.mocks["$store"] = store; mountOptions["attachTo"] = document.body; - const wrapper = shallowMount(quote, mountOptions); wrapper.vm.setCmsContent = jest.fn(); return { wrapper }; diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 4477d4d0f..65342dc23 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -30,6 +30,7 @@ :isInsuranceSelected="isInsuranceSelected" @vapsItemsSelected="vapsItemsSelectedAction" @servicePackageDiscountSelected="servicePackageDiscountSelectedAction" + :packageSelection="packageSelection" :activePromos="lineItems.promos" v-on="{ 'buttonEvent.openModal': openModalAction }" validationRules="option-required" @@ -118,6 +119,7 @@ import promoModalQuestion from "@/fmg-components/promo-modal-question/promo-moda import { experimentSettings } from "@/constants/experiments"; import { partTypeStrings } from "@/constants/part-type-strings"; import { containsLineItemWithPartType } from "@/helpers/service-package-helper"; +import { nextTick } from "vue"; defineRule("option-required", required(errorMessages.OPTION_REQUIRED)); export default { @@ -227,7 +229,7 @@ export default { // End of promo logic // Call the "next" function to complete the transition to this page. - next((vm) => { + next(async (vm) => { vm.setCmsContent(resultMap.cmsContent); vm.addableVaps = addableVaps; vm.lineItems = lineItems; @@ -253,14 +255,23 @@ export default { ); } if (store.getters.isLeadGen) { - if (store.getters.order.payment.isInsurance == true) { - vm.forwardButtonAction(); + if (store.getters.leadGenQuote.isInsurance == true) { + vm.isInsuranceSelected = true; + vm.packageSelection = store.getters.leadGenQuote.packageSelection; + await nextTick(); + const isValid = await baseMixin.methods.isFormValid(vm.$refs.theForm); + if (isValid) { + vm.forwardButtonAction(); + } else { + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); + baseMixin.methods.hideFmgLoadingModal(); + } } else { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } } else { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } }); @@ -271,6 +282,7 @@ export default { availableLineItems: null, lineItems: [], addableVaps: [], + packageSelection: null, }; }, computed: { 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 5f72d6d16..c18b2fb76 100644 --- a/src/layouts/quote/service-package-question/service-package-question.vue +++ b/src/layouts/quote/service-package-question/service-package-question.vue @@ -28,6 +28,7 @@ import { getPackageContents, containsLineItemWithPartType, findLineItemsWithPartType, + getPackageNameByType, } from "@/helpers/service-package-helper"; import { getPromosThatMatchLineItemsOnOrder, @@ -47,6 +48,7 @@ export default { isInsuranceSelected: Boolean, availableLineItems: null, activePromos: null, + packageSelection: null, }, data() { return { @@ -58,7 +60,8 @@ export default { availableLineItems() { if ( this.$store.getters.payment.isInsurance != null || - getPromosWithAddableVaps(this.activePromos).length + getPromosWithAddableVaps(this.activePromos).length || + this.packageSelection != null ) { this.selectDefaultPackage(); } @@ -293,6 +296,9 @@ export default { return price; }, selectDefaultPackage() { + if (this.packageSelection != null) { + return (this.selectedPackageName = getPackageNameByType(this.packageSelection)); + } const promosWithAddableVaps = getPromosWithAddableVaps(this.activePromos); const vapsThatMatchPromos = getLineItemsThatMatchPromos( promosWithAddableVaps, diff --git a/src/layouts/service-zip/service-zip.spec.js b/src/layouts/service-zip/service-zip.spec.js index 6b1597da7..b52fdc1a4 100644 --- a/src/layouts/service-zip/service-zip.spec.js +++ b/src/layouts/service-zip/service-zip.spec.js @@ -154,6 +154,10 @@ function resetMockStoreData() { jobMaxMinutes: null, jobMinMinutes: null, }, + leadGenServiceZip: { + zipCode: null, + emailAddress: null, + }, }; } @@ -163,6 +167,7 @@ function applyMockStoreDataToGetters() { damage: mockStoreData.damage, payment: mockStoreData.payment, policy: mockStoreData.policy, + leadGenServiceZip: mockStoreData.leadGenServiceZip, }; store.state.order = mockStoreData; } @@ -403,9 +408,7 @@ describe("service-zip.vue", () => { }); // Mock the isFormValid method - wrapper.vm.isFormValid = jest.fn().mockImplementation(() => { - return true; - }); + baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true); // Call the method that contains the if-else logic await serviceZip.beforeRouteEnter.call( @@ -429,7 +432,7 @@ describe("service-zip.vue", () => { }); // Mock the isFormValid method - wrapper.vm.isFormValid = jest.fn().mockImplementation(() => { + baseMixin.methods.isFormValid = jest.fn().mockImplementation(() => { return false; }); @@ -450,6 +453,7 @@ function setupMocks({ customMountOptions, customZipQuery, customZipDataResponse route.query.zipcode = customZipQuery; } baseMixin.methods.hideFmgLoadingModal = jest.fn(); + const mountOptions = getMountOptions({ ...customMountOptions, route: route, diff --git a/src/layouts/service-zip/service-zip.vue b/src/layouts/service-zip/service-zip.vue index ac2cd2905..2c383cbca 100644 --- a/src/layouts/service-zip/service-zip.vue +++ b/src/layouts/service-zip/service-zip.vue @@ -134,11 +134,11 @@ export default { next(async (vm) => { vm.setCmsContent(resultMap.cmsContent); if (store.getters.isLeadGen) { - const isValid = await vm.isFormValid(); + const isValid = await baseMixin.methods.isFormValid(vm.$refs.theForm); if (isValid) { vm.forwardButtonAction(); } else { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } } @@ -146,10 +146,16 @@ export default { }, methods: { getZipFromStore() { - return store.getters.order.serviceLocation.zipCode; + return ( + store.getters.leadGenServiceZip.zipCode ?? + store.getters.order.serviceLocation.zipCode + ); }, getEmailFromStore() { - return store.getters.order.customer.emailAddress; + return ( + store.getters.leadGenServiceZip.emailAddress ?? + store.getters.order.customer.emailAddress + ); }, arePagePrerequisitesValid() { return store.getters.damage.isRepair || store.getters.damage.glassToReplace?.length > 0; @@ -185,7 +191,7 @@ export default { if (!zipCodeData.isValid) { this.displayInvalidZipAlert = true; if (store.getters.isLeadGen) { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } return this.$refs.navbar.removeLoader(); @@ -195,7 +201,7 @@ export default { if (!zipCodeData.isServiceable) { this.displayNonServiceableZipAlert = true; if (store.getters.isLeadGen) { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } return this.$refs.navbar.removeLoader(); @@ -250,11 +256,6 @@ export default { await this.navigateForwardWithSingleCarMatch(); } }, - async isFormValid() { - const form = this.$refs.theForm; - const formValidateResponse = await form.validate(); - return formValidateResponse?.valid; - }, }, computed: { AlertNonServiceableZipHeader() { diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js index 2bb761d5d..3c4300ba3 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.spec.js +++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js @@ -67,6 +67,11 @@ jest.mock("@/store", () => ({ }, }, isLeadGen: false, + leadGenDamage: { + damageType: null, + isRepair: null, + numberOfChips: null, + }, }, })); @@ -148,6 +153,11 @@ describe("vehicle-damage.vue", () => { getters: { vehicle: {}, payment: { insuranceCoverage: { isVerified: false } }, + leadGenDamage: { + damageType: null, + isRepair: null, + numberOfChips: null, + }, }, }, }, @@ -183,6 +193,7 @@ describe("vehicle-damage.vue", () => { (c) => c(wrapper.vm) ); + wrapper.vm.isFormValid = jest.fn(); await wrapper.vm.forwardButtonAction(); //Assert @@ -257,6 +268,11 @@ describe("vehicle-damage.vue", () => { getters: { vehicle: {}, payment: { insuranceCoverage: { isVerified: false } }, + leadGenDamage: { + damageType: null, + isRepair: null, + numberOfChips: null, + }, }, }, }, @@ -278,7 +294,7 @@ describe("vehicle-damage.vue", () => { undefined, (c) => c(wrapper.vm) ); - + wrapper.vm.isFormValid = jest.fn(); await wrapper.vm.forwardButtonAction(); //Assert @@ -540,6 +556,11 @@ describe("vehicle-damage.vue", () => { eventBusItem: jest.fn(), damage: { glassToReplace: [{ glassLocation: damageLocation }] }, isRepair: true, + leadGenDamage: { + damageType: null, + isRepair: null, + numberOfChips: null, + }, }; var glassSelections = wrapper.vm.getDamageLocationsFromStore(); @@ -617,6 +638,11 @@ describe("vehicle-damage.vue", () => { isRepair: isRepair, numberOfChips: 2, }, + leadGenDamage: { + damageType: null, + isRepair: null, + numberOfChips: null, + }, }; var windshieldSelections = wrapper.vm.getWindshieldOptionsFromStore(); @@ -653,6 +679,11 @@ describe("vehicle-damage.vue", () => { glassToReplace: [{ glassLocation: damageLocation, glassName: damageName }], }, isRepair: true, + leadGenDamage: { + damageType: null, + isRepair: null, + numberOfChips: null, + }, }; var glassSelections = wrapper.vm.getDriverSideReplaceOptionsFromStore(); @@ -689,6 +720,11 @@ describe("vehicle-damage.vue", () => { glassToReplace: [{ glassLocation: damageLocation, glassName: damageName }], }, isRepair: true, + leadGenDamage: { + damageType: null, + isRepair: null, + numberOfChips: null, + }, }; var glassSelections = wrapper.vm.getPassengerSideReplaceOptionsFromStore(); @@ -723,6 +759,11 @@ describe("vehicle-damage.vue", () => { glassToReplace: [{ glassLocation: damageLocation, glassName: damageName }], }, isRepair: true, + leadGenDamage: { + damageType: null, + isRepair: null, + numberOfChips: null, + }, }; var glassSelections = wrapper.vm.getRearReplaceOptionsFromStore(); @@ -744,6 +785,11 @@ describe("vehicle-damage.vue", () => { vehicle: {}, payment: { insuranceCoverage: { isVerified: true } }, requiresVerifiedRedirecting: true, + leadGenDamage: { + damageType: null, + isRepair: null, + numberOfChips: null, + }, }, }, }, @@ -763,20 +809,24 @@ describe("vehicle-damage.vue", () => { }); describe("vehicle-damage.vue", () => { - test("should call forwardButtonAction if isLeadGen is true and selectedDamageLocations is not empty", async () => { + test("should call forwardButtonAction if isLeadGen is true and form is valid", async () => { // Set up the store with isLeadGen as true store.getters.isLeadGen = true; + store.getters.leadGenDamage = { + damageType: "windshieldReplace", + isRepair: false, + numberOfChips: null, + }; // Set up the component const { wrapper } = setupMocks({}); wrapper.vm.forwardButtonAction = jest.fn(); + + baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true); const nextFunction = jest.fn((c) => { c(wrapper.vm); }); - // Set selectedDamageLocations - wrapper.setData({ selectedDamageLocations: ["windshield"] }); - // Call the method that contains the if-else logic await vehicleDamage.beforeRouteEnter.call( wrapper.vm, @@ -784,32 +834,10 @@ describe("vehicle-damage.vue", () => { undefined, nextFunction ); + await nextTick(); expect(nextFunction).toHaveBeenCalled(); expect(wrapper.vm.forwardButtonAction).toHaveBeenCalled(); }); - test("should not call forwardButtonAction if isLeadGen is true and selectedDamageLocations is empty", async () => { - // Set up the store with isLeadGen as true - store.getters.isLeadGen = true; - - // Set up the component - const { wrapper } = setupMocks({}); - wrapper.vm.forwardButtonAction = jest.fn(); - const nextFunction = jest.fn((c) => { - c(wrapper.vm); - }); - - // Set selectedDamageLocations to empty - wrapper.setData({ selectedDamageLocations: [] }); - - // Call the method that contains the if-else logic - await vehicleDamage.beforeRouteEnter.call( - wrapper.vm, - { query: { fmgPage: "vehicle-damage" } }, - undefined, - nextFunction - ); - expect(wrapper.vm.forwardButtonAction).not.toHaveBeenCalled(); - }); }); }); @@ -834,7 +862,12 @@ function setupMocks({ pageHeaderWidgetHeaderText, mountOptionsMockData, funnelCo isVerified: false, }, }, - isLeadGen: false, + // isLeadGen: false, + // leadGenDamage: { + // damageType: null, + // isRepair: null, + // numberOfChips: null, + // }, }, }, }; diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index 602960931..e20e4e056 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -106,6 +106,7 @@ import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper"; import store from "@/store"; import baseMixin from "@/mixins/base-mixin"; +import { nextTick } from "vue"; // DEFINE VALIDATION RULES defineRule("replace-options-required", required(errorMessages.REPLACE_OPTIONS_REQUIRED)); @@ -136,7 +137,7 @@ export default { const resultMap = await settleAllPromises(promiseResultMap); // Call the "next" function to complete the transition to this page. - next((vm) => { + next(async (vm) => { vm.setCmsContent(resultMap.cmsContent); vm.$refs.damageLocation.initializeComponent(resultMap.damageOptions); vm.$refs.sideDoorOptions.initializeComponent( @@ -150,14 +151,16 @@ export default { resultMap.damageOptions.backGlassOptions.availableReplacementOptions ); if (store.getters.isLeadGen) { - if (vm.selectedDamageLocations?.length > 0) { + await nextTick(); + const isValid = await baseMixin.methods.isFormValid(vm.$refs.theForm); + if (isValid) { vm.forwardButtonAction(); } else { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } } else { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } }); @@ -184,7 +187,6 @@ export default { } return false; }, - attachCustomEvents() { if (this.$store.getters.vehicle.imageVifNumber) { this.pushEventToGA( @@ -208,7 +210,9 @@ export default { store.getters.damage.glassToReplace?.some((glass) => { return glass.glassLocation === damageLocationsSelected.WINDSHIELD; }) || - store.getters.damage.isRepair + store.getters.damage.isRepair || + store.getters.leadGenDamage.isRepair || + store.getters.leadGenDamage.damageType?.toUpperCase().includes("WINDSHIELD") ) { glassSelections.push(damageLocationsSelected.WINDSHIELD); } @@ -241,11 +245,13 @@ export default { selectedWindshieldReplaceOptions: [], }; - if (store.getters.damage.isRepair === undefined) return windshieldOptions; + if (store.getters.leadGenDamage.isRepair || store.getters.damage.isRepair === undefined) + return windshieldOptions; - if (store.getters.damage.isRepair) { + if (store.getters.leadGenDamage.isRepair || store.getters.damage.isRepair) { windShieldOptions.selectedWindshieldDamageType = damageLocationsSelected.REPAIR; - windShieldOptions.selectedWindshieldChipCount = store.getters.damage.numberOfChips; + windShieldOptions.selectedWindshieldChipCount = + store.getters.leadGenDamage.numberOfChips || store.getters.damage.numberOfChips; } else { if ( store.getters.damage.glassToReplace?.some((glass) => { @@ -253,7 +259,8 @@ export default { glass.glassLocation === damageLocationsSelected.WINDSHIELD && glass.glassName === damageLocationsSelected.SINGLE ); - }) + }) || + store.getters.leadGenDamage.damageType?.toUpperCase() === "WINDSHIELDREPLACE" ) { windShieldOptions.selectedWindshieldDamageType = damageLocationsSelected.REPLACE; @@ -350,6 +357,8 @@ export default { }, async forwardButtonAction() { + const isValid = await this.isFormValid(); + console.log(isValid); await this.dispatchStoreAction( this.storeActions.SAVE_VEHICLE_DAMAGE, { diff --git a/src/layouts/vehicle/vehicle.spec.js b/src/layouts/vehicle/vehicle.spec.js index 0d34a9bf7..0afcbc7ef 100644 --- a/src/layouts/vehicle/vehicle.spec.js +++ b/src/layouts/vehicle/vehicle.spec.js @@ -29,6 +29,12 @@ jest.mock("@/store", () => ({ experiments: [{ universeName: "ConceptFunnel" }], }, isLeadGen: false, + leadGenVehicle: { + year: null, + make: null, + model: null, + style: null, + }, vehicle: { carId: "C00000000", image: "test.jpg", @@ -87,50 +93,21 @@ describe("vehicle.vue", () => { }); describe("vehicle.vue", () => { - test("should call forwardButtonAction if isLeadGen is true and displayNoServiceAlert is false", async () => { - // Set up the store with isLeadGen as true + test("should call forwardButtonAction if isLeadGen is true and form is valid", async () => { store.getters.isLeadGen = true; - - // Set up the component + // Create a shallow mount of MyComponent const { wrapper } = setupMocks(); - wrapper.vm.forwardButtonAction = jest.fn(); - const nextFunction = jest.fn((c) => { - c(wrapper.vm); - }); - // Set displayNoServiceAlert to false wrapper.setData({ displayNoServiceAlert: false }); // Mock the getVehicleDetails method wrapper.vm.getVehicleDetails = jest.fn(); - - // Call the method that contains the if-else logic - await vehicle.beforeRouteEnter.call( - wrapper.vm, - { query: { fmgPage: "vehicle" } }, - undefined, - nextFunction - ); - expect(nextFunction).toHaveBeenCalled(); - expect(wrapper.vm.forwardButtonAction).toHaveBeenCalled(); - }); - test("should not call forwardButtonAction if isLeadGen is true and displayNoServiceAlert is true", async () => { - // Set up the store with isLeadGen as true - store.getters.isLeadGen = true; - - // Set up the component - const { wrapper } = setupMocks(); wrapper.vm.forwardButtonAction = jest.fn(); + + baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true); const nextFunction = jest.fn((c) => { c(wrapper.vm); }); - - // Set displayNoServiceAlert to false - wrapper.setData({ displayNoServiceAlert: true }); - - // Mock the getVehicleDetails method - wrapper.vm.getVehicleDetails = jest.fn(); - // Call the method that contains the if-else logic await vehicle.beforeRouteEnter.call( wrapper.vm, @@ -138,7 +115,10 @@ describe("vehicle.vue", () => { undefined, nextFunction ); - expect(wrapper.vm.forwardButtonAction).not.toHaveBeenCalled(); + await nextTick(); + + expect(nextFunction).toHaveBeenCalled(); + expect(wrapper.vm.forwardButtonAction).toHaveBeenCalled(); }); }); diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index 2b9b02863..f88caad42 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -143,14 +143,14 @@ export default { var styleQuestionInitialDataPromise = null; if ( - store.getters.order.vehicle.make && - store.getters.order.vehicle.model && - store.getters.order.vehicle.style + (store.getters.leadGenVehicle.make || store.getters.order.vehicle.make) && + (store.getters.leadGenVehicle.model || store.getters.order.vehicle.model) && + (store.getters.leadGenVehicle.style || store.getters.order.vehicle.style) ) { makeQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_VEHICLE_MAKES, { - year: store.getters.order.vehicle.year, + year: store.getters.leadGenVehicle.year || store.getters.order.vehicle.year, }, "vehicle" ); @@ -158,8 +158,8 @@ export default { modelQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_VEHICLE_MODELS, { - year: store.getters.order.vehicle.year, - make: store.getters.order.vehicle.make, + year: store.getters.leadGenVehicle.year || store.getters.order.vehicle.year, + make: store.getters.leadGenVehicle.make || store.getters.order.vehicle.make, }, "vehicle" ); @@ -167,9 +167,9 @@ export default { styleQuestionInitialDataPromise = baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_VEHICLE_STYLES, { - year: store.getters.order.vehicle.year, - make: store.getters.order.vehicle.make, - model: store.getters.order.vehicle.model, + year: store.getters.leadGenVehicle.year || store.getters.order.vehicle.year, + make: store.getters.leadGenVehicle.make || store.getters.order.vehicle.make, + model: store.getters.leadGenVehicle.model || store.getters.order.vehicle.model, }, "vehicle" ); @@ -235,13 +235,19 @@ export default { if (store.getters.isLeadGen) { await vm.getVehicleDetails(); if (!vm.displayNoServiceAlert) { - vm.forwardButtonAction(); + const isValid = await baseMixin.methods.isFormValid(vm.$refs.theForm); + if (isValid) { + vm.forwardButtonAction(); + } else { + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); + baseMixin.methods.hideFmgLoadingModal(); + } } else { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } } else { - baseMixin.methods.dispatchStoreAction(storeActions.RESET_IS_LEAD_GEN); + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); baseMixin.methods.hideFmgLoadingModal(); } }); @@ -429,16 +435,16 @@ export default { this.styleOptions = styleOptions; }, selectedYearfromStore() { - return store.getters.vehicle.year?.toString(); + return store.getters.leadGenVehicle.year ?? store.getters.vehicle.year?.toString(); }, selectedMakefromStore() { - return store.getters.vehicle.make; + return store.getters.leadGenVehicle.make ?? store.getters.vehicle.make; }, selectedModelfromStore() { - return store.getters.vehicle.model; + return store.getters.leadGenVehicle.model ?? store.getters.vehicle.model; }, selectedStylefromStore() { - return store.getters.vehicle.style; + return store.getters.leadGenVehicle.style ?? store.getters.vehicle.style; }, async getMakeOptions(year) { return await baseMixin.methods.dispatchStoreActionWithLogging( diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index ce8365a53..240281b3c 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -154,7 +154,7 @@ import { required, regex } from "@/helpers/validation-rules"; import { Form, defineRule } from "vee-validate"; import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper"; import { routerParams } from "@/router/router-constants/router-params"; - +import baseMixin from "@/mixins/base-mixin.js"; import store from "@/store"; import vinPagesMixin from "@/mixins/vin-pages-mixin"; @@ -192,6 +192,10 @@ export default { // Call the "next" function to complete the transition to this page. next((vm) => { vm.setCmsContent(resultMap.cmsContent); + if (store.getters.isLeadGen) { + baseMixin.methods.dispatchStoreAction(storeActions.RESET_LEADGEN_STATE); + baseMixin.methods.hideFmgLoadingModal(); + } }); }, data() { diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 90a6a7838..7cf47848e 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -196,6 +196,10 @@ export default { hideFmgLoadingModal() { showFmgLoadingModal(false); }, + async isFormValid(form) { + const formValidateResponse = await form?.validate(); + return formValidateResponse?.valid; + }, }, computed: { storeActions() { diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index 98eb7a75b..75054f776 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -3,6 +3,7 @@ import store from "@/store"; import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin"; import { saveSession } from "@/helpers/heritage-integration/order-helper.js"; import { experimentSettings } from "@/constants/experiments"; +import { vinLookupMethodSelections } from "@/constants/vin-lookup-method-selections.js"; export default { computed: { @@ -32,5 +33,14 @@ export default { vehicleQuestionsMixin.methods.navigateForward(partsOrQuestions, this); }, + getVinlookupMethod(vinSelection) { + const vinLookupMethods = { + vin: vinLookupMethodSelections.MANUALVIN, + licensePlate: vinLookupMethodSelections.LICENSEPLATE, + address: vinLookupMethodSelections.HOMEADDRESS, + decline: vinLookupMethodSelections.DECLINE, + }; + return vinLookupMethods[vinSelection] || null; + }, }, }; diff --git a/src/router/index.js b/src/router/index.js index db28a5ef1..e1546cbcc 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -33,6 +33,7 @@ import { experimentTriggers } from "../constants/experiments"; import { applicationConfig } from "../constants/application-config"; import { shouldStripPromoQueryString } from "@/helpers/promotions-helper"; import bailout from "@/layouts/bailout/bailout"; +import { nextTick } from "vue"; const routes = [ { @@ -84,14 +85,25 @@ const routes = [ ); const parentAccount = getQuerystringParameter(queryStrings.PARENT_ACCOUNT); const correlationId = getQuerystringParameter(queryStrings.CORRELATION_ID); - const vehicleYear = getQuerystringParameter(queryStrings.VEHICLE_YEAR); - const vehicleMake = getQuerystringParameter(queryStrings.VEHICLE_MAKE); - const vehicleModel = getQuerystringParameter(queryStrings.VEHICLE_MODEL); - const vehicleStyle = getQuerystringParameter(queryStrings.VEHICLE_STYLE); - const vehicleDamage = getQuerystringParameter(queryStrings.VEHICLE_DAMAGE); - const serviceZip = getQuerystringParameter(queryStrings.SERVICE_ZIP); - const email = getQuerystringParameter(queryStrings.EMAIL); - const isInsurance = getQuerystringParameter(queryStrings.IS_INSURANCE); + const leadGenYear = getQuerystringParameter(queryStrings.VEHICLE_YEAR); + const leadGenMake = getQuerystringParameter(queryStrings.VEHICLE_MAKE); + const leadGenModel = getQuerystringParameter(queryStrings.VEHICLE_MODEL); + const leadGenStyle = getQuerystringParameter(queryStrings.VEHICLE_STYLE); + const leadGenDamage = getQuerystringParameter(queryStrings.VEHICLE_DAMAGE); + const leadGenZipCode = getQuerystringParameter(queryStrings.SERVICE_ZIP); + const leadGenEmail = getQuerystringParameter(queryStrings.EMAIL); + const leadGenIsInsurance = getQuerystringParameter( + queryStrings.IS_INSURANCE + ); + const leadGenVinSelection = getQuerystringParameter( + queryStrings.VIN_SELECTION + ); + const leadGenPackageSelection = getQuerystringParameter( + queryStrings.PACKAGE_SELECTION + ); + const leadGenNumberOfChips = getQuerystringParameter( + queryStrings.NUMBER_OF_CHIPS + ); if (referralNumber) { store.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber); store.commit(storeMutations.UPDATE_PARENT_ACCT_NUMBER, parentAccount); @@ -102,47 +114,60 @@ const routes = [ updateOrCreateFunnelCookie(); } if ( - vehicleYear && - vehicleMake && - vehicleModel && - vehicleStyle && - vehicleDamage && - serviceZip && - email && - isInsurance + leadGenYear && + leadGenMake && + leadGenModel && + leadGenStyle && + leadGenDamage && + leadGenZipCode && + leadGenEmail && + leadGenIsInsurance && + leadGenVinSelection && + leadGenPackageSelection && + leadGenNumberOfChips ) { if (!store.getters.applicationUser.triggeredSiteEntry) { - store.commit(storeMutations.UPDATE_YEAR, vehicleYear); - store.commit(storeMutations.UPDATE_MAKE, vehicleMake); - store.commit(storeMutations.UPDATE_MODEL, vehicleModel); - store.commit(storeMutations.UPDATE_STYLE, vehicleStyle); store.commit(storeMutations.UPDATE_IS_LEAD_GEN, true); - if (vehicleDamage == "windshieldReplace") { - store.commit(storeMutations.UPDATE_IS_REPAIR, false); - store.commit(storeMutations.UPDATE_NUMBER_OF_CHIPS, null); - const glassToReplace = [ - { glassLocation: "Windshield", glassName: "Single" }, - ]; + store.commit(storeMutations.UPDATE_LEAD_GEN_YEAR, leadGenYear); + store.commit(storeMutations.UPDATE_LEAD_GEN_MAKE, leadGenMake); + store.commit(storeMutations.UPDATE_LEAD_GEN_MODEL, leadGenModel); + store.commit(storeMutations.UPDATE_LEAD_GEN_STYLE, leadGenStyle); + store.commit( + storeMutations.UPDATE_LEAD_GEN_DAMAGE_TYPE, + leadGenDamage + ); + if (leadGenDamage?.toUpperCase() == "WINDSHIELDREPLACE") { + store.commit(storeMutations.UPDATE_LEAD_GEN_IS_REPAIR, false); store.commit( - storeMutations.UPDATE_GLASS_TO_REPLACE, - glassToReplace + storeMutations.UPDATE_LEAD_GEN_NUMBER_OF_CHIPS, + null + ); + } else if (leadGenDamage?.toUpperCase() == "WINDSHIELDREPAIR") { + store.commit(storeMutations.UPDATE_LEAD_GEN_IS_REPAIR, true); + store.commit( + storeMutations.UPDATE_LEAD_GEN_NUMBER_OF_CHIPS, + leadGenNumberOfChips ); - } else if (vehicleDamage == "windshieldRepair") { - store.commit(storeMutations.UPDATE_IS_REPAIR, true); - store.commit(storeMutations.UPDATE_NUMBER_OF_CHIPS, 1); } - const serviceZipInfo = { - state: null, - zipCode: serviceZip, - zipCodeCtu: null, - }; - store.commit(storeMutations.UPDATE_SERVICE_ZIP, serviceZipInfo); - store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, email); - if (isInsurance == "true") { - store.commit(storeMutations.UPDATE_IS_INSURANCE, true); - } else { - store.commit(storeMutations.UPDATE_IS_INSURANCE, null); + store.commit( + storeMutations.UPDATE_LEAD_GEN_ZIP_CODE, + leadGenZipCode + ); + store.commit( + storeMutations.UPDATE_LEAD_GEN_EMAIL_ADDRESS, + leadGenEmail + ); + if (leadGenIsInsurance == "true") { + store.commit(storeMutations.UPDATE_LEAD_GEN_IS_INSURANCE, true); + store.commit( + storeMutations.UPDATE_LEAD_GEN_PACKAGE_SELECTION, + leadGenPackageSelection + ); } + store.commit( + storeMutations.UPDATE_LEAD_GEN_VIN_SELECTION, + leadGenVinSelection + ); } } diff --git a/src/store/index.js b/src/store/index.js index c449a61c5..67bc30df7 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -160,7 +160,6 @@ const getDefaultState = () => { customerPortalLoginToken: null, lockToken: null, settledTenderAmount: 0, - isLeadGen: false, }, applicationUser: { eventBus: [], @@ -177,7 +176,7 @@ const getDefaultState = () => { }; export const state = getDefaultState(); - +export const leadGenState = getLeadGenDefaultState(); // Export Mutations export const mutations = { // VEHICLE MUTATIONS @@ -295,9 +294,6 @@ export const mutations = { updateSettledTenderAmount(state, settledTenderAmount) { state.order.settledTenderAmount = settledTenderAmount; }, - updateIsLeadGen(state, isLeadGen) { - state.order.isLeadGen = isLeadGen; - }, updateCCToken(state, ccToken) { state.order.payment.ccToken.subscriptionId = ccToken.subscriptionId; state.order.payment.ccToken.expMonth = ccToken.expMonth; @@ -418,6 +414,91 @@ export const mutations = { state.applicationUser.eventBus.splice(itemIndex, 1); } }, + //LEADGEN MUTATIONS + updateIsLeadGen(state, isLeadGen) { + leadGenState.isLeadGen = isLeadGen; + setLeadGenState(leadGenState); + }, + updateLeadGenYear(state, year) { + leadGenState.vehicle.year = year; + setLeadGenState(leadGenState); + }, + updateLeadGenMake(state, make) { + leadGenState.vehicle.make = make; + setLeadGenState(leadGenState); + }, + updateLeadGenModel(state, model) { + leadGenState.vehicle.model = model; + setLeadGenState(leadGenState); + }, + updateLeadGenStyle(state, style) { + leadGenState.vehicle.style = style; + setLeadGenState(leadGenState); + }, + updateLeadGenIsRepair(state, isRepair) { + leadGenState.vehicleDamage.isRepair = isRepair; + setLeadGenState(leadGenState); + }, + updateLeadGenNumberOfChips(state, numberOfChips) { + leadGenState.vehicleDamage.numberOfChips = numberOfChips; + setLeadGenState(leadGenState); + }, + updateLeadGenDamageType(state, damageType) { + leadGenState.vehicleDamage.damageType = damageType; + setLeadGenState(leadGenState); + }, + updateLeadGenZipCode(state, zipCode) { + leadGenState.serviceZip.zipCode = zipCode; + setLeadGenState(leadGenState); + }, + updateLeadGenEmailAddress(state, emailAddress) { + leadGenState.serviceZip.emailAddress = emailAddress; + setLeadGenState(leadGenState); + }, + updateLeadGenIsInsurance(state, isInsurance) { + leadGenState.quote.isInsurance = isInsurance; + setLeadGenState(leadGenState); + }, + updateLeadGenVinSelection(state, vinSelection) { + leadGenState.estimate.vinSelection = vinSelection; + setLeadGenState(leadGenState); + }, + updateLeadGenPackageSelection(state, packageSelection) { + leadGenState.quote.packageSelection = packageSelection; + setLeadGenState(leadGenState); + }, + //RESET LEADGEN MUTATIONS + resetLeadGenVehicleState(state) { + leadGenState.vehicle.year = + leadGenState.vehicle.make = + leadGenState.vehicle.model = + leadGenState.vehicle.style = + null; + setLeadGenState(leadGenState); + }, + resetLeadGenDamageState(state) { + leadGenState.vehicleDamage.isRepair = + leadGenState.vehicleDamage.numberOfChips = + leadGenState.vehicleDamage.damageType = + null; + setLeadGenState(leadGenState); + }, + resetLeadGenEstimateState(state) { + leadGenState.estimate.vinSelection = null; + setLeadGenState(leadGenState); + }, + resetLeadGenServiceZipState(state) { + leadGenState.serviceZip.zipCode = leadGenState.serviceZip.emailAddress = null; + setLeadGenState(leadGenState); + }, + resetLeadGenQuoteState(state) { + leadGenState.quote.isInsurance = null; + setLeadGenState(leadGenState); + }, + resetIsLeadGen(state) { + leadGenState.isLeadGen = null; + setLeadGenState(leadGenState); + }, // RESET DEPENDENCY MUTATIONS resetVehicleState(state) { @@ -678,7 +759,6 @@ export const getters = { isOvernightDropOffAppointment: (state) => { return state.order.schedule.routeCode?.includes(RouteCodeFlags.OVERNIGHT_DROP_OFF); }, - isLeadGen: (state) => state.order.isLeadGen, isRecalibrationOnOrder: (state) => { return getHasRecalibrationPart(state); }, @@ -809,6 +889,12 @@ export const getters = { requiresVerifiedRedirecting: (state) => { return state.order?.referralNumber?.length === 6; }, + isLeadGen: (state) => leadGenState?.isLeadGen, + leadGenVehicle: (state) => leadGenState?.vehicle, + leadGenDamage: (state) => leadGenState?.vehicleDamage, + leadGenQuote: (state) => leadGenState?.quote, + leadGenServiceZip: (state) => leadGenState?.serviceZip, + leadGenEstimate: (state) => leadGenState?.estimate, }; function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) { @@ -1932,13 +2018,11 @@ export const actions = { context.state.order.vehicle.year != year || context.state.order.vehicle.make != make || context.state.order.vehicle.model != model || - context.state.order.vehicle.style != style || - context.state.order.isLeadGen + context.state.order.vehicle.style != style ) { - if (!context.state.order.isLeadGen) { - context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); - context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); - } + context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); + context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); + context.commit(storeMutations.UPDATE_VEHICLE_VIN, null); context.commit(storeMutations.UPDATE_YEAR, year); context.commit(storeMutations.UPDATE_MAKE, make); @@ -2703,14 +2787,27 @@ export const actions = { //restore user's experiments context.commit(storeMutations.UPDATE_EXPERIMENTS, experiments); + + //clear leadGen session storage + window.sessionStorage.removeItem("leadGenState"); }, resetSubmittedOrder(context) { // clear from local storage window.sessionStorage.removeItem("submittedOrder"); }, - resetIsLeadGen(context) { - context.commit(storeMutations.UPDATE_IS_LEAD_GEN, false); + resetLeadGenState(context) { + if (context.getters.isLeadGen) { + context.commit(storeMutations.RESET_LEADGEN_VEHICLE_STATE); + context.commit(storeMutations.RESETL_EADGEN_DAMAGE_STATE); + context.commit(storeMutations.RESET_LEADGEN_ESTIMATE_STATE); + context.commit(storeMutations.RESET_LEADGEN_SERVICEZIP_STATE); + context.commit(storeMutations.RESET_LEADGEN_QUOTE_STATE); + context.commit(storeMutations.RESET_IS_LEADGEN); + } + }, + createLeadGenState(context) { + createLeadGenDefaultState(); }, }; @@ -3199,3 +3296,43 @@ async function resetScheduleIfUnavailable(context, order, pageNameToLog) { } } } +function createLeadGenDefaultState() { + // create default leadGen state + const leadGenDefaultState = { + isLeadGen: null, + vehicle: { + year: null, + make: null, + model: null, + style: null, + }, + vehicleDamage: { + damageType: null, + isRepair: null, + numberOfChips: null, + }, + estimate: { + vinSelection: null, + }, + serviceZip: { + emailAddress: null, + zipCode: null, + }, + quote: { + isInsurance: null, + packageSelection: null, + }, + }; + // set to session storage + setLeadGenState(leadGenDefaultState); +} +function getLeadGenDefaultState() { + const leadGenState = window.sessionStorage.getItem("leadGenState"); + if (leadGenState === null) { + createLeadGenDefaultState(); + } + return JSON.parse(window.sessionStorage.getItem("leadGenState")); +} +async function setLeadGenState(leadGenState) { + window.sessionStorage.setItem("leadGenState", JSON.stringify(leadGenState)); +} From 7e0bcf4b7c0ddfa6fb90e54b467bb04454c16980 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Thu, 18 Jul 2024 20:28:23 +0530 Subject: [PATCH 04/15] Update quote.vue --- src/layouts/quote/quote.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 65342dc23..f06827739 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -258,7 +258,7 @@ export default { if (store.getters.leadGenQuote.isInsurance == true) { vm.isInsuranceSelected = true; vm.packageSelection = store.getters.leadGenQuote.packageSelection; - await nextTick(); + await nextTick(); const isValid = await baseMixin.methods.isFormValid(vm.$refs.theForm); if (isValid) { vm.forwardButtonAction(); From e4402a621599ce92bab227370ae2fa27842cd4bb Mon Sep 17 00:00:00 2001 From: Bryan Mauger Date: Thu, 18 Jul 2024 14:04:40 -0400 Subject: [PATCH 05/15] CSR-2140 QA Updates. --- src/layouts/quote/quote.vue | 7 ++++++- .../service-package-radio/service-package-radio.vue | 7 +++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index a85fd7d29..a7ab3df24 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -454,7 +454,12 @@ export default { }, }; -