From d92cb225c2a3dce2b1520cb01e3f60cecfac850a Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Wed, 5 Feb 2025 16:45:50 +0530 Subject: [PATCH 01/21] CASH-182 Do not assign service type and schedule details from load session once user make selection. it is overriding user selection. --- src/store/index.js | 81 +++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index c591d493d..b02f7907a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -49,6 +49,7 @@ import { import { externalParameterStatus } from "@/constants/external-parameters"; import { experimentSettings } from "@/constants/experiments"; import experimentMixin from "@/mixins/experiment-mixin.js"; +import { Store } from "vuex/dist/vuex.cjs.js"; // Export State const getDefaultState = () => { @@ -678,34 +679,38 @@ export const mutations = { sessionInformation.order.payment.billToAccountNumber; state.order.payment.inactivePromos = sessionInformation.order.payment.inactivePromos; - state.order.serviceLocation.address = - sessionInformation.order.serviceLocation.streetAddress; - state.order.serviceLocation.address2 = - sessionInformation.order.serviceLocation.streetAddress2; - state.order.serviceLocation.city = sessionInformation.order.serviceLocation.city; - state.order.serviceLocation.state = sessionInformation.order.serviceLocation.state; - state.order.serviceLocation.zipCode = sessionInformation.order.serviceLocation.zipCode; - state.order.serviceLocation.zipCodeCtu = - sessionInformation.order.serviceLocation.zipCodeCtu; + //Do not assign default service type once user make service type selection + if (state.order.serviceLocation.appointmentType == null) { + state.order.serviceLocation.address = + sessionInformation.order.serviceLocation.streetAddress; + state.order.serviceLocation.address2 = + sessionInformation.order.serviceLocation.streetAddress2; + state.order.serviceLocation.city = sessionInformation.order.serviceLocation.city; + state.order.serviceLocation.state = sessionInformation.order.serviceLocation.state; + state.order.serviceLocation.zipCode = sessionInformation.order.serviceLocation.zipCode; + state.order.serviceLocation.zipCodeCtu = + sessionInformation.order.serviceLocation.zipCodeCtu; - state.order.serviceLocation.appointmentType = - sessionInformation.order.serviceLocation.appointmentType; - state.order.serviceLocation.isVehicleProtected = - sessionInformation.order.serviceLocation.isVehicleProtected; + state.order.serviceLocation.appointmentType = + sessionInformation.order.serviceLocation.appointmentType; + state.order.serviceLocation.isVehicleProtected = + sessionInformation.order.serviceLocation.isVehicleProtected; - state.order.serviceLocation.provider.providerNumber = - sessionInformation.order.serviceLocation.provider?.providerNumber; - state.order.serviceLocation.provider.address.streetAddress = - sessionInformation.order.serviceLocation.provider?.address?.streetAddress; - state.order.serviceLocation.provider.address.city = - sessionInformation.order.serviceLocation.provider?.address?.city; - state.order.serviceLocation.provider.address.state = - sessionInformation.order.serviceLocation.provider?.address?.state; - state.order.serviceLocation.provider.address.zipCode = - sessionInformation.order.serviceLocation.provider?.address?.zipCode; - state.order.serviceLocation.provider.address.zipCodeCtu = - sessionInformation.order.serviceLocation.provider?.address?.zipCodeCtu; - state.order.serviceLocation.techNotes = sessionInformation.order.serviceLocation.techNotes; + state.order.serviceLocation.provider.providerNumber = + sessionInformation.order.serviceLocation.provider?.providerNumber; + state.order.serviceLocation.provider.address.streetAddress = + sessionInformation.order.serviceLocation.provider?.address?.streetAddress; + state.order.serviceLocation.provider.address.city = + sessionInformation.order.serviceLocation.provider?.address?.city; + state.order.serviceLocation.provider.address.state = + sessionInformation.order.serviceLocation.provider?.address?.state; + state.order.serviceLocation.provider.address.zipCode = + sessionInformation.order.serviceLocation.provider?.address?.zipCode; + state.order.serviceLocation.provider.address.zipCodeCtu = + sessionInformation.order.serviceLocation.provider?.address?.zipCodeCtu; + state.order.serviceLocation.techNotes = + sessionInformation.order.serviceLocation.techNotes; + } // 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. @@ -749,14 +754,15 @@ export const mutations = { state.applicationUser.savedSessionId = sessionInformation.applicationUser.savedSessionId; } - - state.order.schedule.date = sessionInformation.order.schedule?.date; - state.order.schedule.startTime = sessionInformation.order.schedule?.startTime; - state.order.schedule.endTime = sessionInformation.order.schedule?.endTime; - state.order.schedule.routeCode = sessionInformation.order.schedule?.routeCode; - state.order.schedule.jobMaxMinutes = sessionInformation.order.schedule?.jobMaxMinutes; - state.order.schedule.jobMinMinutes = sessionInformation.order.schedule?.jobMinMinutes; - + //Do not assign default schedule details once user make schedule selection + if (state.order.schedule.date == null) { + state.order.schedule.date = sessionInformation.order.schedule?.date; + state.order.schedule.startTime = sessionInformation.order.schedule?.startTime; + state.order.schedule.endTime = sessionInformation.order.schedule?.endTime; + state.order.schedule.routeCode = sessionInformation.order.schedule?.routeCode; + state.order.schedule.jobMaxMinutes = sessionInformation.order.schedule?.jobMaxMinutes; + state.order.schedule.jobMinMinutes = sessionInformation.order.schedule?.jobMinMinutes; + } state.order.policy.currentDeductible = sessionInformation.order.policy?.currentDeductible; state.order.policy.originalDeductible = sessionInformation.order.policy?.originalDeductible; state.order.policy.additionalAuthFlag = sessionInformation.order.policy?.additionalAuthFlag; @@ -2254,7 +2260,7 @@ export const actions = { response.data ); - await resetScheduleIfUnavailable(context, response.data.order, pageNameToLog); + await resetScheduleIfUnavailable(context, context.state.order, pageNameToLog); return response; }, (error) => { @@ -3042,7 +3048,10 @@ export const actions = { }, savePhoneNumber(context, phoneNumber) { - context.commit(storeMutations.UPDATE_CUSTOMER_PHONE_NUMBER, phoneNumber === "" ? null : phoneNumber); + context.commit( + storeMutations.UPDATE_CUSTOMER_PHONE_NUMBER, + phoneNumber === "" ? null : phoneNumber + ); }, saveVin(context, { isSelectedGlassAvailableForVehicle, vehicleInfo }) { From 8af9fcc0a315da91b7869bb32938c194726aec9d Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Wed, 5 Feb 2025 18:36:44 +0530 Subject: [PATCH 02/21] CASH-182 remove unwanted file reference --- src/store/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index b02f7907a..c46d35a0b 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -49,7 +49,6 @@ import { import { externalParameterStatus } from "@/constants/external-parameters"; import { experimentSettings } from "@/constants/experiments"; import experimentMixin from "@/mixins/experiment-mixin.js"; -import { Store } from "vuex/dist/vuex.cjs.js"; // Export State const getDefaultState = () => { From 690d992ef7a52c7798c74ff1b80e51a299272ee8 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Wed, 5 Feb 2025 09:03:46 -0500 Subject: [PATCH 03/21] CASH-176 CASH-176 service zip changes for sms --- src/constants/error-messages.js | 2 + src/constants/store-actions.js | 1 + src/layouts/confirmation/confirmation.vue | 4 +- src/layouts/service-zip/service-zip.vue | 45 +++++++++++++------ src/mixins/vin-pages-mixin.js | 9 ++++ src/router/router-constants/fmgPage-values.js | 1 + src/store/index.js | 29 +++++++++++- 7 files changed, 74 insertions(+), 17 deletions(-) diff --git a/src/constants/error-messages.js b/src/constants/error-messages.js index 4326a5412..45841f21f 100644 --- a/src/constants/error-messages.js +++ b/src/constants/error-messages.js @@ -18,6 +18,8 @@ const errorMessages = { LAST_NAME_REQUIRED: "Please enter your last name", EMAIL_ADDRESS_REQUIRED: "Please enter your email address", EMAIL_ADDRESS_FORMAT: "Please enter a valid email address", + EMAIL_SMS_REQUIRED: "Please enter your mobile phone number or email", + EMAIL_SMS_FORMAT: "Please enter a valid mobile phone number or email", SERVICE_ZIP_REQUIRED: "Please enter your service ZIP", SERVICE_ZIP_FORMAT: "Please enter a valid service ZIP", VIN_REQUIRED: "Please enter your VIN", diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index ec6b0db0c..833645578 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -1,6 +1,7 @@ const storeActions = { // Content Actions GET_PAGE_DATA: "getPageData", + SAVE_PAGE_DATA: "savePageData", // Vehicle Actions GET_VEHICLE_YEARS: "getVehicleYears", diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 0739a9af6..804ed5608 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -121,9 +121,9 @@ export default { const partsOrQuestions = orderFromStore.damage?.partQuestionAnswers; if (partsOrQuestions) { - partsOrQuestions.forEach(pqa => { + partsOrQuestions.forEach((pqa) => { const payloadPartQuestions = []; - pqa.answeredQuestions.forEach(answer => { + pqa.answeredQuestions.forEach((answer) => { payloadPartQuestions.push({ questionSeq: answer?.questionNum, questionText: answer?.questionText, diff --git a/src/layouts/service-zip/service-zip.vue b/src/layouts/service-zip/service-zip.vue index b74db95dc..18a8b3362 100644 --- a/src/layouts/service-zip/service-zip.vue +++ b/src/layouts/service-zip/service-zip.vue @@ -23,11 +23,11 @@ @@ -88,16 +88,17 @@ import vinPagesMixin from "@/mixins/vin-pages-mixin"; import { saveSession } from "@/helpers/heritage-integration/order-helper.js"; import baseMixin from "@/mixins/base-mixin.js"; import { queryStrings } from "@/constants/query-strings"; +import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; // Define Validation Rules defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED)); defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT)); -defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED)); +defineRule("email-sms-required", required(errorMessages.EMAIL_SMS_REQUIRED)); defineRule( - "email-address-format", + "email-sms-format", regex( - /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/, - errorMessages.EMAIL_ADDRESS_FORMAT + /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$|^\(?(\d{3})\)?[-. ]?(\d{3})[-. ]?(\d{4})$/, + errorMessages.EMAIL_SMS_FORMAT ) ); defineRule("option-required", required(errorMessages.OPTION_REQUIRED)); @@ -108,7 +109,7 @@ export default { data() { return { serviceZipCode: this.getZipFromStore() ?? this.$route.query.zipcode, - emailAddress: this.getEmailFromStore(), + emailOrSms: this.getEmailOrSmsFromStore(), displayInvalidZipAlert: false, displayNonServiceableZipAlert: false, }; @@ -160,11 +161,11 @@ export default { store.getters.order.serviceLocation.zipCode ); }, - getEmailFromStore() { - return ( - store.getters.externalParameterServiceZip.emailAddress ?? - store.getters.order.customer.emailAddress - ); + getEmailOrSmsFromStore() { + return store.getters.emailOrSms; + }, + getPhoneFromStore() { + return store.getters.order.customer.phoneNumber; }, arePagePrerequisitesValid() { return store.getters.damage.isRepair || store.getters.damage.glassToReplace?.length > 0; @@ -186,7 +187,23 @@ export default { }, async forwardButtonAction() { const zipCodeData = await this.getZipCodeData(this.serviceZipCode); - await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailAddress, false); + + if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { + const phone = this.emailOrSms.replace(/[()]/g, ""); + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); + } else { + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + } + + await this.dispatchStoreAction( + storeActions.SAVE_PAGE_DATA, + { + page: fmgPageValues.EMAIL_SMS_PAGES, + data: { emailOrSmsValue: this.emailOrSms }, + }, + false + ); + await this.dispatchStoreAction( storeActions.SAVE_SERVICE_ZIP_CODE_INFO, { diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js index 7d15066c5..fc195d910 100644 --- a/src/mixins/vin-pages-mixin.js +++ b/src/mixins/vin-pages-mixin.js @@ -16,6 +16,11 @@ export default { ? "email-address-format" : "email-address-required|email-address-format"; }, + EmailOrSmsValidationRules() { + return this.IsEmailOptional + ? "email-sms-format" + : "email-sms-required|email-sms-format"; + }, }, methods: { async navigateForwardWithSingleCarMatch() { @@ -56,5 +61,9 @@ export default { false ); }, + isPhoneNumber(input) { + const phoneRegex = /^\(?(\d{3})\)?[-. ]?(\d{3})[-. ]?(\d{4})$/; + return phoneRegex.test(input); + }, }, }; diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js index 5fade6506..1cba0414b 100644 --- a/src/router/router-constants/fmgPage-values.js +++ b/src/router/router-constants/fmgPage-values.js @@ -23,6 +23,7 @@ const fmgPageValues = { PAYMENT_PIA_RETURN: "payment-pia-return", CONFIRMATION: "confirmation", RETURN_USER: "return-user", + EMAIL_SMS_PAGES: "email-or-sms-related-pages", }; const funnelStartPageName = fmgPageValues.VEHICLE; diff --git a/src/store/index.js b/src/store/index.js index c591d493d..a137dd7ef 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -997,6 +997,26 @@ export const getters = { externalParameterEstimate: (state) => externalParameterState?.estimate, externalParameterCustomer: (state) => externalParameterState?.customer, isExternalParameter: (state) => externalParameterState?.isExternalParameter, + + emailOrSms: (state) => { + const email = externalParameterState.serviceZip.emailAddress ?? state.order.customer.emailAddress; + const phone = state.order.customer.phoneNumber; + + if (!phone && !email) { + return null; + } + + if (phone && !email) { + return phone; + } + + if (email && !phone) { + return email; + } + + // if we're here, then we have both email and phone so get the value from pageData to reflect what they entered on the page + return state.applicationUser.pageData[fmgPageValues.EMAIL_SMS_PAGES]?.emailOrSmsValue; + }, }; function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) { @@ -3042,7 +3062,14 @@ export const actions = { }, savePhoneNumber(context, phoneNumber) { - context.commit(storeMutations.UPDATE_CUSTOMER_PHONE_NUMBER, phoneNumber === "" ? null : phoneNumber); + context.commit( + storeMutations.UPDATE_CUSTOMER_PHONE_NUMBER, + phoneNumber === "" ? null : phoneNumber + ); + }, + + savePageData(context, emailOrSms) { + context.commit(storeMutations.UPDATE_PAGE_DATA, emailOrSms); }, saveVin(context, { isSelectedGlassAvailableForVehicle, vehicleInfo }) { From d728cd76488f1c2cc1f4f0e664c20fe8b470314d Mon Sep 17 00:00:00 2001 From: CarlNation Date: Wed, 5 Feb 2025 09:32:42 -0500 Subject: [PATCH 04/21] CASH-176 CASDH-176 mock emailOrSms for test --- src/layouts/service-zip/service-zip.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/layouts/service-zip/service-zip.spec.js b/src/layouts/service-zip/service-zip.spec.js index 214fd96f0..773157980 100644 --- a/src/layouts/service-zip/service-zip.spec.js +++ b/src/layouts/service-zip/service-zip.spec.js @@ -181,6 +181,7 @@ function applyMockStoreDataToGetters() { payment: mockStoreData.payment, policy: mockStoreData.policy, externalParameterServiceZip: mockStoreData.externalParameterServiceZip, + emailOrSms: mockStoreData.customer.emailAddress, }; store.state.order = mockStoreData; store.state.applicationUser.experiments = mockExperimentSettings; @@ -241,7 +242,7 @@ describe("service-zip.vue", () => { // Assert expect(wrapper.vm.serviceZipCode).toEqual("11111"); - expect(wrapper.vm.emailAddress).toEqual("builddigitaltest@safelite.com"); + expect(wrapper.vm.emailOrSms).toEqual("builddigitaltest@safelite.com"); }); test("Zip in querystring -> pushed to data", () => { From 31719e5ef6b678d9a0482a13fac7db94be47f745 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Wed, 5 Feb 2025 09:59:22 -0500 Subject: [PATCH 05/21] CASH-183 | Update the store when exposure is logged This prevents erroneous logs being created in EXPERIMENT_LOG by log-custom-event If the store still showed not exposed after logExposure was called, following log-custom-events still sent the experiment as not exposed --- src/constants/store-actions.js | 2 +- src/layouts/vehicle/vehicle.vue | 2 +- src/store/index.js | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index ec6b0db0c..8c9a28910 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -54,7 +54,7 @@ const storeActions = { GET_RECAL_PARTS_AND_SAVE_TO_LINE_ITEMS: "getRecalPartsAndSaveToLineItems", // Analytics - LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure", + LOG_EXPERIMENT_EXPOSURE_AND_UPDATE_STORE: "logExperimentExposureAndUpdateStore", LOG_PAGE_VIEW: "logPageView", LOG_CUSTOM_EVENT: "logCustomEvent", INITIALIZE_SESSION: "initializeSession", diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index fa7f5c036..d5dc768ce 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -187,7 +187,7 @@ export default { if (experimentForLogging !== undefined) { // Log experiment exposure baseMixin.methods.dispatchStoreActionWithLogging( - storeActions.LOG_EXPERIMENT_EXPOSURE, + storeActions.LOG_EXPERIMENT_EXPOSURE_AND_UPDATE_STORE, { userId: getUserIdValue(), deviceId: getDeviceIdValue(), diff --git a/src/store/index.js b/src/store/index.js index c591d493d..dcd631941 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1262,10 +1262,23 @@ export const actions = { }, // Analytics Actions - logExperimentExposure( + logExperimentExposureAndUpdateStore( context, { payload: { userId, deviceId, sessionKey, pageName, experiment }, pageNameToLog } ) { + const experiments = deepClone(context.getters.applicationUser.experiments); + const experimentToMarkAsExposed = experiments.find(ex => { + ex.universeId == experiment.universeId && + ex.testId == experiment.testIde && + ex.variationId == experiment.variationId && + ex.assignmentId == experiment.assignmentId + }); + if (experimentToMarkAsExposed) { + experimentToMarkAsExposed.isExposed = true; + } + + context.commit(storeMutations.UPDATE_EXPERIMENTS, experiments); + return globalMethods.callHttpClient({ method: endpoints.LogExperimentExposureIfAssigned.method, endpoint: endpoints.LogExperimentExposureIfAssigned.url, From 9247117e1242848e18c7cd658acb0c7f4c3965e8 Mon Sep 17 00:00:00 2001 From: Johnny shultz Date: Thu, 6 Feb 2025 13:01:54 -0500 Subject: [PATCH 06/21] CASH-176 CASH-176 Added email or sms to vin-lookup, address-lookup, and license plate-lookup --- src/layouts/address-lookup/address-lookup.vue | 23 +++++--- .../customer-questions/customer-questions.vue | 16 +++--- .../license-plate-lookup.vue | 37 +++++++++---- src/layouts/vin-lookup/vin-lookup.vue | 53 ++++++++++++++----- src/store/index.js | 3 +- 5 files changed, 94 insertions(+), 38 deletions(-) diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index 55d8a0499..8789f0839 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -18,7 +18,7 @@ @@ -59,12 +59,12 @@ import textBlock from "@/digital-components/text-block/text-block"; // DEFINE VALIDATION RULES defineRule("first-name-required", required(errorMessages.FIRST_NAME_REQUIRED)); defineRule("last-name-required", required(errorMessages.LAST_NAME_REQUIRED)); -defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED)); +defineRule("email-sms-required", required(errorMessages.EMAIL_SMS_REQUIRED)); defineRule( - "email-address-format", + "email-sms-format", regex( - /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/, - errorMessages.EMAIL_ADDRESS_FORMAT + /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$|^\(?(\d{3})\)?[-. ]?(\d{3})[-. ]?(\d{4})$/, + errorMessages.EMAIL_SMS_FORMAT ) ); @@ -84,7 +84,7 @@ export default { }, firstName: "", lastName: "", - emailAddress: "", + emailOrSms: "", }, }), }, diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index b374e8bb6..e1b3f721e 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -28,10 +28,10 @@ @@ -110,17 +110,18 @@ import { Form, defineRule } from "vee-validate"; import baseMixin from "@/mixins/base-mixin.js"; import store from "@/store"; import vinPagesMixin from "@/mixins/vin-pages-mixin"; +import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; // DEFINE VALIDATION RULES defineRule("license-plate-required", required(errorMessages.LICENSE_PLATE_REQUIRED)); defineRule("registration-zip-required", required(errorMessages.REGISTRATION_ZIP_REQUIRED)); defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT)); -defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED)); +defineRule("email-sms-required", required(errorMessages.EMAIL_SMS_REQUIRED)); defineRule( - "email-address-format", + "email-sms-format", regex( - /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/, - errorMessages.EMAIL_ADDRESS_FORMAT + /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$|^\(?(\d{3})\)?[-. ]?(\d{3})[-. ]?(\d{4})$/, + errorMessages.EMAIL_SMS_FORMAT ) ); @@ -155,7 +156,7 @@ export default { return { licensePlate: this.getLicensePlateFromStore(), registrationZipCode: this.getRegistrationZipFromStore() ?? this.$route.query.zipcode, - email: this.getEmailFromStore(), + emailOrSms: this.getEmailOrSmsFromStore(), serviceZipCode: this.getServiceZipFromStore(), displayNonServiceableZipAlert: false, displayVinNotFoundAlert: false, @@ -193,8 +194,8 @@ export default { getRegistrationZipFromStore() { return this.$store.getters.vehicle.registration.zipCode; }, - getEmailFromStore() { - return this.$store.getters.order.customer.emailAddress; + getEmailOrSmsFromStore() { + return this.$store.getters.emailOrSms; }, getServiceZipFromStore() { return this.$store.getters.order.serviceLocation.zipCode; @@ -310,7 +311,21 @@ export default { false ); - await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.email, false); + if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { + const phone = this.emailOrSms.replace(/[()]/g, ""); + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); + } else { + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + } + + await this.dispatchStoreAction( + storeActions.SAVE_PAGE_DATA, + { + page: fmgPageValues.EMAIL_SMS_PAGES, + data: { emailOrSmsValue: this.emailOrSms }, + }, + false + ); await this.dispatchStoreAction( storeActions.SAVE_SERVICE_ZIP_CODE_INFO, diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index eb184bd69..82c54d43a 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -46,10 +46,10 @@ @@ -151,16 +151,17 @@ 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"; +import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; // DEFINE VALIDATION RULES defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED)); defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT)); -defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED)); +defineRule("email-sms-required", required(errorMessages.EMAIL_SMS_REQUIRED)); defineRule( - "email-address-format", + "email-sms-format", regex( - /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/, - errorMessages.EMAIL_ADDRESS_FORMAT + /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$|^\(?(\d{3})\)?[-. ]?(\d{3})[-. ]?(\d{4})$/, + errorMessages.EMAIL_SMS_FORMAT ) ); defineRule("vin-required", required(errorMessages.VIN_REQUIRED)); @@ -195,7 +196,7 @@ export default { return { vin: this.getVinFromStore(), serviceZipCode: this.getZipFromStore() ?? this.$route.query.zipcode, - emailAddress: this.getEmailFromStore(), + emailOrSms: this.getEmailOrSmsFromStore(), isCarIdDifferent: false, customAlertData: {}, previouslyEnteredCarId: "", @@ -212,8 +213,8 @@ export default { arePagePrerequisitesValid() { return store.getters.vehicle.carId !== null; }, - getEmailFromStore() { - return this.$store.getters.order.customer.emailAddress; + getEmailOrSmsFromStore() { + return this.$store.getters.emailOrSms; }, getVinFromStore() { return this.$store.getters.vehicle.vin; @@ -329,7 +330,21 @@ export default { false ); - await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailAddress, false); + if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { + const phone = this.emailOrSms.replace(/[()]/g, ""); + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); + } else { + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + } + + await this.dispatchStoreAction( + storeActions.SAVE_PAGE_DATA, + { + page: fmgPageValues.EMAIL_SMS_PAGES, + data: { emailOrSmsValue: this.emailOrSms }, + }, + false + ); await this.dispatchStoreAction( storeActions.SAVE_SERVICE_ZIP_CODE_INFO, { @@ -365,7 +380,21 @@ export default { ); } - await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailAddress, false); + if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { + const phone = this.emailOrSms.replace(/[()]/g, ""); + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); + } else { + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + } + + await this.dispatchStoreAction( + storeActions.SAVE_PAGE_DATA, + { + page: fmgPageValues.EMAIL_SMS_PAGES, + data: { emailOrSmsValue: this.emailOrSms }, + }, + false + ); return await this.navigateForward(); } diff --git a/src/store/index.js b/src/store/index.js index 1feb02a2f..e1c726892 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1004,7 +1004,8 @@ export const getters = { isExternalParameter: (state) => externalParameterState?.isExternalParameter, emailOrSms: (state) => { - const email = externalParameterState.serviceZip.emailAddress ?? state.order.customer.emailAddress; + const email = + externalParameterState.serviceZip.emailAddress ?? state.order.customer.emailAddress; const phone = state.order.customer.phoneNumber; if (!phone && !email) { From 759e1eef57efd731278fcff740274985c0d19787 Mon Sep 17 00:00:00 2001 From: Johnny shultz Date: Thu, 6 Feb 2025 15:25:21 -0500 Subject: [PATCH 07/21] CASH-176 CASH-176 Fixed unit test for license-plate-spec --- .../license-plate-lookup/license-plate-lookup.spec.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js index 93aee887a..9dfbc4ed1 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -68,7 +68,7 @@ describe("license-plate-lookup.vue", () => { const { wrapper } = setupMocks({ emailAddress: mockEmail }); // ACT - const customerEmail = wrapper.vm.getEmailFromStore(); + const customerEmail = wrapper.vm.getEmailOrSmsFromStore(); // Assert expect(customerEmail).toEqual(mockEmail); @@ -625,6 +625,8 @@ function setupMocks({ licensePlate = null, //"TESTPLATE", emailAddress = null, //"test@test.com" }) { + console.log("======================================================================================================" + emailAddress); + console.log("serviceLocationZipCode" + serviceLocationZipCode); store.commit(storeMutations.RESET_STATE); //Mock api responses const apiResponses = { @@ -665,6 +667,7 @@ function setupMocks({ }, store: { getters: { + emailOrSms: emailAddress, vehicle: { registration: { licensePlate: licensePlate, From f9b043ca66d766c50c35a0c105692c24495df9b8 Mon Sep 17 00:00:00 2001 From: Johnny shultz Date: Thu, 6 Feb 2025 16:48:43 -0500 Subject: [PATCH 08/21] CASH-176 CASH-176 Removed console.logs from license-plate-lookup.spec.js --- .../save-progress-modal-question.vue | 4 ++-- src/layouts/address-lookup/address-lookup.vue | 6 +++++- .../license-plate-lookup/license-plate-lookup.spec.js | 2 -- src/store/index.js | 10 +++++----- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/fmg-components/save-progress-modal-question/save-progress-modal-question.vue b/src/fmg-components/save-progress-modal-question/save-progress-modal-question.vue index 27ca1f479..c6e31b781 100644 --- a/src/fmg-components/save-progress-modal-question/save-progress-modal-question.vue +++ b/src/fmg-components/save-progress-modal-question/save-progress-modal-question.vue @@ -158,8 +158,8 @@ export default { box-shadow: none; } &:focus-visible span { - outline: 2px solid #005FCC; - border-radius: .25rem; + outline: 2px solid #005fcc; + border-radius: 0.25rem; } &.delay { // fixes flicker while transitioning between states diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index 8789f0839..e069ee48d 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -361,7 +361,11 @@ export default { const phone = this.customerQuestions.emailOrSms.replace(/[()]/g, ""); await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); } else { - await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.customerQuestions.emailOrSms, false); + await this.dispatchStoreAction( + storeActions.SAVE_EMAIL, + this.customerQuestions.emailOrSms, + false + ); } await this.dispatchStoreAction( diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js index 9dfbc4ed1..2d4b729d8 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -625,8 +625,6 @@ function setupMocks({ licensePlate = null, //"TESTPLATE", emailAddress = null, //"test@test.com" }) { - console.log("======================================================================================================" + emailAddress); - console.log("serviceLocationZipCode" + serviceLocationZipCode); store.commit(storeMutations.RESET_STATE); //Mock api responses const apiResponses = { diff --git a/src/store/index.js b/src/store/index.js index ae85d311e..8e156871f 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1293,16 +1293,16 @@ export const actions = { { payload: { userId, deviceId, sessionKey, pageName, experiment }, pageNameToLog } ) { const experiments = deepClone(context.getters.applicationUser.experiments); - const experimentToMarkAsExposed = experiments.find(ex => { + const experimentToMarkAsExposed = experiments.find((ex) => { ex.universeId == experiment.universeId && - ex.testId == experiment.testIde && - ex.variationId == experiment.variationId && - ex.assignmentId == experiment.assignmentId + ex.testId == experiment.testIde && + ex.variationId == experiment.variationId && + ex.assignmentId == experiment.assignmentId; }); if (experimentToMarkAsExposed) { experimentToMarkAsExposed.isExposed = true; } - + context.commit(storeMutations.UPDATE_EXPERIMENTS, experiments); return globalMethods.callHttpClient({ From 11f3b06e6feff1052a5560ecef7416e2720a1213 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Fri, 7 Feb 2025 09:04:50 -0500 Subject: [PATCH 09/21] CASH-183 | Bug fix --- src/store/index.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 8e156871f..095767380 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1294,10 +1294,12 @@ export const actions = { ) { const experiments = deepClone(context.getters.applicationUser.experiments); const experimentToMarkAsExposed = experiments.find((ex) => { - ex.universeId == experiment.universeId && - ex.testId == experiment.testIde && + return ( + ex.universeId == experiment.universeId && + ex.testId == experiment.testId && ex.variationId == experiment.variationId && - ex.assignmentId == experiment.assignmentId; + ex.assignmentId == experiment.assignmentId + ); }); if (experimentToMarkAsExposed) { experimentToMarkAsExposed.isExposed = true; From 4886e0be923bd25b30c3780fe1792f401775726f Mon Sep 17 00:00:00 2001 From: CarlNation Date: Sat, 8 Feb 2025 07:43:24 -0500 Subject: [PATCH 10/21] CASH-207 CASH-97 CASH-207 CASH-97 - updates for tech review on CASH-97 for moving the vuex phone number update out of the router. The also implemented CASH-207 to default the smsOptin to true when quick quote supplies a mobile number. --- src/constants/store-actions.js | 1 + src/constants/store-mutations.js | 1 + src/layouts/estimate/estimate.vue | 14 ++++++++++++++ src/layouts/service-zip/service-zip.vue | 14 ++++++++++++++ src/router/index.js | 1 - src/store/index.js | 18 +++++++++++++----- 6 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 9ad6d9890..4750f1641 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -78,6 +78,7 @@ const storeActions = { SAVE_SCHEDULE: "saveSchedule", SAVE_EMAIL: "saveEmail", SAVE_PHONE_NUMBER: "savePhoneNumber", + SAVE_IS_SMS_OPT_IN: "saveIsSmsOptIn", SAVE_REGISTRATION_LICENSE_PLATE_LOOKUP: "saveRegistrationLicensePlateLookup", SAVE_VIN: "saveVin", SAVE_REGISTRATION_ADDRESS_LOOKUP: "saveRegistrationAddressLookup", diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 1ebf39b8d..d9cfc703e 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -42,6 +42,7 @@ const storeMutations = { // CUSTOMER MUTATIONS UPDATE_CUSTOMER_EMAIL_ADDRESS: "updateCustomerEmailAddress", UPDATE_CUSTOMER_PHONE_NUMBER: "updateCustomerPhoneNumber", + UPDATE_CUSTOMER_IS_SMS_OPT_IN: "updateCustomerIsSmsOptin", UPDATE_CUSTOMER_DETAILS: "updateCustomerDetails", // ORDER MUTATIONS diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue index 6a85ae349..5ab1df2ae 100644 --- a/src/layouts/estimate/estimate.vue +++ b/src/layouts/estimate/estimate.vue @@ -145,6 +145,20 @@ export default { vm.setCmsContent(resultMap.cmsContent); if (store.getters.externalParameterState?.isExternalParameter) { + if (store.getters.externalParameterCustomer.phoneNumber) { + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_PHONE_NUMBER, + store.getters.externalParameterCustomer.phoneNumber, + false + ); + + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_IS_SMS_OPT_IN, + true, + false + ); + } + if (store.getters.externalParameterEstimate.vinSelection) { vm.selectedVinLookupMethod = vinPagesMixin.methods.getVinlookupMethod( store.getters.externalParameterEstimate.vinSelection diff --git a/src/layouts/service-zip/service-zip.vue b/src/layouts/service-zip/service-zip.vue index 18a8b3362..88d160077 100644 --- a/src/layouts/service-zip/service-zip.vue +++ b/src/layouts/service-zip/service-zip.vue @@ -149,6 +149,20 @@ export default { ); } + if (store.getters.externalParameterCustomer.phoneNumber) { + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_PHONE_NUMBER, + store.getters.externalParameterCustomer.phoneNumber, + false + ); + + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_IS_SMS_OPT_IN, + true, + false + ); + } + baseMixin.methods.ResetExternalParamsAndHideModal(); } } diff --git a/src/router/index.js b/src/router/index.js index 83004b38c..2230a652d 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -898,7 +898,6 @@ function updateExternalParameterState() { storeMutations.UPDATE_EXTERNAL_PARAMETER_PHONE_NUMBER, externalParameterPhoneNumber ); - store.dispatch(storeActions.SAVE_PHONE_NUMBER, externalParameterPhoneNumber); } } diff --git a/src/store/index.js b/src/store/index.js index 095767380..bba99f230 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -346,6 +346,9 @@ export const mutations = { updateCustomerPhoneNumber(state, phoneNumber) { state.order.customer.phoneNumber = phoneNumber; }, + updateCustomerIsSmsOptin(state, isSmsOptIn) { + state.order.customer.isSmsOptIn = isSmsOptIn; + }, updateVehicle(state, vehicleInfo) { state.order.vehicle.year = vehicleInfo.year; state.order.vehicle.make = vehicleInfo.make; @@ -483,7 +486,7 @@ export const mutations = { saveExternalParameterState(externalParameterState); }, updateExternalParameterEmailAddress(state, emailAddress) { - externalParameterState.serviceZip.emailAddress = emailAddress; + externalParameterState.customer.emailAddress = emailAddress; saveExternalParameterState(externalParameterState); }, updateExternalParameterIsInsurance(state, isInsurance) { @@ -524,7 +527,6 @@ export const mutations = { }, resetExternalParameterServiceZipState(state) { externalParameterState.serviceZip.zipCode = null; - externalParameterState.serviceZip.emailAddress = null; saveExternalParameterState(externalParameterState); }, resetExternalParameterQuoteState(state) { @@ -536,6 +538,7 @@ export const mutations = { saveExternalParameterState(externalParameterState); }, resetExternalParameterCustomerState(state) { + externalParameterState.customer.emailAddress = null; externalParameterState.customer.phoneNumber = null; saveExternalParameterState(externalParameterState); }, @@ -1005,8 +1008,9 @@ export const getters = { emailOrSms: (state) => { const email = - externalParameterState.serviceZip.emailAddress ?? state.order.customer.emailAddress; - const phone = state.order.customer.phoneNumber; + externalParameterState.customer.emailAddress ?? state.order.customer.emailAddress; + const phone = + externalParameterState.customer.phoneNumber ?? state.order.customer.phoneNumber; if (!phone && !email) { return null; @@ -3088,6 +3092,10 @@ export const actions = { phoneNumber === "" ? null : phoneNumber ); }, + saveIsSmsOptIn(context, isSmsOptIn) { + debugger; // eslint-disable-line + context.commit(storeMutations.UPDATE_CUSTOMER_IS_SMS_OPT_IN, isSmsOptIn); + }, savePageData(context, emailOrSms) { context.commit(storeMutations.UPDATE_PAGE_DATA, emailOrSms); @@ -3752,7 +3760,6 @@ function createExternalParameterDefaultState() { vinSelection: null, }, serviceZip: { - emailAddress: null, zipCode: null, }, quote: { @@ -3760,6 +3767,7 @@ function createExternalParameterDefaultState() { servicePackage: null, }, customer: { + emailAddress: null, phoneNumber: null, }, }; From 1764db4739fdbaa3010caed1a928dc3fb31adbc4 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Sat, 8 Feb 2025 08:57:02 -0500 Subject: [PATCH 11/21] CASH-207 CASH-207 null check --- src/layouts/service-zip/service-zip.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/service-zip/service-zip.vue b/src/layouts/service-zip/service-zip.vue index 88d160077..b01f99c06 100644 --- a/src/layouts/service-zip/service-zip.vue +++ b/src/layouts/service-zip/service-zip.vue @@ -149,7 +149,7 @@ export default { ); } - if (store.getters.externalParameterCustomer.phoneNumber) { + if (store.getters.externalParameterCustomer?.phoneNumber) { await baseMixin.methods.dispatchStoreAction( storeActions.SAVE_PHONE_NUMBER, store.getters.externalParameterCustomer.phoneNumber, From 3c55924140ece4d4d70036755a4effe4ee320e85 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Sat, 8 Feb 2025 09:17:04 -0500 Subject: [PATCH 12/21] CASH-207 CASH-207 another null check --- src/layouts/estimate/estimate.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue index 5ab1df2ae..b9fdf1958 100644 --- a/src/layouts/estimate/estimate.vue +++ b/src/layouts/estimate/estimate.vue @@ -145,7 +145,7 @@ export default { vm.setCmsContent(resultMap.cmsContent); if (store.getters.externalParameterState?.isExternalParameter) { - if (store.getters.externalParameterCustomer.phoneNumber) { + if (store.getters.externalParameterCustomer?.phoneNumber) { await baseMixin.methods.dispatchStoreAction( storeActions.SAVE_PHONE_NUMBER, store.getters.externalParameterCustomer.phoneNumber, From 398eac72a673c527a3a2a97405ba80a4703073ba Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 10 Feb 2025 06:10:44 -0500 Subject: [PATCH 13/21] CASH-207 CASH-207 missed debugger statement --- src/store/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index bba99f230..b8a11e928 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -3093,7 +3093,6 @@ export const actions = { ); }, saveIsSmsOptIn(context, isSmsOptIn) { - debugger; // eslint-disable-line context.commit(storeMutations.UPDATE_CUSTOMER_IS_SMS_OPT_IN, isSmsOptIn); }, From 5e661111e1e6ce778545facdcf2c8237da340a60 Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Tue, 11 Feb 2025 13:51:03 +0530 Subject: [PATCH 14/21] CASH-170 creating async function as the computed property can not directly handle asynchronous operations or promises. --- .../mobile-location-modal-questions.spec.js | 21 ++++++++---- .../mobile-location-modal-questions.vue | 24 ++++++++++---- .../service-location/service-location.spec.js | 32 ++++++++++++++++--- .../service-location/service-location.vue | 12 +++++-- 4 files changed, 69 insertions(+), 20 deletions(-) diff --git a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js index 863a04c82..91f26b64d 100644 --- a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js +++ b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js @@ -203,7 +203,7 @@ describe("mobile-location-modal-questions.vue", () => { expect(wrapper.vm.$refs.MobileLocationModalWidget.openModal).toHaveBeenCalled(); }); - it("Should emit update:modelValue on setMobileLocation for a valid address and vehicle protection answer", async () => { + it("Should emit updated-mobile-location-questions on setMobileLocation for a valid address and vehicle protection answer", async () => { // Arrange const mobileLocationQuestions = { addressQuestions: { @@ -240,17 +240,26 @@ describe("mobile-location-modal-questions.vue", () => { }); wrapper.vm.$refs.MobileLocationModalWidget.closeModal = jest.fn(); + // Mock the emitEvent function + wrapper.vm.emitEvent = jest.fn(async (eventName, payload) => { + return new Promise((resolve) => { + wrapper.vm.$emit(eventName, newMobileLocationQuestions, resolve); + resolve(newMobileLocationQuestions); + }); + }); // Act wrapper.vm.internalModel = newMobileLocationQuestions; + await wrapper.vm.setMobileLocation(); - let expectedEmit = [[newMobileLocationQuestions]]; - // Assert - expect(wrapper.emitted("update:modelValue")).toEqual(expectedEmit); + expect(wrapper.emitted()["updated-mobile-location-questions"]).toBeTruthy(); + expect(wrapper.emitted()["updated-mobile-location-questions"][0][0]).toBe( + newMobileLocationQuestions + ); }); - it("Should not emit update:modelValue on setMobileLocation for an invalid address zip code", async () => { + it("Should not emit updated-mobile-location-questions on setMobileLocation for an invalid address zip code", async () => { // Arrange const mobileLocationQuestions = { addressQuestions: { @@ -293,7 +302,7 @@ describe("mobile-location-modal-questions.vue", () => { await wrapper.vm.setMobileLocation(); // Assert - expect(wrapper.emitted("update:modelValue")).not.toBeTruthy(); + expect(wrapper.emitted("updated-mobile-location-questions")).not.toBeTruthy(); }); it("Should display invalid zip alert for invalid address zip inputs", async () => { 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 d88bd53e2..dadbaff8b 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 @@ -98,6 +98,7 @@ export default { "updated-contains-military-base", "updated-bill-to-account-number", "mobileLocationSelected", + "updated-mobile-location-questions", ], data() { return { @@ -251,10 +252,15 @@ export default { if (!zipCodeData.isValid) { this.displayInvalidZipAlert = true; this.resetModalButtonStyle(); + return; } else if (zipCodeData.state != this.internalModel.addressQuestions.state) { this.displayMismatchStateAndZipAlert = true; this.resetModalButtonStyle(); - } else { + return; + } else if ( + this.internalModel.addressQuestions.zipCode !== + this.modelValue.addressQuestions.zipCode + ) { // retrieve mobile fee part const serviceZipCode = this.internalModel.addressQuestions.zipCode; const mobileFeePart = await getPricedMobileFeePart( @@ -279,13 +285,17 @@ export default { 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"); } + // update the page level model + await this.emitEvent("updated-mobile-location-questions", this.internalModel); + + this.$emit("mobileLocationSelected"); + }, + //creating emitEvent function to raise events with resolve callback to handle events sequencing + async emitEvent(eventName, payload) { + return new Promise((resolve) => { + this.$emit(eventName, payload, resolve); + }); }, }, watch: { diff --git a/src/layouts/service-location/service-location.spec.js b/src/layouts/service-location/service-location.spec.js index 54f28a89c..b29ec604b 100644 --- a/src/layouts/service-location/service-location.spec.js +++ b/src/layouts/service-location/service-location.spec.js @@ -463,11 +463,23 @@ describe("service-location.vue", () => { }; // Act - mobileLocationQuestionsComponent.vm.$emit( - "update:modelValue", + + // Mock the emitEvent function + mobileLocationQuestionsComponent.vm.emitEvent = jest.fn(async (eventName, payload) => { + return new Promise((resolve) => { + mobileLocationQuestionsComponent.vm.$emit(eventName, payload, resolve); + }); + }); + + // Trigger the event + await mobileLocationQuestionsComponent.vm.emitEvent( + "updated-mobile-location-questions", newMobileLocationQuestions ); + await wrapper.vm.$nextTick(); // Wait for DOM updates + await new Promise((resolve) => setTimeout(resolve, 0)); // Wait for promise to resolve + // Assert expect(wrapper.vm.mobileLocationQuestions).toStrictEqual(newMobileLocationQuestions); }); @@ -532,11 +544,23 @@ describe("service-location.vue", () => { }; // Act - mobileLocationQuestionsComponent.vm.$emit( - "update:modelValue", + + // Mock the emitEvent function + mobileLocationQuestionsComponent.vm.emitEvent = jest.fn(async (eventName, payload) => { + return new Promise((resolve) => { + mobileLocationQuestionsComponent.vm.$emit(eventName, payload, resolve); + }); + }); + + // Trigger the event + await mobileLocationQuestionsComponent.vm.emitEvent( + "updated-mobile-location-questions", newMobileLocationQuestions ); + await wrapper.vm.$nextTick(); // Wait for DOM updates + await new Promise((resolve) => setTimeout(resolve, 0)); // Wait for promise to resolve + // Assert expect(wrapper.vm.serviceZipCodeQuestion).toStrictEqual(newServiceZipCodeInfo); }); diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 9addea705..47cf5262e 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -93,6 +93,7 @@ @updated-serviceability="setServiceabilityDetails" @updated-contains-military-base="setContainsMilitaryBase" @updated-mobile-ctu="setCtuForMobile" + @updated-mobile-location-questions="setMobileLocationQuestions" validationRules="mobile-location-required" ref="mobileLocationQuestions" linkWidgetName="MobileLocationLinkWidget" @@ -296,17 +297,18 @@ export default { isVehicleProtected: this.isVehicleProtected, }; }, - set: function (newValue) { + async set(newValue) { if (newValue.addressQuestions.zipCode !== this.zipCode) { - getShopProviderData(newValue.addressQuestions.zipCode).then((result) => { + await getShopProviderData(newValue.addressQuestions.zipCode).then((result) => { this.shopProviderData = result.data; this.selectedProvider = new Provider( this.shopProviderData.mobileProviderNumber ); }); } - this.setMobileLocation(newValue); + //handle promise + newValue.resolve?.(); }, }, isServiceableMobile() { @@ -485,6 +487,10 @@ export default { setMobileFeePart(mobileFeePart) { this.mobileFeePart = mobileFeePart; }, + //creating async function as the computed property can not directly handle asynchronous operations or promises. + async setMobileLocationQuestions(newValue, resolve) { + this.mobileLocationQuestions = { ...newValue, resolve }; + }, getServiceAddressFromStore() { return store.getters.order.serviceLocation.address; }, From 53da1ac5ebb32e583ff4020b69f4b354f563a5f9 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 11 Feb 2025 04:27:52 -0500 Subject: [PATCH 15/21] CASH-240 CASH-240 make sure to save phone and sms optin before navigating --- src/layouts/service-zip/service-zip.vue | 52 ++++++++++++------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/layouts/service-zip/service-zip.vue b/src/layouts/service-zip/service-zip.vue index b01f99c06..717880553 100644 --- a/src/layouts/service-zip/service-zip.vue +++ b/src/layouts/service-zip/service-zip.vue @@ -133,36 +133,36 @@ export default { vm.setCmsContent(resultMap.cmsContent); if (store.getters.externalParameterState?.isExternalParameter) { + if (store.getters.externalParameterServiceZip.zipCode) { + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_SERVICE_ZIP_CODE_INFO, + { + zipCode: store.getters.externalParameterServiceZip.zipCode, + state: null, + zipCodeCtu: null, + }, + false + ); + } + + if (store.getters.externalParameterCustomer?.phoneNumber) { + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_PHONE_NUMBER, + store.getters.externalParameterCustomer.phoneNumber, + false + ); + + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_IS_SMS_OPT_IN, + true, + false + ); + } + const isValid = await baseMixin.methods.isFormValid(vm.$refs.theForm); if (isValid) { vm.forwardButtonAction(); } else { - if (store.getters.externalParameterServiceZip.zipCode) { - await baseMixin.methods.dispatchStoreAction( - storeActions.SAVE_SERVICE_ZIP_CODE_INFO, - { - zipCode: store.getters.externalParameterServiceZip.zipCode, - state: null, - zipCodeCtu: null, - }, - false - ); - } - - if (store.getters.externalParameterCustomer?.phoneNumber) { - await baseMixin.methods.dispatchStoreAction( - storeActions.SAVE_PHONE_NUMBER, - store.getters.externalParameterCustomer.phoneNumber, - false - ); - - await baseMixin.methods.dispatchStoreAction( - storeActions.SAVE_IS_SMS_OPT_IN, - true, - false - ); - } - baseMixin.methods.ResetExternalParamsAndHideModal(); } } From 80caabf5efdabba4ab37d51169c46666e99f9199 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 11 Feb 2025 09:10:00 -0500 Subject: [PATCH 16/21] CASH-201 | Add "Pay on my own" link Add the link to insurance-company Make cash auto selected on quote when this link is used --- .../insurance-company/insurance-company.vue | 16 +++++++++++++++- src/layouts/quote/quote.vue | 4 ++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/layouts/insurance-company/insurance-company.vue b/src/layouts/insurance-company/insurance-company.vue index 79e238d47..ddfffe177 100644 --- a/src/layouts/insurance-company/insurance-company.vue +++ b/src/layouts/insurance-company/insurance-company.vue @@ -16,6 +16,13 @@ v-model="parentAccountNumber" :originalList="originalList" /> + diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 4428f6e40..99b75c9a7 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -328,6 +328,10 @@ export default { } const getIsInsuranceSelectedValue = (availableLineItems, insuranceThreshold) => { + // routeParam checked here is set on insurance-selection "Pay on my own" link click + if (from.params.forceCashSelection) { + return false; + } const serviceLocationState = store.getters.order.serviceLocation.state; // usually true when returning from heritage but can be false when returning from heritage on a save quote From 37cd5f01bfb92d5eaa07a4a50ac977a048e4a15b Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 11 Feb 2025 09:20:48 -0500 Subject: [PATCH 17/21] CASH-201 | Update unit test Fixed broken tests, haven't added new ones yet --- src/layouts/quote/quote.spec.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js index deca0d6d1..42e3aecd0 100644 --- a/src/layouts/quote/quote.spec.js +++ b/src/layouts/quote/quote.spec.js @@ -293,7 +293,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - undefined, + {params:{}}, (c) => c(wrapper.vm) ); @@ -345,7 +345,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - undefined, + {params:{}}, (c) => c(wrapper.vm) ); //Assert @@ -388,7 +388,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - undefined, + {params:{}}, (c) => c(wrapper.vm) ); @@ -432,7 +432,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote", isInsurance: false } }, - undefined, + {params:{}}, (c) => c(wrapper.vm) ); @@ -478,7 +478,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - undefined, + {params:{}}, (c) => c(wrapper.vm) ); @@ -523,7 +523,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - undefined, + {params:{}}, (c) => c(wrapper.vm) ); @@ -570,7 +570,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - undefined, + {params:{}}, (c) => c(wrapper.vm) ); @@ -618,7 +618,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - undefined, + {params:{}}, (c) => c(wrapper.vm) ); @@ -662,7 +662,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - undefined, + {params:{}}, (c) => c(wrapper.vm) ); //Assert @@ -783,7 +783,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - undefined, + {params:{}}, nextFunction ); await nextTick(); From 738e6a108d025e812cda4f68986e9cfdd26f3aa5 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 11 Feb 2025 10:20:34 -0500 Subject: [PATCH 18/21] CASH-201 | Switch to query parameter --- .../insurance-company/insurance-company.vue | 9 ++++++--- src/layouts/quote/quote.spec.js | 20 +++++++++---------- src/layouts/quote/quote.vue | 4 ++-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/layouts/insurance-company/insurance-company.vue b/src/layouts/insurance-company/insurance-company.vue index ddfffe177..452484e48 100644 --- a/src/layouts/insurance-company/insurance-company.vue +++ b/src/layouts/insurance-company/insurance-company.vue @@ -101,7 +101,7 @@ export default { return !!this.parentAccountNumber; }, payWithCashButtonCopy() { - return "Pay on my own"; + return this.getCmsContent("PayWithCashWidget", "Text"); } }, methods: { @@ -122,8 +122,11 @@ export default { }, backButtonAction(forceCashSelectionOnQuote) { // Go back to Quote page - if (forceCashSelectionOnQuote) - this.$route.params['forceCashSelection'] = true; + if (forceCashSelectionOnQuote) { + this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route, {"isCashSelected": true}); + return; + } + this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route); }, async forwardButtonAction() { diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js index 42e3aecd0..deca0d6d1 100644 --- a/src/layouts/quote/quote.spec.js +++ b/src/layouts/quote/quote.spec.js @@ -293,7 +293,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - {params:{}}, + undefined, (c) => c(wrapper.vm) ); @@ -345,7 +345,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - {params:{}}, + undefined, (c) => c(wrapper.vm) ); //Assert @@ -388,7 +388,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - {params:{}}, + undefined, (c) => c(wrapper.vm) ); @@ -432,7 +432,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote", isInsurance: false } }, - {params:{}}, + undefined, (c) => c(wrapper.vm) ); @@ -478,7 +478,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - {params:{}}, + undefined, (c) => c(wrapper.vm) ); @@ -523,7 +523,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - {params:{}}, + undefined, (c) => c(wrapper.vm) ); @@ -570,7 +570,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - {params:{}}, + undefined, (c) => c(wrapper.vm) ); @@ -618,7 +618,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - {params:{}}, + undefined, (c) => c(wrapper.vm) ); @@ -662,7 +662,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - {params:{}}, + undefined, (c) => c(wrapper.vm) ); //Assert @@ -783,7 +783,7 @@ describe("quote.vue", () => { await quote.beforeRouteEnter.call( wrapper.vm, { query: { fmgPage: "quote" } }, - {params:{}}, + undefined, nextFunction ); await nextTick(); diff --git a/src/layouts/quote/quote.vue b/src/layouts/quote/quote.vue index 99b75c9a7..20dc16304 100644 --- a/src/layouts/quote/quote.vue +++ b/src/layouts/quote/quote.vue @@ -328,8 +328,8 @@ export default { } const getIsInsuranceSelectedValue = (availableLineItems, insuranceThreshold) => { - // routeParam checked here is set on insurance-selection "Pay on my own" link click - if (from.params.forceCashSelection) { + // query param checked here is set on insurance-selection "Pay on my own" link click + if (to.query?.isCashSelected || to.query?.iscashselected) { return false; } const serviceLocationState = store.getters.order.serviceLocation.state; From 8b2b22b86846854765f6a5943e3041cf03516243 Mon Sep 17 00:00:00 2001 From: Scott Kiener Date: Tue, 11 Feb 2025 10:33:52 -0500 Subject: [PATCH 19/21] CASH-201 | Add unit test --- src/layouts/quote/quote.spec.js | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js index deca0d6d1..522bc4f2e 100644 --- a/src/layouts/quote/quote.spec.js +++ b/src/layouts/quote/quote.spec.js @@ -577,6 +577,56 @@ describe("quote.vue", () => { //Assert expect(wrapper.vm.isInsuranceSelected).toBe(false); }); + test("should default to cash if isCashSelected is true, despite all other checks pointing to insurance selection", async () => { + // Also needs no query parameter or previous selection in store to be present + //Arrange + + store.getters = { + lineItems: { + glassParts: ["item", "item2"], + }, + applicationUser: { + experiments: [], + }, + order: { + lineItems: { + glassParts: ["item", "item2"], + }, + payment: { + isInsurance: true, + }, + customer: { + emailAddress: "test@test.com", + }, + serviceLocation: { + state: null, + }, + }, + vehicle: { + cardId: "123", + }, + experimentSettings: { + settingName: "SERVICE_PACKAGE_DISCOUNT", + }, + }; + mockTierOnePrice = 505; + const { wrapper } = setupMocks({}); + + + //Act + await quote.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "quote", + isInsuranceSelected: true, + isCashSelected: true, + } }, + undefined, + (c) => c(wrapper.vm) + ); + + //Assert + expect(wrapper.vm.isInsuranceSelected).toBe(false); + }); test("should default to insurance if total economy package price is over $500", async () => { // Also needs no query parameter or previous selection in store to be present //Arrange From 3e75513993a64cd893419c41a605b376dbed08a5 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 11 Feb 2025 15:01:59 -0500 Subject: [PATCH 20/21] CASH-240 CASH-240 save phone and sms optin when other damage type passed in on quickquote --- .../molding-questions/molding-questions.vue | 14 ++++++++++++++ src/layouts/part-questions/part-questions.vue | 15 +++++++++++++++ src/layouts/vehicle-damage/vehicle-damage.vue | 14 ++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/src/layouts/molding-questions/molding-questions.vue b/src/layouts/molding-questions/molding-questions.vue index 1bcc3d7a8..2c5f5a7c3 100644 --- a/src/layouts/molding-questions/molding-questions.vue +++ b/src/layouts/molding-questions/molding-questions.vue @@ -78,6 +78,20 @@ export default { ); } + if (store.getters.externalParameterCustomer?.phoneNumber) { + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_PHONE_NUMBER, + store.getters.externalParameterCustomer.phoneNumber, + false + ); + + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_IS_SMS_OPT_IN, + true, + false + ); + } + baseMixin.methods.ResetExternalParamsAndHideModal(); } }); diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index f905e86c7..d60ddbb70 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -79,6 +79,21 @@ export default { false ); } + + if (store.getters.externalParameterCustomer?.phoneNumber) { + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_PHONE_NUMBER, + store.getters.externalParameterCustomer.phoneNumber, + false + ); + + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_IS_SMS_OPT_IN, + true, + false + ); + } + baseMixin.methods.ResetExternalParamsAndHideModal(); } }); diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index 6e9c4b198..46efb4728 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -152,6 +152,20 @@ export default { if (isValid) { vm.forwardButtonAction(); } else { + if (store.getters.externalParameterCustomer?.phoneNumber) { + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_PHONE_NUMBER, + store.getters.externalParameterCustomer.phoneNumber, + false + ); + + await baseMixin.methods.dispatchStoreAction( + storeActions.SAVE_IS_SMS_OPT_IN, + true, + false + ); + } + if (store.getters.externalParameterServiceZip.zipCode) { await baseMixin.methods.dispatchStoreAction( storeActions.SAVE_SERVICE_ZIP_CODE_INFO, From 7caadb88808ae69c50ae12fbb04179d1615c3af3 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Wed, 12 Feb 2025 12:50:23 -0500 Subject: [PATCH 21/21] CASH-250 CASH-250 clear phone / email when user clears the field --- src/layouts/service-zip/service-zip.vue | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/layouts/service-zip/service-zip.vue b/src/layouts/service-zip/service-zip.vue index 717880553..ae7609da8 100644 --- a/src/layouts/service-zip/service-zip.vue +++ b/src/layouts/service-zip/service-zip.vue @@ -202,11 +202,18 @@ export default { async forwardButtonAction() { const zipCodeData = await this.getZipCodeData(this.serviceZipCode); - if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { - const phone = this.emailOrSms.replace(/[()]/g, ""); - await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); - } else { - await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + // if no value due to field being optional, blank both phone and email address + if (!this.emailOrSms) { + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, "", false); + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, "", false); + } + else { + if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { + const phone = this.emailOrSms.replace(/[()]/g, ""); + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); + } else { + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + } } await this.dispatchStoreAction(