import { createStore, Store } from "vuex"; import { endpoints } from "@/constants/endpoints.js"; import { storeMutations } from "@/constants/store-mutations"; import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper"; import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; import { storeActions } from "@/constants/store-actions"; import { applicationConfig } from "@/constants/application-config"; import { experimentTriggers } from "@/constants/experiments"; import { damageLocationsSelected } from "@/constants/damage-locations-selected"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import router from "@/router"; import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper.js"; // Export State const getDefaultState = () => { return { order: { vehicle: { year: null, make: null, model: null, style: null, carId: null, category: null, vin: null, imageUrl: null, imageVifNumber: null, imageColor: null, registration: { licensePlate: null, address: null, city: null, state: null, zipCode: null, firstName: null, lastName: null, }, }, serviceLocation: { address: null, city: null, state: null, zipCode: null, zipCodeCtu: null, }, customer: { emailAddress: null, }, damage: { isRepair: null, numberOfChips: null, glassToReplace: null, partQuestionAnswers: null, moldingQuestionAnswers: null, capabilityQuestionAnswers: null, }, lineItems: { glassParts: null, supportingItems: null, vaps: null, serverData: null, }, payment: { isInsurance: null, insuranceCoverage: { isVerified: null, coverageStatus: null, }, parentAccountNumber: 0, }, referralNumber: null, referralDate: null, referralCorrelationId: null, eon: null, }, applicationUser: { eventBus: [], pageData: {}, savedSessionTimeout: getDateForSavedSessionTimeout(), saveSessionPromise: null, savedSessionId: null, crmCustomerId: null, lastPageVisited: null, experiments: [], triggeredSiteEntry: false, }, }; }; export const state = getDefaultState(); // Export Mutations export const mutations = { // VEHICLE MUTATIONS updateYear(state, year) { state.order.vehicle.year = year; }, updateMake(state, make) { state.order.vehicle.make = make; }, updateModel(state, model) { state.order.vehicle.model = model; }, updateStyle(state, style) { state.order.vehicle.style = style; }, updateCarId(state, carId) { state.order.vehicle.carId = carId; }, updateVehicleCategory(state, category) { state.order.vehicle.category = category; }, updateVehicleImageUrl(state, imageUrl) { state.order.vehicle.imageUrl = imageUrl; }, updateVehicleImageVifNumber(state, imageVifNumber) { state.order.vehicle.imageVifNumber = imageVifNumber; }, updateVehicleImageColor(state, imageColor) { state.order.vehicle.imageColor = imageColor; }, updateVehicleVin(state, vin) { state.order.vehicle.vin = vin; }, updateIsRepair(state, isRepair) { state.order.damage.isRepair = isRepair; }, updateNumberOfChips(state, numberOfChips) { state.order.damage.numberOfChips = numberOfChips; }, updateGlassToReplace(state, glassToReplace) { state.order.damage.glassToReplace = glassToReplace; }, updatePartQuestionAnswers(state, answersArray) { state.order.damage.partQuestionAnswers = answersArray; }, updateMoldingQuestionAnswers(state, answersArray) { state.order.damage.moldingQuestionAnswers = answersArray; }, updateCapabilityQuestionAnswers(state, answersArray) { state.order.damage.capabilityQuestionAnswers = answersArray; }, updateGlassParts(state, partsData) { state.order.lineItems.glassParts = partsData; }, updateVaps(state, partsData) { state.order.lineItems.vaps = partsData; }, updateSupportingItems(state, partsData) { state.order.lineItems.supportingItems = partsData; }, updateLineItemsServerData(state, serverData) { state.order.lineItems.serverData = serverData; }, updatePageData(state, pageData) { state.applicationUser.pageData[pageData.page] = pageData.data; }, updateReferralCorrelationId(state, referralCorrelationId) { state.order.referralCorrelationId = referralCorrelationId; }, updateReferralNumber(state, referralNumber) { state.order.referralNumber = referralNumber; }, updateReferralDate(state, referralDate) { state.order.referralDate = referralDate; }, updateParentAcctNumber(state, parentAcctNumber) { state.order.payment.parentAccountNumber = parentAcctNumber; }, updateEON(state, eon) { state.order.eon = eon; }, updateIsInsurance(state, isInsurance) { state.order.payment.isInsurance = isInsurance; }, updateInsuranceVerifiedStatus(state, isVerified) { state.order.payment.insuranceCoverage.isVerified = isVerified; }, updateRegistrationLicensePlate(state, licensePlate) { state.order.vehicle.registration.licensePlate = licensePlate; }, updateRegistrationAddress(state, registrationAddress) { state.order.vehicle.registration.address = registrationAddress; }, updateRegistrationCity(state, registrationCity) { state.order.vehicle.registration.city = registrationCity; }, updateRegistrationState(state, registrationState) { state.order.vehicle.registration.state = registrationState; }, updateRegistrationZipCode(state, registrationZipCode) { state.order.vehicle.registration.zipCode = registrationZipCode; }, updateRegistrationFirstName(state, firstName) { state.order.vehicle.registration.firstName = firstName; }, updateRegistrationLastName(state, lastName) { state.order.vehicle.registration.lastName = lastName; }, updateCustomerEmailAddress(state, customerEmailAddress) { state.order.customer.emailAddress = customerEmailAddress; }, updateVehicle(state, vehicleInfo) { state.order.vehicle.year = vehicleInfo.year; state.order.vehicle.make = vehicleInfo.make; state.order.vehicle.model = vehicleInfo.model; state.order.vehicle.style = vehicleInfo.style; state.order.vehicle.carId = vehicleInfo.carId; state.order.vehicle.category = vehicleInfo.category; state.order.vehicle.vin = vehicleInfo.vin; state.order.vehicle.imageUrl = vehicleInfo.imageUrl; state.order.vehicle.imageVifNumber = vehicleInfo.imageVifNumber; state.order.vehicle.imageColor = vehicleInfo.imageVifColor; }, updateRegistration(state, registrationInfo) { state.order.vehicle.registration.licensePlate = registrationInfo?.licensePlate; state.order.vehicle.registration.address = registrationInfo?.address; state.order.vehicle.registration.city = registrationInfo?.city; state.order.vehicle.registration.state = registrationInfo?.state; state.order.vehicle.registration.zipCode = registrationInfo?.zipCode; state.order.vehicle.registration.firstName = registrationInfo?.firstName; state.order.vehicle.registration.lastName = registrationInfo?.lastName; }, updateServiceLocation(state, serviceLocationInfo) { state.order.serviceLocation.address = serviceLocationInfo.address; state.order.serviceLocation.city = serviceLocationInfo.city; state.order.serviceLocation.state = serviceLocationInfo.state; state.order.serviceLocation.zipCode = serviceLocationInfo.zipCode; state.order.serviceLocation.zipCodeCtu = serviceLocationInfo.zipCodeCtu; }, // applicationUser MUTATIONS updateSaveSessionPromise(state, saveSessionPromise) { state.applicationUser.saveSessionPromise = saveSessionPromise; }, updateSavedSessionId(state, savedSessionId) { state.applicationUser.savedSessionId = savedSessionId; }, updateCrmCustomerId(state, crmCustomerId) { state.applicationUser.crmCustomerId = crmCustomerId; }, updateLastPageVisited(state, lastPageVisited) { state.applicationUser.lastPageVisited = lastPageVisited; }, // EVENT BUS MUTATIONS addEventToBus(state, event) { state.applicationUser.eventBus.push(event); }, removeEventFromBus(state, eventData) { const matchedEvent = state.applicationUser.eventBus.find( ({ category, subCategory }) => category === eventData.category && subCategory === eventData.subCategory ); const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent); // If the item exists, remove it. if (itemIndex > -1) { state.applicationUser.eventBus.splice(itemIndex, 1); } }, // RESET DEPENDENCY MUTATIONS resetVehicleState(state) { state.order.vehicle.year = null; state.order.vehicle.make = null; state.order.vehicle.model = null; state.order.vehicle.style = null; state.order.vehicle.carId = null; state.order.vehicle.category = null; state.order.vehicle.vin = null; state.order.vehicle.imageUrl = null; state.order.vehicle.imageVifNumber = null; state.order.vehicle.imageColor = null; }, resetDamageState(state) { state.order.damage.isRepair = null; state.order.damage.numberOfChips = null; state.order.damage.glassToReplace = null; }, resetRegistrationState(state) { state.order.vehicle.registration.licensePlate = null; state.order.vehicle.registration.address = null; state.order.vehicle.registration.city = null; state.order.vehicle.registration.state = null; state.order.vehicle.registration.zipCode = null; state.order.vehicle.registration.firstName = null; state.order.vehicle.registration.lastName = null; }, resetGlassPartsState(state) { state.order.lineItems.glassParts = null; state.order.damage.partQuestionAnswers = null; state.order.damage.moldingQuestionAnswers = null; state.order.damage.capabilityQuestionAnswers = null; state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null; state.applicationUser.pageData[fmgPageValues.VEHICLE_PARTS] = null; state.applicationUser.pageData[fmgPageValues.MOLDING_QUESTIONS] = null; state.applicationUser.pageData[fmgPageValues.CAPABILITY_QUESTIONS] = null; }, resetState(state) { Object.assign(state, getDefaultState()); }, resetSaveSessionPromise(state) { state.applicationUser.saveSessionPromise = null; }, // Misc Mutations updateStateWithOrderInformation(state, sessionInformation) { state.order.referralNumber = sessionInformation.order.referralNumber; state.order.referralDate = sessionInformation.order.referralDate; state.order.referralCorrelationId = sessionInformation.order.referralCorrelationId; state.order.eon = sessionInformation.order.eon; if (state.order.vehicle.vin !== sessionInformation.order.vehicle?.vin) { state.applicationUser.pageData[fmgPageValues.PART_QUESTIONS] = null; state.applicationUser.pageData[fmgPageValues.VEHICLE_PARTS] = null; state.applicationUser.pageData[fmgPageValues.MOLDING_QUESTIONS] = null; state.applicationUser.pageData[fmgPageValues.CAPABILITY_QUESTIONS] = null; } state.order.vehicle = Object.assign(state.order.vehicle, { year: sessionInformation.order.vehicle?.year, make: sessionInformation.order.vehicle?.make, model: sessionInformation.order.vehicle?.model, style: sessionInformation.order.vehicle?.style, vin: sessionInformation.order.vehicle?.vin, carId: sessionInformation.order.vehicle?.carId, category: sessionInformation.order.vehicle?.category, imageUrl: sessionInformation.order.vehicle?.imageUrl, imageVifNumber: sessionInformation.order.vehicle?.imageVifNumber, imageColor: sessionInformation.order.vehicle?.imageVifColor, registration: { firstName: sessionInformation.order.vehicle.registration.firstName, lastName: sessionInformation.order.vehicle.registration.lastName, address: sessionInformation.order.vehicle.registration.streetAddress, city: sessionInformation.order.vehicle.registration.city, state: sessionInformation.order.vehicle.registration.state, zipCode: sessionInformation.order.vehicle.registration.zipCode, licensePlate: sessionInformation.order.vehicle.registration.licensePlateNumber, }, }); state.order.damage.glassToReplace = sessionInformation.order.damage.glassToReplace; state.order.damage.isRepair = sessionInformation.order.damage.isRepair; state.order.damage.numberOfChips = sessionInformation.order.damage.numberOfChips; state.order.damage.partQuestionAnswers = sessionInformation.order.damage.partQuestionAnswers; state.order.damage.moldingQuestionAnswers = sessionInformation.order.damage.moldingQuestionAnswers; state.order.damage.capabilityQuestionAnswers = sessionInformation.order.damage.capabilityQuestionAnswers; state.order.lineItems.glassParts = sessionInformation.order.lineItems.glassParts; state.order.lineItems.supportingItems = sessionInformation.order.lineItems.supportingItems; state.order.lineItems.vaps = sessionInformation.order.lineItems.vaps; state.order.lineItems.serverData = sessionInformation.order.lineItems.serverData; state.order.payment.parentAccountNumber = sessionInformation.order.payment.parentAccountNumber; state.order.providerNumber = sessionInformation.order.providerNumber; (state.order.serviceLocation.address = sessionInformation.order.serviceLocation.streetAddress), (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.payment.isInsurance = sessionInformation.order.payment.isInsurance; state.order.payment.insuranceCoverage.isVerified = sessionInformation?.order.payment.insuranceCoverage.isVerified; state.order.payment.insuranceCoverage.coverageStatus = sessionInformation?.insuranceInfo?.coverageStatus; state.order.customer.emailAddress = sessionInformation.order.customer.emailAddress; state.order.existingPromoCode = sessionInformation.order.existingPromoCode; state.applicationUser.experiments = sessionInformation.applicationUser.experiments; state.applicationUser.crmCustomerId = sessionInformation.applicationUser.crmCustomerId; state.applicationUser.pageData = sessionInformation.applicationUser.pageData; state.applicationUser.lastPage = sessionInformation.applicationUser.lastPage; }, updateExperiments(state, experiments) { state.applicationUser.experiments = experiments; }, updateTriggeredSiteEntry(state, wasSiteEntryTriggered) { state.applicationUser.triggeredSiteEntry = wasSiteEntryTriggered; }, }; // Export Getters export const getters = { vehicle: (state) => state.order.vehicle, eventBusItem: (state) => (eventCategory, eventSubCategory) => { const matchedEvent = state.applicationUser.eventBus.find( ({ category, subCategory }) => category === eventCategory && subCategory === eventSubCategory ); return matchedEvent !== undefined ? matchedEvent.eventValue : undefined; }, eventBus: (state) => state.applicationUser.eventBus, damage: (state) => state.order.damage, hasAnyNonWindshieldGlassParts: (state) => { const nonWindshieldItems = state.order.damage.glassToReplace?.filter( (glassToReplace) => glassToReplace.glassLocation != "Windshield" ); return !!nonWindshieldItems?.length; }, lineItems: (state) => state.order.lineItems, pageData: (state) => (page) => { return state.applicationUser.pageData[page]; }, applicationUser: (state) => state.applicationUser, order: (state) => state.order, payment: (state) => state.order.payment, experimentOrder: (state) => { return { funnelVehicleYear: state.order.vehicle.year, funnelVehicleMake: state.order.vehicle.make, funnelVehicleModel: state.order.vehicle.model, funnelVehicleStyle: state.order.vehicle.style, funnelIsRepair: state.order.damage.isRepair, funnelNumberOfChips: state.order.damage.numberOfChips, funnelCarId: state.order.vehicle.carId, funnelServiceCity: state.order.serviceLocation.city, funnelServiceState: state.order.serviceLocation.state, funnelServiceZipCode: state.order.serviceLocation.zipCode, funnelParentAccountNumber: state.order.payment.parentAccountNumber, funnelIsCoverageVerified: state.order.payment.insuranceCoverage.isVerified, funnelHasRecalibrationPart: getHasRecalibrationPart(state), funnelSelectedMultiGlass: state.order.damage.glassToReplace?.length > 1, funnelSelectedWindshieldGlass: getNonFalseValuesOfPropertyInArrayOfObjects( state.order.damage.glassToReplace, "glassLocation" ).includes(damageLocationsSelected.WINDSHIELD), funnelSelectedBackGlass: getNonFalseValuesOfPropertyInArrayOfObjects( state.order.damage.glassToReplace, "glassLocation" ).includes(damageLocationsSelected.REAR), funnelSelectedDriverSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects( state.order.damage.glassToReplace, "glassLocation" ).includes(damageLocationsSelected.DRIVER), funnelSelectedPassengerSideGlass: getNonFalseValuesOfPropertyInArrayOfObjects( state.order.damage.glassToReplace, "glassLocation" ).includes(damageLocationsSelected.PASSENGER), funnelOrderPartNumbers: [ ...getNonFalseValuesOfPropertyInArrayOfObjects( state.order.lineItems.glassParts, "partNumber" ), ...getNonFalseValuesOfPropertyInArrayOfObjects( state.order.lineItems.supportingItems, "partNumber" ), ...getNonFalseValuesOfPropertyInArrayOfObjects( state.order.lineItems.vaps, "partNumber" ), ], funnelOrderPartTypes: [ ...getNonFalseValuesOfPropertyInArrayOfObjects( state.order.lineItems.glassParts, "recalibrationType" ), ], }; }, experimentSettings: (state) => state.applicationUser.experiments .map((x) => x.settings) .reduce((r, c) => Object.assign(r, c), {}) ?? {}, }; function getNonFalseValuesOfPropertyInArrayOfObjects(array, propertyName) { return (array ?? []).map((x) => x[propertyName]).filter((x) => x); } // Export Actions export const actions = { // Vehicle API Actions getVehicleYears(context) { return globalMethods.callHttpClient({ method: endpoints.GetVehicleYears.method, endpoint: endpoints.GetVehicleYears.url, payload: {}, }); }, lookupVehicleByYmms(context, { year, make, model, style }) { return globalMethods.callHttpClient({ method: endpoints.LookupVehicleByYmms.method, endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`, payload: {}, }); }, lookupVehicleByVin(context, { vin }) { return globalMethods.callHttpClient({ method: endpoints.LookupVehicleByVin.method, endpoint: endpoints.LookupVehicleByVin.url, payload: { vin: vin, // EX "1J4GW58S4XC541166" }, }); }, lookupVinByPlate(context, { licensePlate, licenseState }) { return globalMethods.callHttpClient({ method: endpoints.LookupVinByPlate.method, endpoint: endpoints.LookupVinByPlate.url, payload: { licensePlate: licensePlate, licenseState: licenseState, }, }); }, lookupVinByAddress( context, { licenseLastName, licenseStreetAddress, licenseZip, licenseState } ) { return globalMethods.callHttpClient({ method: endpoints.LookupVinByAddress.method, endpoint: endpoints.LookupVinByAddress.url, payload: { licenseLastName: licenseLastName, licenseStreetAddress: licenseStreetAddress, licenseZip: licenseZip, licenseState: licenseState, }, }); }, isVinByAddressPermissible(context, zip) { return globalMethods.callHttpClient({ method: endpoints.IsVinByAddressPermissible.method, endpoint: `${endpoints.IsVinByAddressPermissible.url}?zipcode=${zip}`, payload: {}, }); }, getVehicleMakes(context, { year }) { return globalMethods.callHttpClient({ method: endpoints.GetVehicleMakes.method, endpoint: `${endpoints.GetVehicleMakes.url}/${year}`, payload: {}, }); }, getVehicleModels(context, { year, make }) { return globalMethods.callHttpClient({ method: endpoints.GetVehicleModels.method, endpoint: `${endpoints.GetVehicleModels.url}/${year}/${make}`, payload: {}, }); }, getVehicleStyles(context, { year, make, model }) { return globalMethods.callHttpClient({ method: endpoints.GetVehicleStyles.method, endpoint: `${endpoints.GetVehicleStyles.url}/${year}/${make}/${model}`, payload: {}, }); }, setVehicle(context, { year, make, model, style }) { return globalMethods .callHttpClient({ methods: endpoints.GetVehicle.method, endpoint: `${endpoints.GetVehicle.url}/${year}/${make}/${model}/${style}`, payload: {}, }) .then((response) => { context.commit(storeMutations.UPDATE_CAR_ID, response.data.carId); context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, response.data.category); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, response.data.imageUrl); context.commit( storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, response.data.imageVifNumber ); context.commit( storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, response.data.imageVifColor ); return response; }); }, getDamageOptions(context, { carId }) { return globalMethods.callHttpClient({ methods: endpoints.GetDamageOptions.method, endpoint: `${endpoints.GetDamageOptions.url}/${carId}`, payload: {}, }); }, validateZip(context, { zip }) { return globalMethods.callHttpClient({ methods: endpoints.ValidateZip.method, endpoint: `${endpoints.ValidateZip.url}/${zip}`, }); }, // Dependency Actions resetDamageAndDependencies(context) { context.commit(storeMutations.RESET_DAMAGE_STATE); context.commit(storeMutations.RESET_GLASS_PARTS_STATE); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); context.commit(storeMutations.UPDATE_VAPS, null); }, resetRegistrationAndDependencies(context) { context.commit(storeMutations.RESET_REGISTRATION_STATE); context.commit(storeMutations.RESET_GLASS_PARTS_STATE); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); }, resetPartsAndDependencies(context) { context.commit(storeMutations.RESET_GLASS_PARTS_STATE); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); }, resetState(context) { context.commit(storeMutations.RESET_STATE); }, resetSaveSessionPromise(context) { context.commit(storeMutations.RESET_SAVE_SESSION_PROMISE); }, // Content API Actions getRouteInfo(context, { pageName }) { return globalMethods.callHttpClient({ method: endpoints.GetRouteInfo.method, endpoint: endpoints.GetRouteInfo.url(applicationConfig.APPLICATION_ABBREVIATION), payload: { pageName: pageName, }, }); }, getHomepageName(context) { return globalMethods.callHttpClient({ method: endpoints.GetHomepageInfo.method, endpoint: endpoints.GetHomepageInfo.url(applicationConfig.APPLICATION_ABBREVIATION), }); }, getPageData(context, { pageName }) { return globalMethods.callHttpClient({ method: endpoints.GetPageData.method, endpoint: endpoints.GetPageData.url( applicationConfig.APPLICATION_ABBREVIATION, pageName ), payload: {}, }); }, // Analytics Actions logExperimentExposure(context, { userId, sessionKey, pageName, experiment }) { return globalMethods.callHttpClient({ method: endpoints.LogExperimentExposureIfAssigned.method, endpoint: endpoints.LogExperimentExposureIfAssigned.url, payload: { experimentForLogging: { userId: userId, experimentUniverseId: experiment.universeId, experimentUniverseName: experiment.universeName, experimentTestId: experiment.testId, experimentTestName: experiment.testName, experimentVariationId: experiment.variationId, experimentVariationName: experiment.variationName, enabled: experiment.isActive, isExposed: experiment.isExposed, userPartitionNumber: experiment.userPartitionNumber, assignmentId: experiment.assignmentId, sessionKey: sessionKey, pageName: pageName, }, }, }); }, // Misc Actions updateStoreWithSaveSessionResponse( context, { referralNumber, referralDate, referralCorrelationId, eon, parentAccountNumber, savedSessionId, crmCustomerId, } ) { context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber); context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate); context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId); context.commit(storeMutations.UPDATE_EON, eon); context.commit(storeMutations.UPDATE_PARENT_ACCT_NUMBER, parentAccountNumber); context.commit(storeMutations.UPDATE_SAVED_SESSION_ID, savedSessionId); context.commit(storeMutations.UPDATE_CRM_CUSTOMER_ID, crmCustomerId); }, logPageView( context, { userId, sessionKey, pageName, sessionId, action, event, shouldUseSessionId, experimentsForUser, } ) { var payload = { userId: userId, sessionKey: sessionKey, sessionId: sessionId, pageName: pageName, applicationName: applicationConfig.APPLICATION_NAME, action: action, event: event, shouldUseSessionId: shouldUseSessionId, experimentsForUser: experimentsForUser, }; return globalMethods.callHttpClient({ method: endpoints.LogPageView.method, endpoint: endpoints.LogPageView.url, payload: payload, logApiCall: false, }); }, logCustomEvent( context, { userId, sessionKey, pageName, sessionId, category, action, label, value, shouldUseSessionId, experimentsForUser, } ) { var payload = { userId: userId, sessionKey: sessionKey, sessionId: sessionId, pageName: pageName, applicationName: applicationConfig.APPLICATION_NAME, category: category, action: action, label: label, value: value, shouldUseSessionId: shouldUseSessionId, experimentsForUser: experimentsForUser, }; return globalMethods.callHttpClient({ method: endpoints.LogCustomEvent.method, endpoint: endpoints.LogCustomEvent.url, payload: payload, logApiCall: false, }); }, initializeSession(context, { userId, sessionId, userAgent, referrer }) { var payload = { applicationName: applicationConfig.APPLICATION_NAME, userId: userId, deviceId: userId, sessionId: sessionId, userAgent: userAgent, operatorId: "WEB", userName: "SafeliteConceptFunnel", referrer: referrer, }; return globalMethods.callHttpClient({ method: endpoints.InitializeSession.method, endpoint: endpoints.InitializeSession.url, payload: payload, logApiCall: false, }); }, // Misc Actions setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId, eon }) { context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber); context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate); context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId); context.commit(storeMutations.UPDATE_EON, eon); }, GetExperimentsByUser(context, { userId }) { return globalMethods.callHttpClient({ method: endpoints.GetExperimentsByUser.method, endpoint: `${endpoints.GetExperimentsByUser.url}/${userId}`, payload: {}, }); }, async runExperimentsForTrigger(context, { userId, triggerEvent, triggerValue }) { if (triggerEvent == experimentTriggers.SITE_ENTRY) { context.commit(storeMutations.UPDATE_TRIGGERED_SITE_ENTRY, true); } var payload = { applicationName: applicationConfig.APPLICATION_NAME, userId: userId, triggerEvent: triggerEvent, triggerValue: triggerValue, experimentOrder: context.getters.experimentOrder, }; const response = await globalMethods.callHttpClient({ method: endpoints.RunExperimentsForTrigger.method, endpoint: endpoints.RunExperimentsForTrigger.url, payload: payload, }); context.commit(storeMutations.UPDATE_EXPERIMENTS, response.data.experiments); }, getEvoxImage(context, { relativeUrl }) { return globalMethods.callHttpClient({ method: endpoints.GetPageData.method, endpoint: relativeUrl, payload: {}, }); }, // PartsOrQuestions API Actions async getPartsOrQuestions(context) { const vehicle = context.getters.vehicle; const damage = context.getters.damage; const order = context.state.order; const carId = vehicle.carId; const glassArray = damage.glassToReplace; const zipCode = order.serviceLocation.zipCode; const vin = vehicle.vin; // create a new array to avoid mutating state const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray); const response = await globalMethods.callHttpClient({ method: endpoints.GetPartsOrQuestions.method, endpoint: endpoints.GetPartsOrQuestions.url, payload: { carId: carId, glassPieces: glassArrayForPayload, zip: zipCode, vin: vin, }, }); // Flatten location and name properties response.data.partsOrQuestions = convertGlassPieceNamingFromApi( response.data.partsOrQuestions ); return response; }, // Parts API Actions async getParts(context) { const vehicle = context.getters.vehicle; const damage = context.getters.damage; const order = context.state.order; const carId = vehicle.carId; const glassArray = damage.glassToReplace; const resultsArray = damage.partQuestionAnswers; const zipCode = order.serviceLocation.zipCode; const vin = vehicle.vin; // create a new array to avoid mutating state const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray); const resultsArrayForPayload = convertResultsForApi(resultsArray); const response = await globalMethods.callHttpClient({ method: endpoints.GetParts.method, endpoint: endpoints.GetParts.url, payload: { carId: carId, glassPieces: glassArrayForPayload, answerResults: resultsArrayForPayload, zip: zipCode, vin: vin, }, }); // Flatten location and name properties response.data.glassPieceParts = convertGlassPieceNamingFromApi( response.data.glassPieceParts ); return response; }, getWipers(context) { const carId = context.getters.vehicle.carId; const serviceZipCode = context.getters.order.serviceLocation.zipCode; return globalMethods .callHttpClient({ method: endpoints.GetWipers.method, endpoint: `${endpoints.GetWipers.url}/${carId}/${serviceZipCode}`, }) .catch((error) => { // The wiper service sometimes returns 500s on legitimate carId/zipCode combination - return empty array instead of breaking flow return []; }); }, getRainDefense(context) { return globalMethods.callHttpClient({ method: endpoints.GetRainDefense.method, endpoint: endpoints.GetRainDefense.url, }); }, getMobileFeePart(context) { return globalMethods.callMockHttpClient({ method: endpoints.GetMobileFeePart.method, endpoint: "https://run.mocky.io/v3/795de4cb-d014-48b4-9338-dab33261adce", //TODO: Remove Mocky Endpoint }); }, getSupportingItems(context) { const glassPartsArray = context.getters.lineItems.glassParts ?? []; const carId = context.getters.vehicle.carId; const isRepair = context.getters.damage.isRepair; const numberOfChips = context.getters.damage.numberOfChips; return globalMethods.callHttpClient({ method: endpoints.GetSupportingItems.method, endpoint: endpoints.GetSupportingItems.url, payload: { carId: carId, serviceType: isRepair ? "Repair" : "Replace", parentAccountNumber: applicationConfig.CASH_PARENT_ACCOUNT_NUMBER, parts: glassPartsArray, numberOfRepairChips: isRepair ? numberOfChips : 0, }, }); }, getCapabilityQuestions(context, { carId, partNumber }) { return globalMethods.callHttpClient({ method: endpoints.GetCapabilityQuestions.method, endpoint: `${endpoints.GetCapabilityQuestions.url}/${carId}/${partNumber}`, }); }, getPartFromCapabilityQuestionAnswer(context, glassLocation) { const pageData = context.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS); const part = pageData.partsOrQuestions.find((x) => x.glassLocation === glassLocation) .parts[0]; const capabilityQuestionAnswers = context.getters.damage.capabilityQuestionAnswers; const capabilityQuestionAnswersForPart = capabilityQuestionAnswers.find( (x) => x.glassLocation === glassLocation ); return globalMethods.callHttpClient({ method: endpoints.GetPartFromCapabilityAnswer.method, endpoint: endpoints.GetPartFromCapabilityAnswer.url, payload: { part, capabilityAnswerResults: capabilityQuestionAnswersForPart, }, }); }, // Session API Actions saveSession(context) { const vehicle = context.getters.vehicle; const damage = context.getters.damage; const order = context.state.order; const applicationUser = context.getters.applicationUser; const lineItems = context.state.order.lineItems; // create a new array to avoid mutating state const newGlassToReplace = convertGlassPieceNamingForApi(damage.glassToReplace); return globalMethods.callHttpClient({ method: endpoints.SaveSession.method, endpoint: endpoints.SaveSession.url, payload: { applicationUser: { crmCustomerId: applicationUser.crmCustomerId, experiments: applicationUser.experiments, lastPage: applicationUser.lastPageVisited, pageData: applicationUser.pageData, savedSessionId: applicationUser.savedSessionId, }, order: { vehicle: { carId: vehicle.carId, year: vehicle.year, make: vehicle.make, model: vehicle.model, style: vehicle.style, vin: vehicle.vin, registration: { firstName: vehicle.registration.firstName, lastName: vehicle.registration.lastName, streetAddress: vehicle.registration.address, city: vehicle.registration.city, state: vehicle.registration.state, zipCode: vehicle.registration.zipCode, licensePlateNumber: vehicle.registration.licensePlate, }, }, customer: { emailAddress: order.customer.emailAddress, }, damage: { numberOfChips: damage.numberOfChips, glassToReplace: newGlassToReplace, isRepair: damage.isRepair, partQuestionAnswers: order.damage.partQuestionAnswers, moldingQuestionAnswers: order.damage.moldingQuestionAnswers, capabilityQuestionAnswers: order.damage.capabilityQuestionAnswers, }, lineItems: { glassParts: lineItems.glassParts, supportingItems: lineItems.supportingItems, vaps: lineItems.vaps, serverData: lineItems.serverData, }, payment: { InsuranceCoverage: { isVerified: order.payment.insuranceCoverage.isVerified ?? false, }, isInsurance: order.payment.isInsurance ?? false, parentAccountNumber: order.payment.parentAccountNumber, }, providerNumber: "", serviceLocation: { streetAddress: order.serviceLocation.address, city: order.serviceLocation.city, state: order.serviceLocation.state, zipCode: order.serviceLocation.zipCode, zipCodeCtu: order.serviceLocation.zipCodeCtu, }, existingPromoCode: null, referralCorrelationId: order.referralCorrelationId, referralDate: order.referralDate, referralNumber: order.referralNumber?.toString(), // TODO It'd be nice to save these as strings in the first place referralSequenceNumber: order.referralNumber?.toString(), // TODO Pass the referralSequence number once insurance flow creates it eon: order.eon, }, }, }); }, loadSession( context, { savedSessionId, referralNumber, referralDate, parentAccountNumber, referralCorrelationId, isConceptInsurance, } ) { const order = context.state.order; return globalMethods .callHttpClient({ method: endpoints.LoadSession.method, endpoint: endpoints.LoadSession.url, payload: { savedSessionId: savedSessionId?.toString(), referralNumber: referralNumber?.toString(), referralDate: referralDate?.toString(), parentAccountNumber: parentAccountNumber, referralCorrelationId: referralCorrelationId, }, }) .then( (response) => { // Flatten location and name properties response.data.order.damage?.glassToReplace?.map((glass) => { glass.glassLocation = glass.location; glass.glassName = glass.name; delete glass.location; delete glass.name; return glass; }); // clear the state if the existing EON does not equal what is returned from loadSession if (context.state.order.eon && context.state.order.eon != response.data.eon) { context.commit(storeMutations.RESET_STATE); } context.commit( storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data ); return response; }, (error) => { deleteFunnelCookie(); context.commit(storeMutations.RESET_STATE); } ); }, // Business domain actions // Vehicle saveVehicleYear(context, year) { //Reset dependent state when changing if (context.state.order.vehicle.year !== year) { context.commit(storeMutations.UPDATE_MAKE, null); context.commit(storeMutations.UPDATE_MODEL, null); context.commit(storeMutations.UPDATE_STYLE, null); context.commit(storeMutations.UPDATE_CAR_ID, null); context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null); context.commit(storeMutations.UPDATE_VEHICLE_VIN, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null); context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); //Save new values context.commit(storeMutations.UPDATE_YEAR, year); } }, saveVehicleMake(context, make) { //Reset dependent state when changing if (context.state.order.vehicle.make !== make) { context.commit(storeMutations.UPDATE_MODEL, null); context.commit(storeMutations.UPDATE_STYLE, null); context.commit(storeMutations.UPDATE_CAR_ID, null); context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null); context.commit(storeMutations.UPDATE_VEHICLE_VIN, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null); context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); //Save new values context.commit(storeMutations.UPDATE_MAKE, make); } }, saveVehicleModel(context, model) { //Reset dependent state when changing if (context.state.order.vehicle.model !== model) { context.commit(storeMutations.UPDATE_STYLE, null); context.commit(storeMutations.UPDATE_CAR_ID, null); context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null); context.commit(storeMutations.UPDATE_VEHICLE_VIN, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null); context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); //Save new values context.commit(storeMutations.UPDATE_MODEL, model); } }, saveVehicleStyle(context, style) { //Reset dependent state when changing if (context.state.order.vehicle.style !== style) { context.commit(storeMutations.UPDATE_CAR_ID, null); context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null); context.commit(storeMutations.UPDATE_VEHICLE_VIN, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null); context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null); context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); //Save new values context.commit(storeMutations.UPDATE_STYLE, style); } }, saveVehicleDamage( context, { isWindshieldRepair, selectedGlassToReplace, selectedWindshieldChipCount } ) { const selectedGlassPassedInSorted = selectedGlassToReplace.slice().sort(); const isGlassToReplaceTheSame = context.state.order.damage.glassToReplace?.length === selectedGlassToReplace.length && context.state.order.damage.glassToReplace .slice() .sort() .every( (obj, index) => obj.glassLocation === selectedGlassPassedInSorted[index].glassLocation && obj.glassName === selectedGlassPassedInSorted[index].glassName ); const isWindshieldRepairTheSame = isWindshieldRepair === context.state.order.damage.isRepair; const isChipCountTheSame = selectedWindshieldChipCount === context.state.order.damage.numberOfChips; const isDamageChanging = !isGlassToReplaceTheSame || !isWindshieldRepairTheSame || (isWindshieldRepair && !isChipCountTheSame); if (isDamageChanging) { //Reset dependent state when changing context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); context.commit(storeMutations.UPDATE_VAPS, null); // Save new values context.commit(storeMutations.UPDATE_IS_REPAIR, isWindshieldRepair); context.commit( storeMutations.UPDATE_NUMBER_OF_CHIPS, isWindshieldRepair ? parseInt(selectedWindshieldChipCount) : null ); context.commit(storeMutations.UPDATE_GLASS_TO_REPLACE, selectedGlassToReplace); } }, // Vin lookup saveVinLookup(context, { isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo }) { //Reset dependent state when changing if (vehicleInfo.vin !== context.state.order.vehicle.vin) { context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); if (!isSelectedGlassAvailableForVehicle) { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); } //Save new values context.commit(storeMutations.UPDATE_VEHICLE, vehicleInfo); context.commit(storeMutations.UPDATE_REGISTRATION, registrationInfo); } }, saveRegistrationLicensePlateLookup( context, { isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo } ) { //Reset dependent state when changing if ( registrationInfo?.licensePlate !== context.state.order.vehicle.registration?.licensePlate ) { context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); if (!isSelectedGlassAvailableForVehicle) { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); } //Save new values context.commit(storeMutations.UPDATE_VEHICLE, vehicleInfo); context.commit(storeMutations.UPDATE_REGISTRATION, registrationInfo); } }, saveRegistrationAddressLookup( context, { isSelectedGlassAvailableForVehicle, vehicleInfo, registrationInfo } ) { //Reset dependent state when changing if ( registrationInfo?.address !== context.state.order.vehicle.registration?.address || registrationInfo?.city !== context.state.order.vehicle.registration?.city || registrationInfo?.state !== context.state.order.vehicle.registration?.state || registrationInfo?.zipCode !== context.state.order.vehicle.registration?.zipCode || registrationInfo?.firstName !== context.state.order.vehicle.registration?.firstName || registrationInfo?.lastName !== context.state.order.vehicle.registration?.lastName ) { context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES); if (!isSelectedGlassAvailableForVehicle) { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); } //Save new values context.commit(storeMutations.UPDATE_VEHICLE, vehicleInfo); context.commit(storeMutations.UPDATE_REGISTRATION, registrationInfo); } }, savePartQuestionAnswers(context, partQuestionAnswersArray) { // if part question answers have changed, reset subsequent question answers const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue( context.getters.damage.partQuestionAnswers, "result" ); const sortedPartQuestionAnswersArray = sortArrayOfObjectsByPropertyValue( partQuestionAnswersArray, "result" ); const havePartQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedPartQuestionAnswersArray.length || !sortedPreviousResultsArray?.every( (x, i) => x.result === sortedPartQuestionAnswersArray[i].result ); if (havePartQuestionAnswersChanged) { context.commit(storeMutations.UPDATE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); context.commit(storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS, null); context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, null); context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.VEHICLE_PARTS, data: null, }); context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.MOLDING_QUESTIONS, data: null, }); context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.CAPABILITY_QUESTIONS, data: null, }); } //Save new values context.commit(storeMutations.UPDATE_PART_QUESTION_ANSWERS, partQuestionAnswersArray); }, resetMoldingAndCapabilityQuestionAnswersIfNeeded(context, matchedParts) { const partsOrQuestionsDataToCompareWith = context.getters.pageData(fmgPageValues.MOLDING_QUESTIONS)?.partsOrQuestions ?? context.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS)?.partsOrQuestions ?? []; function getAllPartNumbers(partsOrQuestions) { return partsOrQuestions[0]?.parts ? [...partsOrQuestions] .map((glass) => glass.parts) .flat() .map((part) => part.partNumber) .filter((partNumber) => !partNumber.toUpperCase().includes("FEE")) .sort() .join(",") : []; } const previouslySelectedPartNumbers = getAllPartNumbers(partsOrQuestionsDataToCompareWith); const currentlySelectedPartNumbers = getAllPartNumbers(matchedParts); const haveSelectedVehiclePartsChanged = previouslySelectedPartNumbers !== currentlySelectedPartNumbers; if (haveSelectedVehiclePartsChanged) { context.commit(storeMutations.UPDATE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); context.commit(storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS, null); context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, null); context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.MOLDING_QUESTIONS, data: null, }); context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.CAPABILITY_QUESTIONS, data: null, }); } }, saveMoldingQuestionAnswers(context, moldingQuestionAnswers) { const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue( context.getters.damage.moldingQuestionAnswers, "partNum" ); const sortedMoldingQuestionAnswersArray = sortArrayOfObjectsByPropertyValue( moldingQuestionAnswers, "partNum" ); const haveMoldingQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedMoldingQuestionAnswersArray.length || !sortedPreviousResultsArray?.every( (x, i) => x.partNum === sortedMoldingQuestionAnswersArray[i].partNum ); if (haveMoldingQuestionAnswersChanged) { context.commit(storeMutations.UPDATE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); context.commit(storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, null); context.commit(storeMutations.UPDATE_PAGE_DATA, { page: fmgPageValues.CAPABILITY_QUESTIONS, data: null, }); } //Save new values context.commit(storeMutations.UPDATE_MOLDING_QUESTION_ANSWERS, moldingQuestionAnswers); }, saveCapabilityQuestionAnswers(context, capabilityQuestionAnswers) { const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue( context.getters.damage.capabilityQuestionAnswers, "result" ); const sortedCapabilityQuestionAnswersArray = sortArrayOfObjectsByPropertyValue( capabilityQuestionAnswers, "result" ); const haveCapabilityQuestionAnswersChanged = sortedPreviousResultsArray?.length !== sortedCapabilityQuestionAnswersArray.length || !sortedPreviousResultsArray?.every( (x, i) => x.result === sortedCapabilityQuestionAnswersArray[i].result ); if (haveCapabilityQuestionAnswersChanged) { context.commit(storeMutations.UPDATE_GLASS_PARTS, null); context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, null); } //Save new values context.commit( storeMutations.UPDATE_CAPABILITY_QUESTION_ANSWERS, capabilityQuestionAnswers ); }, savePaymentType(context, isInsurance) { context.commit(storeMutations.UPDATE_IS_INSURANCE, isInsurance); }, saveParentAccountNumber(context, parentAccountNumber) { context.commit(storeMutations.UPDATE_PARENT_ACCT_NUMBER, parentAccountNumber); }, saveSupportingItems(context, supportingItems) { context.commit(storeMutations.UPDATE_SUPPORTING_ITEMS, supportingItems); }, saveVaps(context, vaps) { context.commit(storeMutations.UPDATE_VAPS, vaps); }, // Price order actions async priceOrderItemsAndSaveServerData(context, { availableLineItems, serviceZipCode, ctu }) { const zipCodeToUse = serviceZipCode ? serviceZipCode : context.getters.order.serviceLocation.zipCode; const ctuToUse = ctu ? ctu : context.getters.order.serviceLocation.zipCodeCtu; const availableLineItemsFormattedForRequest = getLineItemQueryStringForPricing(availableLineItems); const vehicle = context.getters.order.vehicle; let queryString = `ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}` + `&CTU=${ctuToUse}` + `&CarId=${vehicle.carId}` + `&Make=${vehicle.make}` + `&Model=${vehicle.model}` + `&Year=${vehicle.year}` + `&EON=${context.getters.order.eon}` + `&ZipCode=${zipCodeToUse}` + `${availableLineItemsFormattedForRequest}`; const lineItemServerData = context.getters.order.lineItems.serverData; if (lineItemServerData) { queryString += `&ServerData=${encodeURIComponent(lineItemServerData)}`; } const response = await globalMethods.callHttpClient({ method: endpoints.PriceOrderItems.method, endpoint: `${endpoints.PriceOrderItems.url}?${queryString}`, }); context.commit(storeMutations.UPDATE_LINE_ITEMS_SERVER_DATA, response.data.serverData); availableLineItems = addPricesToLineItems(availableLineItems, response.data.lineItems); return availableLineItems; }, // Misc order actions saveServiceLocation(context, serviceLocationInfo) { context.commit(storeMutations.UPDATE_SERVICE_LOCATION, serviceLocationInfo); }, saveEmail(context, email) { context.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, email); }, saveVin(context, { isSelectedGlassAvailableForVehicle, vehicleInfo }) { //Reset dependent state when changing if (vehicleInfo.vin !== context.state.order.vehicle.vin) { if (!isSelectedGlassAvailableForVehicle) { context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); } //Save new values context.commit(storeMutations.UPDATE_VEHICLE, vehicleInfo); } }, saveGlassParts(context, parts) { context.commit(storeMutations.UPDATE_GLASS_PARTS, parts); }, clearVin(context) { context.commit(storeMutations.UPDATE_VEHICLE_VIN, null); }, isVinOptionalVehicle(context) { switch (context.state.order.vehicle.make.toLowerCase()) { case "mercedes benz": case "volkswagen": case "audi": case "porsche": return true; default: } if ( context.state.order.vehicle.make.toLowerCase() === "ford" && context.state.order.vehicle.year >= 2018 ) { return true; } if ( context.state.order.vehicle.make.toLowerCase() === "bmw" && context.state.order.vehicle.year <= 2017 ) return true; return false; }, }; export default createStore({ plugins: [createPersistedState()], // IMPORTANT: Be VERY careful when modifying these fields for at least a few reasons: // * The CMS can reference the fields by name // * Return users may have a previous "version" of the model, and we don't want // them to have a breaking experience, because the model might have changed. state, mutations, getters, actions, }); // Private Functions function getHasRecalibrationPart(state) { var hasRequiresRecalibration = getNonFalseValuesOfPropertyInArrayOfObjects( state.order.lineItems.glassParts, "requiresRecalibration" )?.length > 0; var hasRecalibrationType = getNonFalseValuesOfPropertyInArrayOfObjects( state.order.lineItems.glassParts, "recalibrationType" )?.length > 0; if (hasRequiresRecalibration) { if (hasRecalibrationType) { // Has both 'requiresRecalibration' and 'recalibrationType' and 'recalibrationType' return ( getNonFalseValuesOfPropertyInArrayOfObjects( state.order.lineItems.glassParts, "recalibrationType" )[0].toLowerCase() != "unknown" ); } else { // Has 'requiresRecalibration' but no 'recalibrationType' at all return true; } } else { // Does not have 'requiresRecalibration' return false; } } function sortArrayOfObjectsByPropertyValue(arrayOfObjects, propertyName) { if (!arrayOfObjects) return null; return arrayOfObjects.sort((a, b) => { if (a[propertyName] < b[propertyName]) return -1; else if (a[propertyName] > b[propertyName]) return 1; else return 0; }); } function convertGlassPieceNamingForApi(glassArray) { if (!glassArray || glassArray.length === 0) return []; // check if array already converted. (likely when a session has been saved previously and then reloaded) if (glassArray[0].location !== undefined) { return glassArray; } const converted = []; glassArray.forEach((glass) => { converted.push({ location: glass.glassLocation, name: glass.glassName, }); }); return converted; } function convertResultsForApi(resultsArray) { if (!resultsArray) return []; const converted = []; resultsArray.forEach((answer) => { converted.push({ location: answer.glassLocation, name: answer.glassName, result: answer.result, }); }); return converted; } function convertGlassPieceNamingFromApi(glassArray) { glassArray.forEach((glass) => { glass.glassLocation = glass.glassPiece.location; glass.glassName = glass.glassPiece.name; delete glass.glassPiece; return glass; }); return glassArray; } function addPricesToLineItems(lineItems, pricingLineItems) { lineItems.forEach((lineItem) => { let lineItemIndex = pricingLineItems.findIndex( (pricingLineItem) => pricingLineItem.partNumber === lineItem.partNumber ); if (lineItem.childParts) { addPricesToLineItems(lineItem.childParts, pricingLineItems); } let pricedLineItem = pricingLineItems.splice(lineItemIndex, 1)[0]; lineItem.laborAmount = pricedLineItem.laborAmount; lineItem.sellingPrice = pricedLineItem.sellingPrice; lineItem.kitPrice = pricedLineItem.kitPrice; }); return lineItems; } function getLineItemQueryStringForPricing(lineItems) { return lineItems .map((lineItem) => { let queryStringSnippet = `&LineItems=${lineItem.partNumber}`; if (lineItem.childParts) { queryStringSnippet += getLineItemQueryStringForPricing(lineItem.childParts); } return queryStringSnippet; }) .join(""); }