diff --git a/src/helpers/cart-helper.js b/src/helpers/cart-helper.js index 405dea57..1920df3c 100644 --- a/src/helpers/cart-helper.js +++ b/src/helpers/cart-helper.js @@ -28,6 +28,20 @@ export function getServiceLineItems(order) { ]; } +/** + * Returns an array containing only the + * @param {object} order order object + * @returns {[]} array of service line items + */ +export function getAvailableLineItems(order) { + const { glassParts, supportingItems } = getLineItems(order); + const availableLineItems = [ + ...(glassParts ?? []), + ...(supportingItems ?? []) + ]; + return availableLineItems; +} + /** * Returns an array containing only the non-service line items (Vaps and Fees) * @param {object} order order object diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue index 54e341ff..b4bf1614 100644 --- a/src/layouts/coverage-statement/coverage-statement.vue +++ b/src/layouts/coverage-statement/coverage-statement.vue @@ -145,6 +145,7 @@ import widgetFields from '@/constants/cms-widget-fields.js'; import { formatAmountInDollars, createUnorderedListFromStringOfParagraphs, createOrderedListFromStringOfParagraphs } from '@/helpers/text-helper.js'; import showIssLoadingModal from '@/helpers/loading-modal-helper'; import { getPriceOfLineItems } from '@/helpers/price-calculator'; +import { getAvailableLineItems } from '@/helpers/cart-helper'; import coverageStatuses from '@/constants/coverage-statuses'; import coverageType from '@/constants/coverage-type'; import oemEndorsementModal from '@/layouts/coverage-statement/oem-endorsement-modal/oem-endorsement-modal.vue'; @@ -470,11 +471,7 @@ export default { this.isPageLoading = false; }, async getPricedParts() { - const { glassParts, supportingItems } = this.mainStore.order.lineItems; - const availableLineItems = [ - ...(glassParts ?? []), - ...(supportingItems ?? []) - ]; + const availableLineItems = getAvailableLineItems(this.mainStore.order); // We only call the ITAC pricing endpoint if we are not repair or we are NoComp if (!this.isRepair || this.mainStore.isNoComp) { @@ -494,6 +491,7 @@ export default { this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD); } else if (this.isITACQuoteVisible || this.isNoCompQuoteVisible) { this.mainStore.updateIsSafeliteProvider(true); + this.pushEventToGA('ShopSelection', 'Safelite', this.mainStore.currentDeductible + `_` + getPriceOfLineItems(getAvailableLineItems(this.mainStore.order)), true); this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE); } else { this.$router.navigateBailout(bailoutMessage.coverageStatementInvalidState()); diff --git a/src/layouts/order-confirmation/order-confirmation.vue b/src/layouts/order-confirmation/order-confirmation.vue index 1a3b6db9..3f34efd4 100644 --- a/src/layouts/order-confirmation/order-confirmation.vue +++ b/src/layouts/order-confirmation/order-confirmation.vue @@ -665,7 +665,7 @@ export default { // TODO: Check if we're coming from SFA and add relevant events // eslint-disable-next-line if (false) { - this.pushEventToGA('visitor_info_confirmation', 'referring_site', 'SFA', null); + this.pushEventToGA('visitor_info_confirmation', 'referring_site', 'SFA', true); } else { this.pushEventToGA('visitor_info_confirmation', 'referring_site', 'ClientSite', true); diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue index 776a48a5..b13f8b64 100644 --- a/src/layouts/policy-vehicles/policy-vehicles.vue +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -201,6 +201,7 @@ export default { policyVehicleId: vehicle.id, vin: this.selectedVehicleVin }); + useMainStore().updateVehicleCoverage({ noCoverage: this.noCoverageForSelectedVehicle, deductible: this.deductibleForSelectedVehicle, @@ -208,6 +209,9 @@ export default { endorsements: this.endorsementsForSelectedVehicle, cvrgEndorsementCode: this.endorsementCodesForSelectedVehicle }); + + this.pushEventToGA("policy_vehicle", "submitted", useMainStore().order.vehicle.make + "_" + useMainStore().order.vehicle.model + " " + useMainStore().order.vehicle.carId, true); + this.navigateForward(); } catch (e) { if (e.isAxiosError && e.status === 404) { @@ -223,6 +227,9 @@ export default { vin: vehicle.vin }); this.policyVinFound = false; + + this.pushEventToGA("policy_vehicle", "submitted", useMainStore().order.vehicle.make + "_" + useMainStore().order.vehicle.model + " " + useMainStore().order.vehicle.carId, true); + this.navigateForward(); return; } diff --git a/src/layouts/provider-preference/provider-preference.vue b/src/layouts/provider-preference/provider-preference.vue index ff2fdf5c..27f88d72 100644 --- a/src/layouts/provider-preference/provider-preference.vue +++ b/src/layouts/provider-preference/provider-preference.vue @@ -67,6 +67,8 @@ import showIssLoadingModal from '@/helpers/loading-modal-helper'; import bailoutMessage from '@/constants/bailoutMessage'; import baseFormMixin from '@/mixins/base-form-mixin'; import PROVIDER_PREFERENCE_OPTIONS from '@/constants/provider-preference'; +import { getPriceOfLineItems } from '@/helpers/price-calculator'; +import { getAvailableLineItems } from '@/helpers/cart-helper'; // Import Component import { Form } from 'vee-validate'; @@ -159,12 +161,14 @@ export default { this.mainStore.updateIsSafeliteProvider(true); const scenario = this.navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE; this.pushEventToGA('prefered_provider', 'Safelite', this.mainStore.accountNameForEvents, true); + this.pushEventToGA('ShopSelection', 'Safelite', this.mainStore.currentDeductible + `_` + getPriceOfLineItems(getAvailableLineItems(this.mainStore.order)), true); this.navigateForward(scenario); }, scheduleWithTPA() { this.mainStore.updateIsSafeliteProvider(false); const scenario = this.navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED; this.pushEventToGA('prefered_provider', 'TPA', this.mainStore.accountNameForEvents, true); + this.pushEventToGA('ShopSelection', 'Other', this.mainStore.currentDeductible + `_` + getPriceOfLineItems(getAvailableLineItems(this.mainStore.order)), true); this.navigateForward(scenario); }, findAnotherShopClicked() { diff --git a/src/layouts/schedule-page/schedule-page.vue b/src/layouts/schedule-page/schedule-page.vue index b40ad1d1..c76aacce 100644 --- a/src/layouts/schedule-page/schedule-page.vue +++ b/src/layouts/schedule-page/schedule-page.vue @@ -961,12 +961,9 @@ export default { } this.pushEventToGA('appointment', 'availability_mobile', `days_out_${dateDiffString}`, true, null, null); }, - pushServiceTypeEvent() { + pushServiceTypeEvent() { if (this.selectedAppointmentType) { - const gaScheduleType = { - ['service_type']: this.selectedAppointmentType.toLowerCase() - }; - this.pushGenericObjectToGA(gaScheduleType); + this.pushEventToGA('appointment', 'service_type', this.selectedAppointmentType.toLowerCase(), true, null, null); } }, async refreshDatePicker() { diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index 1bb70de7..6f72d2df 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -270,17 +270,17 @@ export default { this.mainStore.applicationUser.firstHit = false; } - // TODO: Check if we're coming from SFA + // TODO: Check if we're coming from SFA - site does not support SFA yet, add this back when it is enabled. // eslint-disable-next-line if (false) { - this.pushEventToGA("co_branded", "welcome_clicked_cta", "yes_clicked", 0); - this.pushEventToGA("visitor_info_welcome", "referring_site", "SFA", null); + this.pushEventToGA("co_branded", "welcome_clicked_cta", "yes_clicked", true, null, '0'); + this.pushEventToGA("visitor_info_welcome", "referring_site", "SFA", true); } else { - this.pushEventToGA("visitor_info_welcome", "referring_site", "ClientSite", null); + this.pushEventToGA("visitor_info_welcome", "referring_site", "ClientSite", true); } - this.pushEventToGA("visitor_info_welcome", "client_name", this.mainStore.accountNameForEvents, null); + this.pushEventToGA("visitor_info_welcome", "client_name", this.mainStore.accountNameForEvents, true); }, computed: { DamageCauseOptions() { @@ -358,6 +358,18 @@ export default { } promises.push(this.mainStore.getCoveragePolicyInfo()); await Promise.all(promises); + + this.pushEventToGA("policy_search", "policy_found", this.mainStore.isPolicyLookupSuccessful ? "Yes" : "No", true); + + if ( this.mainStore.isPolicyLookupSuccessful) { + this.pushEventToGA("zip_validation", "success", "N/A", true); + } + else { + if ( this.mainStore.order.policy.policyLookupErrorCode === 2) { + this.pushEventToGA("zip_validation", "fail", "N/A", true); + } + } + await saveSession({ shouldAwaitSaveSessionQueue: true, bailoutOnError: true }) this.navigateForward(); }, diff --git a/src/mixins/analytics-mixin.js b/src/mixins/analytics-mixin.js index 81d63e41..6480a508 100644 --- a/src/mixins/analytics-mixin.js +++ b/src/mixins/analytics-mixin.js @@ -20,7 +20,8 @@ import { GaEvents, ValueToLogTypes } from '@/constants/analytics'; -import { getCartTotal, getSubtotal } from '@/helpers/cart-helper'; +import { getPriceOfLineItems } from '@/helpers/price-calculator'; +import { getAvailableLineItems, getCartTotal, getSubtotal } from '@/helpers/cart-helper'; import { getRecalPartNumbers, isRecalOrder } from "@/helpers/recal-helper"; import coverageStatuses from '@/constants/coverage-statuses'; import coverageType from '@/constants/coverage-type'; @@ -128,15 +129,6 @@ export default { this.logPageView(analyticsPageEvents.ENTRY); }, - pushValueToGA() { - const gaServiceType = { - ['service_type']: useMainStore().order?.serviceLocation?.appointmentType?.toLowerCase() - }; - if (gaServiceType && gaServiceType['service_type']) { - this.pushGenericObjectToGA(gaServiceType); - } - }, - pushOrderToDataLayer() { // helper check for if an object is defined (but maybe falsey) const isDefined = (x) => x !== null && x !== undefined; @@ -282,7 +274,7 @@ export default { payload.priceTotal = ""; // ITAC or NoComp (where cash price is shown) } else if (store.isVerified && (store.isITAC || store.isNoComp)) { - const subtotal = getSubtotal(order).toFixed(2); + const subtotal = getPriceOfLineItems(getAvailableLineItems(order)).toFixed(2); payload.priceSubTotal = parseFloat(subtotal); const total = getCartTotal(order).toFixed(2); payload.priceTotal = parseFloat(total); @@ -292,7 +284,7 @@ export default { } // Cash Quote or Cash Price Sub Total - payload.cashPriceSubTotal = getSubtotal(order).toString(); + payload.cashPriceSubTotal = getPriceOfLineItems(getAvailableLineItems(order)).toString(); // Recalibration payload.isRecalibrationOnOrder = isRecalOrder(order.lineItems); diff --git a/src/router/index.js b/src/router/index.js index 4fd5306e..64771db5 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -190,9 +190,6 @@ router.afterEach(async (to, from) => { // Push experiments to Data Layer analyticsMixin.methods.pushExperimentsToDataLayer(); - // Push values to GA - analyticsMixin.methods.pushValueToGA(); - // Push current order status to Data Layer analyticsMixin.methods.pushOrderToDataLayer(); } diff --git a/src/store/index.js b/src/store/index.js index de4e1d4a..b53885e0 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -112,7 +112,8 @@ export const getDefaultState = () => ({ endorsementQuestionAnswers: [], cvrgEndorsementCode: null, status: null, - policyData: null + policyData: null, + policyLookupErrorCode: 0 }, customer: { address: { @@ -451,7 +452,7 @@ export const useMainStore = defineStore({ .reduce((r, c) => Object.assign(r, c), {}) ?? {}, originalDeductible: (state) => (state.order.damage.isRepair ? state.order.originalDeductible.repair : state.order.originalDeductible.replace), currentDeductible: (state) => (state.order.damage.isRepair ? state.order.currentDeductible.repair : state.order.currentDeductible.replace), - accountNameForEvents: (state) => state.issConfig.clientName.replaceAll(" ", "").replaceAll("&", "amp") + accountNameForEvents: (state) => state.issConfig.clientName }, actions: { @@ -561,6 +562,7 @@ export const useMainStore = defineStore({ console.log(`Coverage lookup attempt #${this.applicationUser.coverageAttempts}. Max attempts allowed: 10.`); try { + order.policy.policyLookupErrorCode = 0; const response = await globalMethods.callHttpClient({ method: endpoints.CoveragePolicyInfo.method, endpoint: endpoints.CoveragePolicyInfo.url, @@ -598,6 +600,9 @@ export const useMainStore = defineStore({ // populate vehicles order.policy.vehicles = responsePolicy.vehicles ?? []; } else { + if ( response?.data?.isError) { + order.policy.policyLookupErrorCode = response?.data?.errorCode; + } this.updateCoverageType(coverageType.NONE); } } catch (e) { @@ -2119,6 +2124,7 @@ export const useMainStore = defineStore({ this.order.policy.endorsementQuestionAnswers = []; this.order.policy.cvrgEndorsementCode = null; this.order.policy.policyData = null; + this.order.policy.policyLookupErrorCode = 0; this.order.policy.deductible.repair = null; this.order.policy.deductible.replace = null; },