diff --git a/src/helpers/recal-helper.js b/src/helpers/recal-helper.js
index e72c2d63..c6cce97e 100644
--- a/src/helpers/recal-helper.js
+++ b/src/helpers/recal-helper.js
@@ -11,7 +11,7 @@ export function isRecalPartOrHasChildRecalPart(glassPart) {
const isGlassPartRecalPart = isRecalPart(glassPart);
if (!isGlassPartRecalPart && glassPart.childParts && glassPart.childParts.length > 0) {
- return glassPart.childParts.filter((cp) => isRecalPartOrHasChildRecalPart(cp));
+ return glassPart.childParts.some((cp) => isRecalPartOrHasChildRecalPart(cp));
}
return isGlassPartRecalPart;
@@ -52,3 +52,24 @@ export function getRecalPartNumbers(glassPartsArray) {
}
}
+export function containsRecalParts(lineItems) {
+ if (!lineItems) {
+ return false;
+ }
+
+ if (Array.isArray(lineItems)) {
+ return lineItems.some((li) => isRecalPartOrHasChildRecalPart(li));
+ } else {
+ // complex object form -- flatten and re-call.
+ const flattened = [
+ ...(lineItems.glassParts ?? []),
+ ...(lineItems.supportingItems ?? []),
+ ...(lineItems.otherParts ?? []),
+ ...(lineItems.feeItems ?? []),
+ ...(lineItems.vaps ?? []),
+ ];
+
+ return flattened.some((li) => isRecalPartOrHasChildRecalPart(li));
+ }
+}
+
diff --git a/src/layouts/coverage-statement/coverage-statement.spec.js b/src/layouts/coverage-statement/coverage-statement.spec.js
index a8b77aa5..dcccbed6 100644
--- a/src/layouts/coverage-statement/coverage-statement.spec.js
+++ b/src/layouts/coverage-statement/coverage-statement.spec.js
@@ -32,6 +32,12 @@ jest.mock('@/helpers/text-helper', () => ({
formatAmountInDollars: jest.fn()
}));
+jest.mock('@/helpers/recal-helper.js', () => ({
+ containsRecalParts: jest.fn()
+}));
+
+import { containsRecalParts } from '@/helpers/recal-helper.js';
+
const SAFELITE_PROVIDER = 'Safelite';
const CANCEL_CLAIM_REF_NAME = 'CancelClaimModal';
@@ -337,15 +343,17 @@ describe('coverageStatement.vue', () => {
// Assert
expect(result).toBeFalsy();
});
- test('returns true when a part in glassParts require recalibration', () => {
+ test('returns true when a part in glassParts require recalibration and recalibration has been added to order', () => {
// Arrange
+ containsRecalParts.mockReturnValue(true);
const mainInitialState = {
order: {
lineItems: {
glassParts: [
{
partNumber: 123,
- requiresRecalibration: true
+ requiresRecalibration: true,
+ partType: 'RECALIBRATION'
},
{
partNumber: 111,
diff --git a/src/layouts/coverage-statement/coverage-statement.vue b/src/layouts/coverage-statement/coverage-statement.vue
index 4cc38651..0e2dadc4 100644
--- a/src/layouts/coverage-statement/coverage-statement.vue
+++ b/src/layouts/coverage-statement/coverage-statement.vue
@@ -147,6 +147,7 @@ import { getPriceOfLineItems } from '@/helpers/price-calculator';
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';
+import { containsRecalParts } from '@/helpers/recal-helper';
const RECAL_MODAL_REF_NAME = 'RecalModal';
const CANCEL_CLAIM_REF_NAME = 'CancelClaimModal';
@@ -305,9 +306,11 @@ export default {
},
isADAS() {
const { glassParts } = useMainStore().order.lineItems;
+ const orderContainsRecalPart = containsRecalParts(glassParts);
return (
glassParts !== null
&& !!glassParts.find((part) => part.requiresRecalibration)
+ && orderContainsRecalPart
);
},
totalServicePrice() {
@@ -410,7 +413,8 @@ export default {
}
},
async navigateForward() {
- if (this.isUnverifiedVisible || this.isDeductibleVisible) {
+ showIssLoadingModal(true);
+ if (this.isUnverifiedVisible || this.isDeductibleVisible) {
this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD);
} else if (this.isITACQuoteVisible || this.isNoCompQuoteVisible) {
this.mainStore.updateIsSafeliteProvider(true);
diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue
index 32203b5c..aeb58dcb 100644
--- a/src/layouts/license-plate-lookup/license-plate-lookup.vue
+++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue
@@ -3,7 +3,7 @@
ref="theForm"
v-slot="{ meta }"
@submit="onSubmit"
- @invalidSubmit="onInvalidSubmit">
+ @invalidSubmit="customInvalidSubmit">
@@ -251,12 +251,15 @@ export default {
if (vinLookupResponse.error) {
this.displayVinNotFoundAlert = true;
this.previouslyEnteredCarId = null;
+ this.pushEventToGA("VehicleDamage", "LicensePlate_NoMatch", "Trouble_Finding", true, null, '0');
showIssLoadingModal(false);
return this.$refs.siteFooter.disableForwardButton();
}
// Vehicle found from VIN lookup
const vehicleFromLookup = vinLookupResponse.data.vehicle;
+ const vehicleString = vehicleFromLookup.year + '_' + vehicleFromLookup.make + '_' + vehicleFromLookup.model + '_' + vehicleFromLookup.style;
+ this.pushEventToGA("VehicleDamage", "LicensePlate_Vin_Match", vehicleString, true, null, '1');
if (!vehicleFromLookup.canSafeliteService) {
this.mainStore.setBailout({
type: 'HeavyTruckVehicle',
@@ -321,6 +324,12 @@ export default {
resetWarningsAndErrors() {
this.displayVinNotFoundAlert = false;
this.displayMatchedDifferentVehicleAlert = false;
+ },
+ customInvalidSubmit({ errors }) {
+ if (errors['license-plate-question']) {
+ this.pushEventToGA("VehicleDamage", "LicensePlate_NoMatch", "Plate_Required", true, null, '0');
+ }
+ this.onInvalidSubmit({ errors });
}
}
};
diff --git a/src/layouts/service-packages/service-package-question/service-package-question.vue b/src/layouts/service-packages/service-package-question/service-package-question.vue
index 73e29932..63bac64f 100644
--- a/src/layouts/service-packages/service-package-question/service-package-question.vue
+++ b/src/layouts/service-packages/service-package-question/service-package-question.vue
@@ -23,6 +23,7 @@ import partTypeStrings from '@/constants/part-type-strings';
import { useMainStore } from '@/store';
import { getPriceOfLineItem } from '@/helpers/price-calculator';
import { shallowRef } from 'vue';
+import { containsRecalParts } from '@/helpers/recal-helper';
const glassLocations = damageLocationsSelected;
@@ -100,7 +101,7 @@ export default {
return modifiedAnswers;
},
isRecalibrationOnOrder() {
- return this.mainStore.hasRecalibrationPart;
+ return this.mainStore.hasRecalibrationPart && containsRecalParts(this.mainStore.order.lineItems);
},
frontWipersApplicableForTierTwo() {
const frontWipersAreAvailable = this.lineItemsContainsPartType(partTypeStrings.FRONT_WIPER);
diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js
index 8bc26edb..e4911f36 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.spec.js
+++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js
@@ -41,7 +41,8 @@ const mountOptions = {
methods: {
getCmsContent: jest.fn(),
getFooterInfoBoxHeight: jest.fn(() => 80),
- getPageNameByQueryString: jest.fn(() => '')
+ getPageNameByQueryString: jest.fn(() => ''),
+ pushEventToGA: jest.fn()
}
}
],
diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue
index 47f7463d..9833cdcd 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.vue
+++ b/src/layouts/vehicle-damage/vehicle-damage.vue
@@ -412,6 +412,8 @@ export default {
this.selectedWindshieldOptions.selectedWindshieldChipCount
);
+ this.logEvents();
+
if (this.isWindshieldRepair) {
const results = await Promise.allSettled([useMainStore().getSupportingItems(), useMainStore().getRecalParts()]);
const supportingItems = results[0].value;
@@ -481,6 +483,76 @@ export default {
}
return selectedGlassToReplace;
+ },
+ logEvents() {
+ const vehicleString = this.mainStore.order.vehicle.make + '_' + this.mainStore.order.vehicle.model + '_' + this.mainStore.order.vehicle.style;
+ this.pushEventToGA("CAR SUBMISSION", this.mainStore.order.vehicle.year?.toString(), vehicleString, true, null, 0);
+
+ if (this.isWindshieldRepair) {
+ this.pushEventToGA("damage", "selected", "repair", true, null, null);
+ this.pushEventToGA("VehicleDamage", "Repair", this.mainStore.damage.numberOfChips?.toString(), true, null, this.mainStore.damage.numberOfChips);
+ } else {
+ this.pushEventToGA("damage", "selected", "replace", true, null, null);
+ this.selectedGlassToReplace().forEach((glass) => {
+ this.logEventForPart(glass);
+ });
+ }
+ },
+ logEventForPart(glass) {
+ let eventGlassLocation = '';
+ let eventGlassName = '';
+ switch (glass.glassLocation) {
+ case damageLocationsSelected.WINDSHIELD:
+ eventGlassLocation = 'Windshield Replace';
+ break;
+ case damageLocationsSelected.DRIVER:
+ eventGlassLocation = "Driver's Side";
+ break;
+ case damageLocationsSelected.PASSENGER:
+ eventGlassLocation = "Passenger's Side";
+ break;
+ case damageLocationsSelected.REAR:
+ eventGlassLocation = 'Back Glass';
+ break;
+ default:
+ eventGlassLocation = glass.glassLocation;
+ }
+
+ switch (glass.glassName) {
+ // Windshield options
+ case damageLocationsSelected.DRIVER:
+ eventGlassName = "Left piece";
+ break;
+ case damageLocationsSelected.PASSENGER:
+ eventGlassName = "Right piece";
+ break;
+ // Bottom two cases here are for rear options, but they are handled the same as single windshield
+ case damageLocationsSelected.SINGLE:
+ case damageLocationsSelected.STATIONARY:
+ case damageLocationsSelected.SLIDER:
+ eventGlassName = '';
+ break;
+ // Side door options
+ case damageLocationsSelected.FRONT:
+ eventGlassName = "Front door";
+ break;
+ case damageLocationsSelected.BACK:
+ eventGlassName = "Rear door";
+ break;
+ case damageLocationsSelected.QUARTER:
+ eventGlassName = "Quarter";
+ break;
+ case damageLocationsSelected.VENT:
+ eventGlassName = "Vent";
+ break;
+ case damageLocationsSelected.SIDEDOOR:
+ eventGlassName = "Sliding door";
+ break;
+ default:
+ eventGlassName = glass.glassName;
+ }
+ const label = eventGlassName ? `${eventGlassLocation} - ${eventGlassName}` : eventGlassLocation;
+ this.pushEventToGA("VehicleDamage", "Replacement", label, true, null, 1);
}
}
};
diff --git a/src/layouts/vin-lookup/vin-location-information/vin-location-information.vue b/src/layouts/vin-lookup/vin-location-information/vin-location-information.vue
index 7bc12729..b462e860 100644
--- a/src/layouts/vin-lookup/vin-location-information/vin-location-information.vue
+++ b/src/layouts/vin-lookup/vin-location-information/vin-location-information.vue
@@ -38,6 +38,7 @@ export default {
isVinLocationDetailVisible: false
};
},
+ emits: ['vin-location-detail-shown'],
computed: {
textForToggle() {
return this.getCmsContent('WhereCanIFindMyVINToggle', 'HeaderText');
@@ -52,6 +53,9 @@ export default {
methods: {
handleClickToggle() {
this.isVinLocationDetailVisible = !this.isVinLocationDetailVisible;
+ if (this.isVinLocationDetailVisible) {
+ this.$emit('vin-location-detail-shown');
+ }
}
}
};
diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue
index a2efafc8..af598359 100644
--- a/src/layouts/vin-lookup/vin-lookup.vue
+++ b/src/layouts/vin-lookup/vin-lookup.vue
@@ -16,11 +16,12 @@
class="mt-4" />
-
+