From bba2631ec5722a8dc54b53f8862bf8882a10cad0 Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Mon, 13 Jan 2025 09:36:16 -0500 Subject: [PATCH 01/22] CASH-69 --- src/constants/store-mutations.js | 2 ++ .../service-location/service-location.vue | 11 +++++++- src/layouts/vehicle/vehicle.vue | 8 ++++++ src/store/index.js | 25 ++++++++++++++++++- 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 740c5a47e..f625e27cf 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -16,6 +16,8 @@ const storeMutations = { UPDATE_VEHICLE_IMAGE_COLOR: "updateVehicleImageColor", UPDATE_VEHICLE_VIN: "updateVehicleVin", UPDATE_VEHICLE: "updateVehicle", + UPDATE_VEHICLE_MOBILE_STATIC_RECALIBRATION_APPLICABLE: + "updateIsMobileStaticRecalibrationApplicable", UPDATE_IS_REPAIR: "updateIsRepair", UPDATE_NUMBER_OF_CHIPS: "updateNumberOfChips", diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 4017088c4..70991f0f5 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -188,6 +188,8 @@ export default { isRecalibrationServiceableInshop: null, isGlassServiceableMobile: null, isRecalibrationServiceableMobile: null, + isVehicleMobileStaticRecalibrationApplicable: + this.getIsVehicleMobileStaticRecalibrationApplicableFromStore(), selectedAppointmentType: this.getSelectedAppointmentType(), selectedProvider: this.getSelectedProvider(), mobileFeePart: null, @@ -306,7 +308,11 @@ export default { }, isServiceableMobile() { if (this.isRecalibrationServiceableMobile !== null) { - return this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile; + return ( + this.isGlassServiceableMobile && + this.isRecalibrationServiceableMobile && + this.isVehicleMobileStaticRecalibrationApplicable + ); } else { return this.isGlassServiceableMobile; } @@ -485,6 +491,9 @@ export default { getSelectedProvider() { return store.getters.order.serviceLocation.provider; }, + getIsVehicleMobileStaticRecalibrationApplicableFromStore() { + return store.getters.order.vehicle.isMobileStaticRecalibrationApplicable; + }, resetMobileLocation() { this.streetAddress = ""; this.apartmentNumberOrBusinessName = ""; diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index 18eee6988..6a634d826 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -117,6 +117,7 @@ export default { modelOptions: [], styleOptions: [], displayNoServiceAlert: false, + isMobileStaticRecalibrationApplicable: this.getIsMobileStaticRecalibrationApplicable(), }; }, @@ -438,6 +439,8 @@ export default { this.imageVifNumber = result?.data.imageVifNumber; this.imageVifColor = result?.data.imageVifColor; this.displayNoServiceAlert = !result?.data.canSafeliteService; + this.isMobileStaticRecalibrationApplicable = + result?.data.isMobileStaticRecalibrationApplicable; }, resetAlert() { this.displayNoServiceAlert = false; @@ -456,6 +459,8 @@ export default { imageUrl: this.imageUrl, imageVifNumber: this.imageVifNumber, imageVifColor: this.imageVifColor, + isMobileStaticRecalibrationApplicable: + this.isMobileStaticRecalibrationApplicable, }, false ); @@ -531,6 +536,9 @@ export default { getImageVifColorfromStore() { return store.getters.vehicle.imageVifColor; }, + getIsMobileStaticRecalibrationApplicable() { + return store.getters.vehicle.isMobileStaticRecalibrationApplicable; + }, }, components: { diff --git a/src/store/index.js b/src/store/index.js index d964a48d5..d7f7dcb06 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -68,6 +68,7 @@ const getDefaultState = () => { registration: { licensePlate: null, }, + isMobileStaticRecalibrationApplicable: false, }, serviceLocation: { address: null, @@ -225,6 +226,10 @@ export const mutations = { updateVehicleVin(state, vin) { state.order.vehicle.vin = vin; }, + updateIsMobileStaticRecalibrationApplicable(state, isMobileStaticRecalibrationApplicable) { + state.order.vehicle.isMobileStaticRecalibrationApplicable = + isMobileStaticRecalibrationApplicable; + }, updateIsRepair(state, isRepair) { state.order.damage.isRepair = isRepair; }, @@ -350,6 +355,8 @@ export const mutations = { state.order.vehicle.imageUrl = vehicleInfo.imageUrl; state.order.vehicle.imageVifNumber = vehicleInfo.imageVifNumber; state.order.vehicle.imageColor = vehicleInfo.imageVifColor; + state.order.vehicle.isMobileStaticRecalibrationApplicable = + vehicleInfo.isMobileStaticRecalibrationApplicable; }, updateRegistration(state, registrationInfo) { state.order.vehicle.registration.licensePlate = registrationInfo?.licensePlate; @@ -534,6 +541,7 @@ export const mutations = { state.order.vehicle.imageUrl = null; state.order.vehicle.imageVifNumber = null; state.order.vehicle.imageColor = null; + state.order.vehicle.isMobileStaticRecalibrationApplicable = false; }, resetDamageState(state) { state.order.damage.isRepair = null; @@ -2221,7 +2229,18 @@ export const actions = { // Vehicle saveVehicle( context, - { year, make, model, style, carId, category, imageUrl, imageVifNumber, imageVifColor } + { + year, + make, + model, + style, + carId, + category, + imageUrl, + imageVifNumber, + imageVifColor, + isMobileStaticRecalibrationApplicable, + } ) { if ( context.state.order.vehicle.year != year || @@ -2242,6 +2261,10 @@ export const actions = { context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, imageUrl); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, imageVifNumber); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, imageVifColor); + context.commit( + storeMutations.UPDATE_VEHICLE_MOBILE_STATIC_RECALIBRATION_APPLICABLE, + isMobileStaticRecalibrationApplicable + ); } }, From 32fc82176b7c6292aeb2cfaeea5386a88c32e44b Mon Sep 17 00:00:00 2001 From: Matt Caimi Date: Mon, 13 Jan 2025 13:57:06 -0500 Subject: [PATCH 02/22] CASH-69 fix unit test --- src/layouts/service-location/service-location.spec.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/layouts/service-location/service-location.spec.js b/src/layouts/service-location/service-location.spec.js index eea946b89..6333082ec 100644 --- a/src/layouts/service-location/service-location.spec.js +++ b/src/layouts/service-location/service-location.spec.js @@ -181,6 +181,9 @@ beforeEach(() => { zipCode: "43235", state: "OH", }, + vehicle: { + isMobileStaticRecalibrationApplicable: true, + }, }, damage: { isRepair: false, From d9933d861c6db1989b16f904fecf51dff27f5114 Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Thu, 16 Jan 2025 10:05:20 -0500 Subject: [PATCH 03/22] CASH-69: Get MSR fee and offer mobile service if applicable for cash and insurance --- .../service-location-helper.js | 5 ++- .../service-location/service-location.vue | 23 +++++++++++--- src/store/index.js | 31 +++++++++++++++++-- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js index 1e7b6bdb3..0e86c4143 100644 --- a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js +++ b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js @@ -11,7 +11,10 @@ export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) { // Get the Mobile Fee Part const mobileFeePart = await baseMixin.methods.dispatchStoreActionWithLogging( storeActions.GET_MOBILE_FEE_PART, - null, + { + serviceZipCode: serviceZipCode, + serviceZipCodeCtu: zipCodeData.zipCodeCtu, + }, pageNameToLog, false ); diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 70991f0f5..21a123e6e 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -159,6 +159,7 @@ import { defineRule } from "vee-validate"; import { errorMessages } from "@/constants/error-messages"; const MOBILE_FEE_PART_TYPE = "MOBILE FEE"; +const MOBILE_STATIC_RECAL_FEE_PART_NUMBER = "RECAL MOBILE"; // DEFINE VALIDATION RULES defineRule("mobile-location-required", (value) => { @@ -309,14 +310,27 @@ export default { isServiceableMobile() { if (this.isRecalibrationServiceableMobile !== null) { return ( - this.isGlassServiceableMobile && - this.isRecalibrationServiceableMobile && - this.isVehicleMobileStaticRecalibrationApplicable + (this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile) || + this.isMobileStaticRecalibrationApplicable ); } else { return this.isGlassServiceableMobile; } }, + isMobileStaticRecalibrationApplicable() { + if (!this.isInsurance) { + return ( + this.isVehicleMobileStaticRecalibrationApplicable && + this.mobileFeePart?.partNumber == MOBILE_STATIC_RECAL_FEE_PART_NUMBER + ); + } else { + return ( + this.isVehicleMobileStaticRecalibrationApplicable && + this.mobileFeePart?.partNumber == MOBILE_STATIC_RECAL_FEE_PART_NUMBER && + this.mobileFeePart?.isInsurable + ); + } + }, mobileFeeApplies() { if ( this.mobileFeePart?.laborAmount > 0 || @@ -355,7 +369,8 @@ export default { return ( this.isServiceableInshop && this.isGlassServiceableMobile && - this.isRecalibrationServiceableMobile === false + this.isRecalibrationServiceableMobile === false && + !this.isMobileStaticRecalibrationApplicable ); }, displayRecalibrationWarning() { diff --git a/src/store/index.js b/src/store/index.js index d7f7dcb06..2c68cab38 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1607,7 +1607,7 @@ export const actions = { return response; }, - getMobileFeePart(context, { pageNameToLog }) { + getMobileFeePart(context, { payload: { serviceZipCode, serviceZipCodeCtu }, pageNameToLog }) { const serviceType = context.getters.damage.isRepair ? "Repair" : "Install"; const facilityType = "Mobile"; const parentAccountNumber = context.getters.payment.parentAccountNumber; @@ -1619,16 +1619,31 @@ export const actions = { const coverageStatus = coverageStatusEnum(order.payment?.insuranceCoverage?.coverageStatus); const coverageType = coverageTypeEnum(order.payment?.insuranceCoverage?.coverageType); const isItacOptimized = order.policy?.isItac ?? false; + const isMobileStaticRecalibrationApplicable = + order.vehicle?.isMobileStaticRecalibrationApplicable; const zipCode = - order.serviceLocation?.provider?.address?.zipCode ?? order.serviceLocation?.zipCode; + serviceZipCode ?? + order.serviceLocation?.provider?.address?.zipCode ?? + order.serviceLocation?.zipCode; var providerNumber = - order.serviceLocation?.provider?.providerNumber ?? order.serviceLocation?.zipCodeCtu; + serviceZipCodeCtu ?? + order.serviceLocation?.provider?.providerNumber ?? + order.serviceLocation?.zipCodeCtu; if (providerNumber.startsWith("00") && providerNumber.length > 5) { providerNumber = providerNumber.substring(1); } var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItacOptimized=${isItacOptimized}&zipCode=${zipCode}`; + + if (isMobileStaticRecalibrationApplicable) { + const staticRecalPartNumber = getStaticRecalPartNumber(order.lineItems?.glassParts[0]); + const carId = order.vehicle?.carId; + if (staticRecalPartNumber && carId) { + endPoint = `${endPoint}&partNumbers=${staticRecalPartNumber}&carId=${carId}`; + } + } + if (coverageStatus) { endPoint = `${endPoint}&coverageStatus=${coverageStatus}`; } @@ -3666,3 +3681,13 @@ function getExternalParameterDefaultState() { function saveExternalParameterState(externalParameterState) { window.sessionStorage.setItem("externalParameterState", JSON.stringify(externalParameterState)); } + +//This function checks if static recalibration is available for the vehicle and returns the part number for it. +function getStaticRecalPartNumber(glassPartsArray) { + const recalPart = glassPartsArray.childParts.find((item) => item.partNumber === "RECAL STATIC"); + if (recalPart) { + return recalPart.partNumber; + } else { + return null; + } +} From 38c16b434b5365e6a5d21718c511387be5c8b95c Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Fri, 17 Jan 2025 08:29:25 -0500 Subject: [PATCH 04/22] CASH-69: Simplify logic --- .../service-location/service-location.vue | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 21a123e6e..71bfa4b01 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -318,18 +318,11 @@ export default { } }, isMobileStaticRecalibrationApplicable() { - if (!this.isInsurance) { - return ( - this.isVehicleMobileStaticRecalibrationApplicable && - this.mobileFeePart?.partNumber == MOBILE_STATIC_RECAL_FEE_PART_NUMBER - ); - } else { - return ( - this.isVehicleMobileStaticRecalibrationApplicable && - this.mobileFeePart?.partNumber == MOBILE_STATIC_RECAL_FEE_PART_NUMBER && - this.mobileFeePart?.isInsurable - ); - } + return ( + this.isVehicleMobileStaticRecalibrationApplicable && + this.mobileFeePart?.partNumber == MOBILE_STATIC_RECAL_FEE_PART_NUMBER && + (this.isInsurance ? this.mobileFeePart?.isInsurable : true) + ); }, mobileFeeApplies() { if ( From e6df30696b9ec9b43dca4fb838b07cc8d9f6d2ba Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 28 Jan 2025 09:59:00 -0500 Subject: [PATCH 05/22] CASH-48: front end work to call new log-part-questions endpoint --- src/constants/endpoints.js | 4 +++ src/constants/store-actions.js | 11 ++++--- src/layouts/confirmation/confirmation.vue | 37 +++++++++++++++++++++++ src/store/index.js | 34 +++++++++++++++++++++ 4 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index c972d8118..43bf8c926 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -168,6 +168,10 @@ const endpoints = { url: "/analytics/api/v1/analytics/initialize", method: "POST", }, + LogPartQuestions: { + url: "/analytics/api/v1/analytics/log-part-questions", + method: "POST", + }, GetExperimentsByUser: { url: "/analytics/api/v1/analytics/get-experiments", method: "GET", diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 45a18bace..aee8d705f 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -42,10 +42,6 @@ const storeActions = { VALIDATE_ZIP: "validateZip", PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA: "priceOrderItemsAndSaveServerData", TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA: "taxOrderItemsAndSaveServerData", - LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure", - LOG_PAGE_VIEW: "logPageView", - LOG_CUSTOM_EVENT: "logCustomEvent", - INITIALIZE_SESSION: "initializeSession", GET_EXPERIMENTS_BY_USER: "GetExperimentsByUser", RUN_EXPERIMENTS_FOR_TRIGGER: "runExperimentsForTrigger", CLEAR_VIN: "clearVin", @@ -57,6 +53,13 @@ const storeActions = { GET_BILL_TO_ACCOUNT_NUMBER: "getBillToAccountNumber", GET_RECAL_PARTS_AND_SAVE_TO_LINE_ITEMS: "getRecalPartsAndSaveToLineItems", + // Analytics + LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure", + LOG_PAGE_VIEW: "logPageView", + LOG_CUSTOM_EVENT: "logCustomEvent", + INITIALIZE_SESSION: "initializeSession", + LOG_PART_QUESTIONS: "logPartQuestions", + // DEPENDENCY MUTATIONS RESET_VEHICLE_STATE_AND_DEPENDENCIES: "resetVehicleStateAndDependencies", RESET_DAMAGE_STATE_AND_DEPENDENCIES: "resetDamageAndDependencies", diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 90886a9b7..26c0fd4a5 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -114,6 +114,43 @@ export default { async beforeRouteEnter(to, from, next) { const hasRecalPriceRemoveExperiment = await store.getters.shouldHideRecalibration; + // send part question data to SPS API for logging + const orderFromStore = await deepClone(store.getters.order); + const applicationUserFromStore = await deepClone(store.getters.applicationUser); + const ctu = orderFromStore.workOrderNumber?.split("-")[0]; + const partsOrQuestions = applicationUserFromStore.pageData["part-questions"].partsOrQuestions; + const onlyPartsWithQuestions = partsOrQuestions.filter((part) => { + return part.partQuestions?.length > 0; + }); + + onlyPartsWithQuestions.forEach(part => { + const payloadPartQuestions = []; + part.partQuestions.forEach(question => { + payloadPartQuestions.push({ + questionSeq: question.questionSequence, + questionText: question.questionText, + answerText: question.answerSelected.split("|")[3], + basePart: question.answerSelected.split("|")[2], + }); + }); + const payload = { + eon: orderFromStore.eon, + ctu: ctu, + workOrderId: orderFromStore.workOrderId, + workOrderNumber: orderFromStore.workOrderNumber, + carId: orderFromStore.vehicle.carId, + glassLocation: part.glassLocation, + partQuestions: payloadPartQuestions, + }; + + baseMixin.methods.dispatchStoreAction( + storeActions.LOG_PART_QUESTIONS, + payload, + false + ); + }); + + // Create order await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER); // This nulls the Store order // Call APIs diff --git a/src/store/index.js b/src/store/index.js index f423fb58d..ede3955cc 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1437,6 +1437,40 @@ export const actions = { }); }, + logPartQuestions( + context, + { + eon, + ctu, + workOrderId, + workOrderNumber, + carId, + glassLocation, + partQuestions, + userAgent, + } + ) { + + var payload = { + applicationName: applicationConfig.ANALYTICS_APPLICATION_NAME, + eon: eon, + ctu: ctu, + workOrderId: workOrderId, + workOrderNumber: workOrderNumber, + carId: carId, + glassLocation: glassLocation, + partQuestions: partQuestions, + userAgent: navigator.userAgent + }; + + return globalMethods + .callHttpClient({ + method: endpoints.LogPartQuestions.method, + endpoint: endpoints.LogPartQuestions.url, + payload: payload, + }); + }, + // Misc Actions setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId, eon }) { context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber); From e6df11f3f6472edd7761103b2440dfb55dd29a08 Mon Sep 17 00:00:00 2001 From: Johnny shultz Date: Tue, 28 Jan 2025 14:31:24 -0500 Subject: [PATCH 06/22] Cash-93 CASH-93 added log-enabled header --- src/constants/header-keys.js | 1 + src/global-methods.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/constants/header-keys.js b/src/constants/header-keys.js index 2f7598244..d9b3578c4 100644 --- a/src/constants/header-keys.js +++ b/src/constants/header-keys.js @@ -5,4 +5,5 @@ export const headerKeys = { SESSION_SEQUENCE_NUMBER: "X-Session-Sequence-Number", TRANSACTION_ID: "X-Transaction-Id", EON: "X-Enterprise-Order-Number", + LOG_ENABLED: "log-enabled" }; diff --git a/src/global-methods.js b/src/global-methods.js index 77255e99d..ce82a4c3f 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -70,6 +70,7 @@ export default { [headerKeys.REFERRAL_SEQUENCE_NUMBER]: order?.referralSequenceNumber, [headerKeys.TRANSACTION_ID]: crypto.randomUUID(), [headerKeys.EON]: order?.eon, + [headerKeys.LOG_ENABLED]: store.getters.applicationUser.loggingOption, }; axios({ From 134c78204c26fe96d5b1010e56ebff67539df412 Mon Sep 17 00:00:00 2001 From: Johnny shultz Date: Tue, 28 Jan 2025 14:44:36 -0500 Subject: [PATCH 07/22] CASH-93 CASH-93 added null check to header --- src/global-methods.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global-methods.js b/src/global-methods.js index ce82a4c3f..164900c33 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -70,7 +70,7 @@ export default { [headerKeys.REFERRAL_SEQUENCE_NUMBER]: order?.referralSequenceNumber, [headerKeys.TRANSACTION_ID]: crypto.randomUUID(), [headerKeys.EON]: order?.eon, - [headerKeys.LOG_ENABLED]: store.getters.applicationUser.loggingOption, + [headerKeys.LOG_ENABLED]: store.getters.applicationUser.loggingOption ?? false, }; axios({ From c9b9476976cf691265a4d075706672f38eb85a52 Mon Sep 17 00:00:00 2001 From: Johnny shultz Date: Tue, 28 Jan 2025 15:04:12 -0500 Subject: [PATCH 08/22] Cash-93 CASH- 93 include undefined in check --- src/global-methods.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global-methods.js b/src/global-methods.js index 164900c33..ba6cec1ec 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -70,7 +70,7 @@ export default { [headerKeys.REFERRAL_SEQUENCE_NUMBER]: order?.referralSequenceNumber, [headerKeys.TRANSACTION_ID]: crypto.randomUUID(), [headerKeys.EON]: order?.eon, - [headerKeys.LOG_ENABLED]: store.getters.applicationUser.loggingOption ?? false, + [headerKeys.LOG_ENABLED]: store.getters.applicationUser?.loggingOption ?? false, }; axios({ From 833d6f248a483a88a4113449a390ce5289a4197c Mon Sep 17 00:00:00 2001 From: Adam Caouette Date: Tue, 28 Jan 2025 19:14:43 -0500 Subject: [PATCH 09/22] CASH-48: update application name value --- src/store/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index c45fe7eee..fa83032d5 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1458,9 +1458,8 @@ export const actions = { userAgent, } ) { - var payload = { - applicationName: applicationConfig.ANALYTICS_APPLICATION_NAME, + applicationName: applicationConfig.APPLICATION_NAME, eon: eon, ctu: ctu, workOrderId: workOrderId, From 042e8962352a96f3623a831b55caf34b7d645c48 Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Wed, 29 Jan 2025 11:14:31 -0500 Subject: [PATCH 10/22] CASH-69: Add MSR experiment. Filter recal part by partType instead of part number --- src/constants/experiments.js | 2 ++ src/constants/part-number-strings.js | 7 +++++++ .../service-location/service-location.spec.js | 4 ++++ src/layouts/service-location/service-location.vue | 14 ++++++++++++-- src/store/index.js | 14 ++++++++------ 5 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 src/constants/part-number-strings.js diff --git a/src/constants/experiments.js b/src/constants/experiments.js index 83555fc04..92d27a4a1 100644 --- a/src/constants/experiments.js +++ b/src/constants/experiments.js @@ -1,6 +1,7 @@ const experimentUniverses = { CONCEPT_FUNNEL: "ConceptFunnel", RECAL_PRICE_REMOVAL: "NextGen_RecalPriceRemoval", + MSR: "MSR", }; const experimentSettings = { @@ -16,6 +17,7 @@ const experimentSettings = { RECAL_PRICE_REMOVE: "RecalPriceRemove", INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL: "NextGen_InternalInsuranceTabDisplayThreshold", INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL: "NextGen_ExternalInsuranceTabDisplayThreshold", + DISPLAY_MSR: "DisplayMSR", }; const experimentTriggers = { diff --git a/src/constants/part-number-strings.js b/src/constants/part-number-strings.js new file mode 100644 index 000000000..c32864a87 --- /dev/null +++ b/src/constants/part-number-strings.js @@ -0,0 +1,7 @@ +const partNumberStrings = { + // Recalibration + MOBILE_STATIC_RECAL_FEE: "RECAL MOBILE", + MOBILE_DUAL_RECAL_FEE: "RECAL MOBILEDUAL", +}; + +export { partNumberStrings }; diff --git a/src/layouts/service-location/service-location.spec.js b/src/layouts/service-location/service-location.spec.js index 6333082ec..54f28a89c 100644 --- a/src/layouts/service-location/service-location.spec.js +++ b/src/layouts/service-location/service-location.spec.js @@ -7,6 +7,7 @@ import { getMountOptions } from "@/helpers/unit-test-helper"; import store from "@/store"; import baseMixin from "@/mixins/base-mixin"; +import { experimentSettings } from "@/constants/experiments"; // Define Mocks jest.mock("@/helpers/cms-content-helper", () => ({ @@ -199,6 +200,9 @@ beforeEach(() => { zipCode: "43054", }, }, + experimentSettings: { + settingName: experimentSettings.DISPLAY_MSR, + }, }; }); diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 71bfa4b01..9addea705 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -139,6 +139,8 @@ import contentGroupModal from "@/fmg-components/content-group-modal/content-grou // Supporting files import baseMixin from "@/mixins/base-mixin.js"; +import experimentMixin from "@/mixins/experiment-mixin.js"; +import { experimentSettings } from "@/constants/experiments"; import { AppointmentTypeStrings } from "@/constants/schedule-constants"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; @@ -151,6 +153,7 @@ import { import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; import { applicationConfig } from "@/constants/application-config"; import { Provider } from "@/layouts/service-location/classes/provider"; +import { partNumberStrings } from "@/constants/part-number-strings"; import store from "@/store"; @@ -159,7 +162,6 @@ import { defineRule } from "vee-validate"; import { errorMessages } from "@/constants/error-messages"; const MOBILE_FEE_PART_TYPE = "MOBILE FEE"; -const MOBILE_STATIC_RECAL_FEE_PART_NUMBER = "RECAL MOBILE"; // DEFINE VALIDATION RULES defineRule("mobile-location-required", (value) => { @@ -319,11 +321,19 @@ export default { }, isMobileStaticRecalibrationApplicable() { return ( + this.displayMSR && this.isVehicleMobileStaticRecalibrationApplicable && - this.mobileFeePart?.partNumber == MOBILE_STATIC_RECAL_FEE_PART_NUMBER && + this.mobileFeePart?.partNumber == partNumberStrings.MOBILE_STATIC_RECAL_FEE && (this.isInsurance ? this.mobileFeePart?.isInsurable : true) ); }, + displayMSR() { + return ( + experimentMixin.methods + .getSettingValue(experimentSettings.DISPLAY_MSR) + ?.toLowerCase() === "true" + ); + }, mobileFeeApplies() { if ( this.mobileFeePart?.laborAmount > 0 || diff --git a/src/store/index.js b/src/store/index.js index fa83032d5..48c6078c7 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1671,10 +1671,10 @@ export const actions = { var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItacOptimized=${isItacOptimized}&zipCode=${zipCode}`; if (isMobileStaticRecalibrationApplicable) { - const staticRecalPartNumber = getStaticRecalPartNumber(order.lineItems?.glassParts[0]); + const recalPartNumber = getRecalPartNumber(order.lineItems?.glassParts[0]); const carId = order.vehicle?.carId; - if (staticRecalPartNumber && carId) { - endPoint = `${endPoint}&partNumbers=${staticRecalPartNumber}&carId=${carId}`; + if (recalPartNumber && carId) { + endPoint = `${endPoint}&partNumbers=${recalPartNumber}&carId=${carId}`; } } @@ -3718,9 +3718,11 @@ function saveExternalParameterState(externalParameterState) { window.sessionStorage.setItem("externalParameterState", JSON.stringify(externalParameterState)); } -//This function checks if static recalibration is available for the vehicle and returns the part number for it. -function getStaticRecalPartNumber(glassPartsArray) { - const recalPart = glassPartsArray.childParts.find((item) => item.partNumber === "RECAL STATIC"); +//This function finds the recalibration part and returns the part number for it. +function getRecalPartNumber(glassPartsArray) { + const recalPart = glassPartsArray.childParts.find( + (item) => item.partType === partTypeStrings.ADAS_RECALIBRATION + ); if (recalPart) { return recalPart.partNumber; } else { From 829567d4018072e25fbbe0bdc85e2b4d15020869 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Sun, 2 Feb 2025 11:11:49 -0500 Subject: [PATCH 11/22] CASH-48 CASH-48 switch to order object from applicationUser --- src/constants/endpoints.js | 2 +- src/layouts/confirmation/confirmation.vue | 52 +++++++++++------------ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 43bf8c926..29d36d091 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -125,7 +125,7 @@ const endpoints = { method: "POST", }, SaveQuote: { - url: "/order/api/v1/order/initiate-saved-progress-email", + url: "/order/api/v1/order/save-progress", method: "POST", }, GetSignature: { diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index 26c0fd4a5..f699d6a59 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -116,40 +116,40 @@ export default { // send part question data to SPS API for logging const orderFromStore = await deepClone(store.getters.order); - const applicationUserFromStore = await deepClone(store.getters.applicationUser); - const ctu = orderFromStore.workOrderNumber?.split("-")[0]; - const partsOrQuestions = applicationUserFromStore.pageData["part-questions"].partsOrQuestions; - const onlyPartsWithQuestions = partsOrQuestions.filter((part) => { - return part.partQuestions?.length > 0; - }); + const ctu = orderFromStore.serviceLocation?.zipCodeCtu - onlyPartsWithQuestions.forEach(part => { + const partsOrQuestions = orderFromStore.damage?.partQuestionAnswers; + + partsOrQuestions.forEach(pqa => { const payloadPartQuestions = []; - part.partQuestions.forEach(question => { + pqa.answeredQuestions.forEach(answer => { payloadPartQuestions.push({ - questionSeq: question.questionSequence, - questionText: question.questionText, - answerText: question.answerSelected.split("|")[3], - basePart: question.answerSelected.split("|")[2], + questionSeq: answer?.questionNum, + questionText: answer?.questionText, + answerText: answer?.selectedAnswerText, + basePart: pqa?.result, }); }); - const payload = { - eon: orderFromStore.eon, - ctu: ctu, - workOrderId: orderFromStore.workOrderId, - workOrderNumber: orderFromStore.workOrderNumber, - carId: orderFromStore.vehicle.carId, - glassLocation: part.glassLocation, - partQuestions: payloadPartQuestions, - }; - baseMixin.methods.dispatchStoreAction( - storeActions.LOG_PART_QUESTIONS, - payload, - false - ); + const payload = { + eon: orderFromStore.eon, + ctu: ctu, + workOrderId: orderFromStore.workOrderId, + workOrderNumber: orderFromStore.workOrderNumber, + carId: orderFromStore.vehicle.carId, + glassLocation: pqa?.glassLocation, + partQuestions: payloadPartQuestions, + }; + + baseMixin.methods.dispatchStoreAction( + storeActions.LOG_PART_QUESTIONS, + payload, + false + ); + }); + // Create order await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER); // This nulls the Store order From 969ea18d2a53e03c24b474146c42f3bdc302f879 Mon Sep 17 00:00:00 2001 From: Johnny shultz Date: Mon, 3 Feb 2025 13:55:06 -0500 Subject: [PATCH 12/22] CASH-97 CASH-97 got phone number from leadGen and populated customer-details phone number field --- src/constants/header-keys.js | 2 +- src/constants/query-strings.js | 1 + src/constants/store-mutations.js | 2 + .../save-progress-modal-question.vue | 2 +- .../save-progress-popup-question.vue | 4 +- src/layouts/confirmation/confirmation.vue | 30 ++++++--------- src/layouts/vehicle/vehicle.vue | 6 ++- src/router/index.js | 7 ++++ src/store/index.js | 38 ++++++++++--------- 9 files changed, 52 insertions(+), 40 deletions(-) diff --git a/src/constants/header-keys.js b/src/constants/header-keys.js index d9b3578c4..ed88393b5 100644 --- a/src/constants/header-keys.js +++ b/src/constants/header-keys.js @@ -5,5 +5,5 @@ export const headerKeys = { SESSION_SEQUENCE_NUMBER: "X-Session-Sequence-Number", TRANSACTION_ID: "X-Transaction-Id", EON: "X-Enterprise-Order-Number", - LOG_ENABLED: "log-enabled" + LOG_ENABLED: "log-enabled", }; diff --git a/src/constants/query-strings.js b/src/constants/query-strings.js index 210ac28f0..f5881f005 100644 --- a/src/constants/query-strings.js +++ b/src/constants/query-strings.js @@ -46,6 +46,7 @@ const queryStrings = { ORGANIC_SOCIAL: "organic_social", EXPERIMENTS: "experiments", FROM_HERITAGE: "fromheritage", + PHONE_NUMBER: "phonenumber", }; export { queryStrings }; diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index f625e27cf..2f231bb59 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -107,6 +107,7 @@ const storeMutations = { UPDATE_EXTERNAL_PARAMETER_VIN_SELECTION: "updateExternalParameterVinSelection", UPDATE_EXTERNAL_PARAMETER_SERVICE_PACKAGE: "updateExternalParameterServicePackage", UPDATE_EXTERNAL_PARAMETER_SOURCE: "updateExternalParameterSource", + UPDATE_EXTERNAL_PARAMETER_PHONE_NUMBER: "updateExternalParameterPhoneNumber", //RESET EXTERNAL_PARAMETER MUTATIONS RESET_EXTERNAL_PARAMETER_VEHICLE_STATE: "resetExternalParameterVehicleState", @@ -115,6 +116,7 @@ const storeMutations = { RESET_EXTERNAL_PARAMETER_SERVICEZIP_STATE: "resetExternalParameterServiceZipState", RESET_EXTERNAL_PARAMETER_QUOTE_STATE: "resetExternalParameterQuoteState", RESET_EXTERNAL_PARAMETER_SOURCE_STATE: "resetExternalParameterSourceState", + RESET_EXTERNAL_PARAMETER_CUSTOMER_STATE: "resetExternalParameterCustomerState", RESET_IS_EXTERNAL_PARAMETER: "resetIsExternalParameter", //Affiliate Cookies 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 5b885f27f..873e58709 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 @@ -205,7 +205,7 @@ export default { } } } - + .alert { border-radius: $border-radius-lg; border: 1px solid $green; diff --git a/src/fmg-components/save-progress-popup-question/save-progress-popup-question.vue b/src/fmg-components/save-progress-popup-question/save-progress-popup-question.vue index 5d98d5c4b..34ef44e71 100644 --- a/src/fmg-components/save-progress-popup-question/save-progress-popup-question.vue +++ b/src/fmg-components/save-progress-popup-question/save-progress-popup-question.vue @@ -219,7 +219,7 @@ export default { .textbox-question { padding: 0; margin: 0 0 1.5rem 0; - + label { text-align: left; font-weight: 900; @@ -258,7 +258,7 @@ export default { &.progress-saved { .modal-footer-button, - .modal-disclaimer { + .modal-disclaimer { display: none; } .skip-button { diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index f699d6a59..f05bece86 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -116,13 +116,13 @@ export default { // send part question data to SPS API for logging const orderFromStore = await deepClone(store.getters.order); - const ctu = orderFromStore.serviceLocation?.zipCodeCtu + const ctu = orderFromStore.serviceLocation?.zipCodeCtu; const partsOrQuestions = orderFromStore.damage?.partQuestionAnswers; - partsOrQuestions.forEach(pqa => { + partsOrQuestions.forEach((pqa) => { const payloadPartQuestions = []; - pqa.answeredQuestions.forEach(answer => { + pqa.answeredQuestions.forEach((answer) => { payloadPartQuestions.push({ questionSeq: answer?.questionNum, questionText: answer?.questionText, @@ -132,24 +132,18 @@ export default { }); const payload = { - eon: orderFromStore.eon, - ctu: ctu, - workOrderId: orderFromStore.workOrderId, - workOrderNumber: orderFromStore.workOrderNumber, - carId: orderFromStore.vehicle.carId, - glassLocation: pqa?.glassLocation, - partQuestions: payloadPartQuestions, - }; - - baseMixin.methods.dispatchStoreAction( - storeActions.LOG_PART_QUESTIONS, - payload, - false - ); + eon: orderFromStore.eon, + ctu: ctu, + workOrderId: orderFromStore.workOrderId, + workOrderNumber: orderFromStore.workOrderNumber, + carId: orderFromStore.vehicle.carId, + glassLocation: pqa?.glassLocation, + partQuestions: payloadPartQuestions, + }; + baseMixin.methods.dispatchStoreAction(storeActions.LOG_PART_QUESTIONS, payload, false); }); - // Create order await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER); // This nulls the Store order diff --git a/src/layouts/vehicle/vehicle.vue b/src/layouts/vehicle/vehicle.vue index c81dfa2b0..fa7f5c036 100644 --- a/src/layouts/vehicle/vehicle.vue +++ b/src/layouts/vehicle/vehicle.vue @@ -80,7 +80,11 @@ import vehicleQuestion from "@/layouts/vehicle/vehicle-question/vehicle-question // Supporting files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { experimentUniverses } from "@/constants/experiments"; -import { getSessionKeyValue, getUserIdValue, getDeviceIdValue } from "@/helpers/heritage-integration/cookie-helper"; +import { + getSessionKeyValue, + getUserIdValue, + getDeviceIdValue, +} from "@/helpers/heritage-integration/cookie-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; import { Form, defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; diff --git a/src/router/index.js b/src/router/index.js index 76d1203b7..2230a652d 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -837,6 +837,7 @@ function updateExternalParameterState() { const externalParameterServicePackage = getQuerystringParameter(queryStrings.SERVICE_PACKAGE); const externalParameterNumberOfChips = getQuerystringParameter(queryStrings.NUMBER_OF_CHIPS); const externalParameterSource = getQuerystringParameter(queryStrings.EXPERIMENTS); + const externalParameterPhoneNumber = getQuerystringParameter(queryStrings.PHONE_NUMBER); if ( externalParameterYear && externalParameterMake && @@ -892,6 +893,12 @@ function updateExternalParameterState() { if (externalParameterSource) { store.commit(storeMutations.UPDATE_EXTERNAL_PARAMETER_SOURCE, externalParameterSource); } + if (externalParameterPhoneNumber) { + store.commit( + storeMutations.UPDATE_EXTERNAL_PARAMETER_PHONE_NUMBER, + externalParameterPhoneNumber + ); + } } // if there is an existing external parameter state then they have already been through from an external source(LeadGen) and diff --git a/src/store/index.js b/src/store/index.js index 77a1f1e95..c41d51d05 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -495,6 +495,11 @@ export const mutations = { externalParameterState.quote.servicePackage = servicePackage; saveExternalParameterState(externalParameterState); }, + updateExternalParameterPhoneNumber(state, phoneNumber) { + externalParameterState.customer.phoneNumber = phoneNumber; + state.order.customer.phoneNumber = externalParameterState.customer.phoneNumber; + saveExternalParameterState(externalParameterState); + }, //RESET ExternalParameter MUTATIONS resetExternalParameterVehicleState(state) { externalParameterState.vehicle.year = null; @@ -528,6 +533,10 @@ export const mutations = { externalParameterState.isExternalParameter = externalParameterStatus.INACTIVE; saveExternalParameterState(externalParameterState); }, + resetExternalParameterCustomerState(state) { + externalParameterState.customer.phoneNumber = null; + saveExternalParameterState(externalParameterState); + }, // RESET DEPENDENCY MUTATIONS resetVehicleState(state) { @@ -984,6 +993,7 @@ export const getters = { externalParameterQuote: (state) => externalParameterState?.quote, externalParameterServiceZip: (state) => externalParameterState?.serviceZip, externalParameterEstimate: (state) => externalParameterState?.estimate, + externalParameterCustomer: (state) => externalParameterState?.customer, isExternalParameter: (state) => externalParameterState?.isExternalParameter, }; @@ -1448,16 +1458,7 @@ export const actions = { logPartQuestions( context, - { - eon, - ctu, - workOrderId, - workOrderNumber, - carId, - glassLocation, - partQuestions, - userAgent, - } + { eon, ctu, workOrderId, workOrderNumber, carId, glassLocation, partQuestions, userAgent } ) { var payload = { applicationName: applicationConfig.APPLICATION_NAME, @@ -1468,15 +1469,14 @@ export const actions = { carId: carId, glassLocation: glassLocation, partQuestions: partQuestions, - userAgent: navigator.userAgent + userAgent: navigator.userAgent, }; - return globalMethods - .callHttpClient({ - method: endpoints.LogPartQuestions.method, - endpoint: endpoints.LogPartQuestions.url, - payload: payload, - }); + return globalMethods.callHttpClient({ + method: endpoints.LogPartQuestions.method, + endpoint: endpoints.LogPartQuestions.url, + payload: payload, + }); }, // Misc Actions @@ -3132,6 +3132,7 @@ export const actions = { context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_ESTIMATE_STATE); context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_SERVICEZIP_STATE); context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_QUOTE_STATE); + context.commit(storeMutations.RESET_EXTERNAL_PARAMETER_CUSTOMER_STATE); context.commit(storeMutations.RESET_IS_EXTERNAL_PARAMETER); } }, @@ -3704,6 +3705,9 @@ function createExternalParameterDefaultState() { isInsurance: null, servicePackage: null, }, + customer: { + phoneNumber: null, + }, }; // set to session storage saveExternalParameterState(externalParameterDefaultState); From 8a0d622049c323c0105ea6be543a77022bd2ee67 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Mon, 3 Feb 2025 15:07:38 -0500 Subject: [PATCH 13/22] CASH-48 CASH-48 null check --- src/layouts/confirmation/confirmation.vue | 54 +++++++++++------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/layouts/confirmation/confirmation.vue b/src/layouts/confirmation/confirmation.vue index f699d6a59..d495d8217 100644 --- a/src/layouts/confirmation/confirmation.vue +++ b/src/layouts/confirmation/confirmation.vue @@ -120,35 +120,35 @@ export default { const partsOrQuestions = orderFromStore.damage?.partQuestionAnswers; - partsOrQuestions.forEach(pqa => { - const payloadPartQuestions = []; - pqa.answeredQuestions.forEach(answer => { - payloadPartQuestions.push({ - questionSeq: answer?.questionNum, - questionText: answer?.questionText, - answerText: answer?.selectedAnswerText, - basePart: pqa?.result, + if (partsOrQuestions) { + partsOrQuestions.forEach(pqa => { + const payloadPartQuestions = []; + pqa.answeredQuestions.forEach(answer => { + payloadPartQuestions.push({ + questionSeq: answer?.questionNum, + questionText: answer?.questionText, + answerText: answer?.selectedAnswerText, + basePart: pqa?.result, + }); }); + + const payload = { + eon: orderFromStore.eon, + ctu: ctu, + workOrderId: orderFromStore.workOrderId, + workOrderNumber: orderFromStore.workOrderNumber, + carId: orderFromStore.vehicle.carId, + glassLocation: pqa?.glassLocation, + partQuestions: payloadPartQuestions, + }; + + baseMixin.methods.dispatchStoreAction( + storeActions.LOG_PART_QUESTIONS, + payload, + false + ); }); - - const payload = { - eon: orderFromStore.eon, - ctu: ctu, - workOrderId: orderFromStore.workOrderId, - workOrderNumber: orderFromStore.workOrderNumber, - carId: orderFromStore.vehicle.carId, - glassLocation: pqa?.glassLocation, - partQuestions: payloadPartQuestions, - }; - - baseMixin.methods.dispatchStoreAction( - storeActions.LOG_PART_QUESTIONS, - payload, - false - ); - - }); - + } // Create order await baseMixin.methods.dispatchStoreAction(storeActions.CREATE_SUBMITTED_ORDER); // This nulls the Store order From 5c8999899c84b7832ad6eb0bf59766dfa8971fec Mon Sep 17 00:00:00 2001 From: Johnny shultz Date: Mon, 3 Feb 2025 17:06:51 -0500 Subject: [PATCH 14/22] CASH-97 CASH-97 update to externalParameterPhoneNumber mutation --- src/store/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/store/index.js b/src/store/index.js index c41d51d05..c93ddf90a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -497,7 +497,6 @@ export const mutations = { }, updateExternalParameterPhoneNumber(state, phoneNumber) { externalParameterState.customer.phoneNumber = phoneNumber; - state.order.customer.phoneNumber = externalParameterState.customer.phoneNumber; saveExternalParameterState(externalParameterState); }, //RESET ExternalParameter MUTATIONS From 19f775c46332cf18937861f8c2d23d633d87b5a4 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 4 Feb 2025 06:40:19 -0500 Subject: [PATCH 15/22] CASH-97 CASH-97 use a store action/mutation to persist phone number in vuex. --- src/constants/store-actions.js | 1 + src/constants/store-mutations.js | 1 + src/router/index.js | 4 ++++ src/store/index.js | 7 +++++++ 4 files changed, 13 insertions(+) diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index aee8d705f..ec6b0db0c 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -76,6 +76,7 @@ const storeActions = { SAVE_SERVICE_LOCATION: "saveServiceLocation", SAVE_SCHEDULE: "saveSchedule", SAVE_EMAIL: "saveEmail", + SAVE_PHONE_NUMBER: "savePhoneNumber", 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 2f231bb59..1ebf39b8d 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -41,6 +41,7 @@ const storeMutations = { // CUSTOMER MUTATIONS UPDATE_CUSTOMER_EMAIL_ADDRESS: "updateCustomerEmailAddress", + UPDATE_CUSTOMER_PHONE_NUMBER: "updateCustomerPhoneNumber", UPDATE_CUSTOMER_DETAILS: "updateCustomerDetails", // ORDER MUTATIONS diff --git a/src/router/index.js b/src/router/index.js index 2230a652d..9595cf11c 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -898,6 +898,10 @@ function updateExternalParameterState() { storeMutations.UPDATE_EXTERNAL_PARAMETER_PHONE_NUMBER, externalParameterPhoneNumber ); + store.commit( + storeMutations.UPDATE_CUSTOMER_PHONE_NUMBER, + externalParameterPhoneNumber + ); } } diff --git a/src/store/index.js b/src/store/index.js index c93ddf90a..c591d493d 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -343,6 +343,9 @@ export const mutations = { updateCustomerEmailAddress(state, customerEmailAddress) { state.order.customer.emailAddress = customerEmailAddress; }, + updateCustomerPhoneNumber(state, phoneNumber) { + state.order.customer.phoneNumber = phoneNumber; + }, updateVehicle(state, vehicleInfo) { state.order.vehicle.year = vehicleInfo.year; state.order.vehicle.make = vehicleInfo.make; @@ -3038,6 +3041,10 @@ export const actions = { context.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, email === "" ? null : email); }, + savePhoneNumber(context, phoneNumber) { + context.commit(storeMutations.UPDATE_CUSTOMER_PHONE_NUMBER, phoneNumber === "" ? null : phoneNumber); + }, + saveVin(context, { isSelectedGlassAvailableForVehicle, vehicleInfo }) { //Reset dependent state when changing if (vehicleInfo.vin !== context.state.order.vehicle.vin) { From c2b7ed99dc8853ad5cf58ebc3d15669f7731767f Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 4 Feb 2025 07:05:43 -0500 Subject: [PATCH 16/22] CASH-97 code coverage CASH-97 code coverage --- jest.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/jest.config.js b/jest.config.js index ce4aa3ad6..04f474e53 100644 --- a/jest.config.js +++ b/jest.config.js @@ -12,6 +12,7 @@ module.exports = { "!src/constants/*.js", "!src/router/**/*.js", "!src/helpers/unit-test-helper.js", + "!src/helpers/logger.js", "!src/layouts/vehicle-damage/windshield-options/windshield-options.vue", "!src/layouts/reveal/**/*.vue", "!src/layouts/payment-method/**/*.vue", From 233a5fa4f091e47ed42674412f9dff5988fbe137 Mon Sep 17 00:00:00 2001 From: CarlNation Date: Tue, 4 Feb 2025 09:10:39 -0500 Subject: [PATCH 17/22] CASH-97 CASH-97 use store action --- src/router/index.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index 9595cf11c..83004b38c 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -898,10 +898,7 @@ function updateExternalParameterState() { storeMutations.UPDATE_EXTERNAL_PARAMETER_PHONE_NUMBER, externalParameterPhoneNumber ); - store.commit( - storeMutations.UPDATE_CUSTOMER_PHONE_NUMBER, - externalParameterPhoneNumber - ); + store.dispatch(storeActions.SAVE_PHONE_NUMBER, externalParameterPhoneNumber); } } From d92cb225c2a3dce2b1520cb01e3f60cecfac850a Mon Sep 17 00:00:00 2001 From: hiteshkumar87 Date: Wed, 5 Feb 2025 16:45:50 +0530 Subject: [PATCH 18/22] 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 19/22] 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 20/22] 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 21/22] 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 22/22] 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,