Merge pull request #601 from Safelite/feature/CSR-711-2

Feature/csr 711 2
This commit is contained in:
Leah Schumann 2022-07-13 11:09:35 -04:00 committed by GitHub
commit 34319d162b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 428 additions and 317 deletions

View file

@ -38,7 +38,14 @@ describe("address-lookup.vue", () => {
}
const { wrapper } = setupMocks({
isZipServiceable: false
isZipValid: true,
isZipServiceable: false,
vinVehicles: [{
vin: "TEST_VIN",
vehicle: {
carId: "C0000"
}
}]
});
store.commit(storeMutations.UPDATE_CAR_ID, "CARID");
@ -54,6 +61,7 @@ describe("address-lookup.vue", () => {
// Assert
expect(wrapper.findComponent({ ref: "alertNonServiceableZip" }).isVisible()).toBe(true);
});
test("if the address matches a different vehicle display the Matched Different VehicleAlert", async () => {
@ -462,7 +470,14 @@ describe("address-lookup.vue", () => {
}
const { wrapper } = setupMocks({
isZipServiceable: false
isZipValid: true,
isZipServiceable: false,
vinVehicles: [{
vin: "TEST_VIN",
vehicle: {
carId: "C0000"
}
}]
});
store.commit(storeMutations.UPDATE_CAR_ID, "CARID");
@ -612,13 +627,14 @@ describe("address-lookup.vue", () => {
});
});
function setupMocks({ isZipServiceable = true, lookupVinbyAddressResponse, partsOrQuestions = [], isStatePermissible = true, vinVehicles =[], carId = 'C0000'}) {
function setupMocks({ isZipValid = true, isZipServiceable = true, lookupVinbyAddressResponse, partsOrQuestions = [], isStatePermissible = true, vinVehicles =[], carId = 'C0000' }) {
store.commit(storeMutations.RESET_STATE);
const wrapper = shallowMount(addressLookup, getMountOptions({
actionList: [
{
actionName: storeActions.VALIDATE_ZIP,
data: {
isValid: isZipValid,
isServiceable: isZipServiceable
}
},
@ -667,7 +683,8 @@ function setupMocks({ isZipServiceable = true, lookupVinbyAddressResponse, parts
}));
const apiResponses = {
serviceZipValidationResponse:{
serviceZipValidationResponse: {
isValid: isZipValid,
isServiceable: isZipServiceable
},
vinLookupResponse: {

View file

@ -7,15 +7,42 @@
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" ref="funnelSubHeader" />
<div class="fade-on-route-transition sub-container make-tall">
<customerQuestions ref="customerQuestions" v-model="customerQuestions" />
<alert ref="alertVinNotFound" v-if="displayVinNotFoundAlert" class="mb-4" cmsWidgetName="AlertVinNotFoundWidget" alertClass="alert-danger" v-bind:isDismissible="false" />
<alert ref="alertMatchedDifferentVehicle" v-if="displayMatchedDifferentVehicleAlert" class="mb-4" :manualHeadline="AlertMatchedDifferentVehicleHeader" :manualCopy="AlertMatchedDifferentVehicleBody" alertClass="alert-warning" v-bind:isDismissible="false" />
<alert ref="alertNonServiceableZip" v-if="displayNonServiceableZipAlert" class="mb-4" alertClass="alert-danger" :manualHeadline="AlertNonServiceableZipHeader" :manualCopy="AlertNonServiceableZipBody" v-bind:isDismissible="false" />
<alert ref="alertVinLookupsByHomeAddressNotAllowed" v-if="displayVinLookupByHomeAddressNotAllowedAlert" class="mb-4" cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget" alertClass="alert-danger" v-bind:isDismissible="false" />
<alert ref="alertVinNotFound"
v-if="displayVinNotFoundAlert"
class="mb-4"
cmsWidgetName="AlertVinNotFoundWidget"
alertClass="alert-danger"
v-bind:isDismissible="false"
/>
<alert ref="alertMatchedDifferentVehicle"
v-if="displayMatchedDifferentVehicleAlert"
class="mb-4"
:manualHeadline="AlertMatchedDifferentVehicleHeader"
:manualCopy="AlertMatchedDifferentVehicleBody"
alertClass="alert-warning" v-bind:isDismissible="false"
/>
<alert ref="alertInvalidZip"
v-if="displayInvalidZipAlert"
class="mb-4"
cmsWidgetName="AlertInvalidZipWidget"
alertClass="alert-danger"
v-bind:isDismissible="false"
/>
<alert ref="alertNonServiceableZip"
v-if="displayNonServiceableZipAlert"
class="mb-4"
alertClass="alert-danger"
:manualHeadline="AlertNonServiceableZipHeader"
:manualCopy="AlertNonServiceableZipBody"
v-bind:isDismissible="false"
/>
<alert ref="alertVinLookupsByHomeAddressNotAllowed"
v-if="displayVinLookupByHomeAddressNotAllowedAlert"
class="mb-4"
cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget"
alertClass="alert-danger"
v-bind:isDismissible="false"
/>
<transition name="fade" mode="out-in">
<div class="service-zip-field" v-if="showServiceZipField" aria-live="polite">
<div class="row mb-4">
@ -42,20 +69,21 @@ import alert from "@/ux-components/alert/alert";
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
import loadingModal from '@/common-components/loading-modal/loading-modal.vue';
import {Form,defineRule} from "vee-validate";
import {required,regex} from "@/helpers/validation-rules";
import {errorMessages} from "@/constants/error-messages";
import { Form, defineRule } from "vee-validate";
import { required, regex } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
// Supporting files
import {fetchCmsContentForPage} from "@/helpers/cms-content-helper";
import {settleAllPromises} from "@/helpers/layout-helper";
import {storeActions} from "@/constants/store-actions";
import {routerParams} from "@/router/router-constants/router-params";
import {getDamageString,isGlassAvailableForCarId} from "@/helpers/damage-helper";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import { storeActions } from "@/constants/store-actions";
import { routerParams } from "@/router/router-constants/router-params";
import { getDamageString, isGlassAvailableForCarId} from "@/helpers/damage-helper";
import store from "@/store";
import vinPagesMixin from "@/mixins/vin-pages-mixin";
// DEFINE VALIDATION RULES - Note: Additional rules are defined in Customer Questions and Address Questions components
defineRule("service-zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED));
defineRule("service-zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT));
@ -98,8 +126,10 @@ export default {
displayMatchedDifferentVehicleAlert: false,
displayVinLookupByHomeAddressNotAllowedAlert: false,
previouslyEnteredCarId: "",
isCarIdDifferent: false,
isSelectedGlassAvailableForVehicle: false,
customAlertData: {},
displayInvalidZipAlert: false,
showServiceZipField: this.getServiceZipFromStore(),
isZipServiceable: false,
}
@ -171,44 +201,38 @@ export default {
{
resultKey: "serviceZipValidationResponse",
promise: this.serviceZipCode ?
this.dispatchStoreAction(storeActions.VALIDATE_ZIP, {zip: this.serviceZipCode}) :
this.dispatchStoreAction(storeActions.VALIDATE_ZIP, {zip: this.customerQuestions.addressQuestions.zipCode})
this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { zip: this.serviceZipCode }) :
this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { zip: this.customerQuestions.addressQuestions.zipCode })
}
];
const resultMap = await settleAllPromises(promiseResultMap);
// Verify if the service zip code or registration zip code provided is serviceable
// If VIN Lookup by address is forbidden by State Restrictions then show an alert
if (!resultMap.vinLookupResponse.isStatePermissible) {
// State Restrictions forbid lookup by address
this.displayVinLookupByHomeAddressNotAllowedAlert = true;
return this.$refs.funnelFooter.removeLoader();
}
// If the neither the registration zip code or service zip code are not serviceable
this.isZipServiceable = resultMap.serviceZipValidationResponse.isServiceable;
if (!this.isZipServiceable) {
this.displayNonServiceableZipAlert = true;
this.showServiceZipField = true;
return this.$refs.funnelFooter.removeLoader();
}
// If the registration zip code is serviceable and nothing was entered for the service zip code
// then set the service zip code to the registration zip code
if (!this.serviceZipCode) {
this.serviceZipCode = this.customerQuestions.addressQuestions.zipCode;
}
// If a Service Zip is entered and it is an invalid zip code (ex. 11111) then show an alert
const isZipValid = resultMap.serviceZipValidationResponse.isValid;
if (this.serviceZipCode && !isZipValid) {
this.displayInvalidZipAlert = true;
return this.$refs.funnelFooter.removeLoader();
}
this.displayInvalidZipAlert = false;
const carsFound = resultMap.vinLookupResponse.vinVehicles;
// Handle cases for different amounts of VINS found for the address.
if (carsFound.length == 1) {
// Single VIN found
const carFound = carsFound[0].vehicle;
this.isCarIdDifferent = carFound.carId !== this.$store.getters.vehicle.carId;
console.log(this.isCarIdDifferent);
console.log(carFound.carId);
console.log(this.$store.getters.vehicle.carId);
if (this.isCarIdDifferent && carFound.carId !== this.previouslyEnteredCarId) {
// Display Alert
this.previouslyEnteredCarId = carFound.carId;
@ -220,21 +244,13 @@ export default {
// Update button "Continue with..."
this.$refs.funnelFooter.updateButtonText(`Continue with ${carFound.year} ${carFound.make} ${carFound.model}`);
return this.$refs.funnelFooter.removeLoader();
}
if (!this.isZipServiceable) {
return;
}
// update data if the zip or service zip is serviceable
vehicleInfoToCommit = Object.assign(carFound, { vin: carsFound[0].vin });
} else if (carsFound.length > 1) {
// Multiple VINS found
if (!this.isZipServiceable) {
return;
}
// If multiple cars were found and one and only one of them matches the carId entered, save the vehicle info
// so we can go to the Heritage Funnel directly
const matchingCars = carsFound.filter(vin => vin.vehicle.carId === this.$store.getters.vehicle.carId);
@ -242,11 +258,27 @@ export default {
if (matchingCars.length === 1) {
vehicleInfoToCommit = Object.assign(matchingCars[0].vehicle, {vin: matchingCars[0].vin});
}
} else {
} else {
// No VINS found.
console.log("no vins");
this.displayVinNotFoundAlert = true;
return this.$refs.funnelFooter.removeLoader();
}
// If the either the registration zip code or service zip code are not serviceable
this.isZipServiceable = resultMap.serviceZipValidationResponse.isServiceable;
if (!this.isZipServiceable) {
this.displayNonServiceableZipAlert = true;
this.showServiceZipField = true;
return this.$refs.funnelFooter.removeLoader();
}
// If the registration zip code is serviceable and nothing was entered for the service zip code
// then set the service zip code to the registration zip code
if (!this.serviceZipCode) {
this.serviceZipCode = this.customerQuestions.addressQuestions.zipCode;
}
// Save vehicle, customer, service and registration information
@ -272,6 +304,7 @@ export default {
}, false);
return await this.navigateForward(carsFound);
},
async navigateForward(carsFound) {
// Match vehicles found to vehicles in state.
@ -279,7 +312,6 @@ export default {
// If a different vehicle is found than the one entered and the selected glass is not available for that vehicle then navigate back to "vehicle-damage"
// display vehicle changed alert on that page.
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle && matchingCars.length === 1) {
this.$router.navigate(this.navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, this.$route, {}, {[routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true});
} else if (matchingCars.length === 1) {
@ -287,12 +319,14 @@ export default {
} else {
this.$router.navigate(this.navigationScenarios.CONTINUING_WITH_MULTIPLE_VEHICLES, this.$route, {}, {}, carsFound);
}
},
resetWarningsAndErrors() {
this.displayVinNotFoundAlert = false;
this.displayNonServiceableZipAlert = false;
this.displayMatchedDifferentVehicleAlert = false;
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
},
},
mounted() {

View file

@ -312,7 +312,7 @@ describe("license-plate-lookup.vue", () => {
//Act
await wrapper.setData({
registrationZip: "55555"
registrationZipCode: "55555"
})
wrapper.vm.getCmsContent = jest.fn();
await wrapper.vm.$nextTick();
@ -328,7 +328,7 @@ describe("license-plate-lookup.vue", () => {
//Act
await wrapper.setData({
serviceZip: "55555"
serviceZipCode: "55555"
})
wrapper.vm.getCmsContent = jest.fn();
await wrapper.vm.$nextTick();
@ -344,9 +344,17 @@ describe("license-plate-lookup.vue", () => {
const { wrapper } = setupMocks({});
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => "");
await wrapper.setData({ registrationZip: "00000" });
await wrapper.setData({ registrationZipCode: "00000" });
navigateToHeritage.navigateToHeritageFunnel = jest.fn();
wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => Promise.resolve({
data: {
vehicle: {
carId: "C00000"
}
}
}));
// Act
await wrapper.vm.forwardButtonAction();
@ -366,11 +374,19 @@ describe("license-plate-lookup.vue", () => {
await wrapper.setData({ registrationZip: "00000" });
navigateToHeritage.navigateToHeritageFunnel = jest.fn();
wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => Promise.resolve({
data: {
vehicle: {
carId: "C00000"
}
}
}));
// Act
await wrapper.vm.forwardButtonAction();
// Assert
const serviceZipField = wrapper.findComponent("[cmsWidgetName='ServiceZip']");
const serviceZipField = wrapper.findComponent("[cmsWidgetName='ServiceZipQuestionWidget']");
expect(serviceZipField.exists()).toBe(true);
expect(serviceZipField.isVisible()).toBe(true);
})
@ -382,8 +398,17 @@ describe("license-plate-lookup.vue", () => {
return { data: { isServiceable: false, state: "XX" } };
});
await wrapper.setData({ registrationZip: "00000" });
await wrapper.setData({ registrationZipCode: "00000" });
navigateToHeritage.navigateToHeritageFunnel = jest.fn();
wrapper.vm.dispatchStoreAction = jest.fn().mockImplementation(() => Promise.resolve({
data: {
vehicle: {
carId: "C00000"
}
}
}));
await wrapper.vm.forwardButtonAction();
wrapper.vm.$router.navigate = jest.fn();
// At this point, serviceZip field is shown
@ -393,7 +418,7 @@ describe("license-plate-lookup.vue", () => {
await wrapper.vm.forwardButtonAction();
// Assert
const serviceZipField = wrapper.findComponent("[cmsWidgetName='ServiceZip']");
const serviceZipField = wrapper.findComponent("[cmsWidgetName='ServiceZipQuestionWidget']");
expect(serviceZipField.exists()).toBe(true);
expect(serviceZipField.isVisible()).toBe(true); 3
expect(navigateToHeritage.navigateToHeritageFunnel).not.toHaveBeenCalled();
@ -415,11 +440,11 @@ describe("license-plate-lookup.vue", () => {
}
}));
await wrapper.setData({ registrationZip: registrationZip });
await wrapper.setData({ registrationZipCode: registrationZip });
await wrapper.vm.forwardButtonAction();
// At this point, serviceZip field is shown
await wrapper.setData({ serviceZip: serviceZip });
await wrapper.setData({ serviceZipCode: serviceZip });
// Act
@ -427,7 +452,7 @@ describe("license-plate-lookup.vue", () => {
await wrapper.vm.forwardButtonAction();
// Assert
const serviceZipField = wrapper.findComponent("[cmsWidgetName='ServiceZip']");
const serviceZipField = wrapper.findComponent("[cmsWidgetName='ServiceZipQuestionWidget']");
expect(serviceZipField.exists()).toBe(true);
expect(serviceZipField.isVisible()).toBe(true);
});
@ -447,7 +472,7 @@ describe("license-plate-lookup.vue", () => {
}
}));
await wrapper.setData({ registrationZip: registrationZip });
await wrapper.setData({ registrationZipCode: registrationZip });
await wrapper.vm.forwardButtonAction();
// At this point, serviceZip field is shown
@ -512,6 +537,7 @@ function setupMocks({
},
},
serviceZipValidationResponse: {
isValid: true,
isServiceable: isServiceable
},
registrationZipValidationResponse: {

View file

@ -17,7 +17,7 @@
<div class="row my-2">
<div class="col">
<textboxQuestion
cmsWidgetName="LicensePlateNumber"
cmsWidgetName="LicensePlateNumberQuestionWidget"
v-model="licensePlate"
isRequired
inputId="license_plate"
@ -28,8 +28,8 @@
<div class="row my-2">
<div class="col">
<textboxQuestion
cmsWidgetName="RegistrationZip"
v-model="registrationZip"
cmsWidgetName="RegistrationZipQuestionWidget"
v-model="registrationZipCode"
inputId="zip"
mask="#####"
validationRules="zip-required|zip-format"
@ -39,43 +39,54 @@
<div class="row my-2">
<div class="col">
<textboxQuestion
cmsWidgetName="EmailAddress"
cmsWidgetName="EmailAddressQuestionWidget"
v-model="email"
inputId="email"
validationRules="email-address-required|email-address-format"
/>
</div>
</div>
<alert
v-if="displayInvalidZipAlert"
class="my-3"
cmsWidgetName="AlertInvalidZipWidget"
alertClass="alert-danger"
v-bind:isDismissible="false"
/>
<alert
v-if="displayNonServiceableZipAlert"
class="my-3"
:manualHeadline="NoServiceZipHeader"
:manualCopy="NoServiceZipBody"
v-if="!isRegistrationZipServiceable && isVinValid && !isCarIdDifferent"
:manualHeadline="AlertNonServiceableZipHeader"
:manualCopy="AlertNonServiceableZipBody"
alertClass="alert-danger"
v-bind:isDismissible="false"
/>
<div class="row my-2">
<div class="col">
<textboxQuestion
v-if="!isRegistrationZipServiceable"
cmsWidgetName="ServiceZip"
v-model="serviceZip"
inputId="serviceZip"
v-if="showServiceZipField"
cmsWidgetName="ServiceZipQuestionWidget"
v-model="serviceZipCode"
inputId="serviceZipCode"
validationRules="zip-required|zip-format"
mask="#####"
/>
</div>
</div>
<alert
v-if="displayVinNotFoundAlert"
class="my-3"
cmsWidgetName="NoMatchAlertWidget"
v-if="!isVinValid"
cmsWidgetName="AlertVinNotFoundWidget"
alertClass="alert-warning"
v-bind:isDismissible="false"
/>
<alert
v-if="displayMatchedDifferentVehicleAlert"
class="my-3"
:manualHeadline="MatchedDifferentVehicleAlertHeader"
:manualCopy="MatchedDifferentVehicleAlertBody"
v-if="isCarIdDifferent"
:manualHeadline="AlertMatchedDifferentVehicleHeader"
:manualCopy="AlertMatchedDifferentVehicleBody"
alertClass="alert-warning"
v-bind:isDismissible="false"
/>
<funnelFooter
ref="funnelFooter"
@ -104,35 +115,20 @@ import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import { storeActions } from "@/constants/store-actions";
import { errorMessages } from "@/constants/error-messages";
import { getDamageString,isGlassAvailableForCarId} from "@/helpers/damage-helper";
import { getDamageString, isGlassAvailableForCarId } from "@/helpers/damage-helper";
import { routerParams } from "@/router/router-constants/router-params";
import { required, regex } from "@/helpers/validation-rules";
import { Form, defineRule } from "vee-validate";
import vinPagesMixin from "@/mixins/vin-pages-mixin";
import store from "@/store";
import vinPagesMixin from "@/mixins/vin-pages-mixin";
// DEFINE VALIDATION RULES
defineRule(
"license-plate-required",
required(errorMessages.LICENSE_PLATE_REQUIRED)
);
defineRule("license-plate-required", required(errorMessages.LICENSE_PLATE_REQUIRED));
defineRule("zip-required", required(errorMessages.REGISTRATION_ZIP_REQUIRED));
defineRule(
"zip-format",
regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT)
);
defineRule(
"email-address-required",
required(errorMessages.EMAIL_ADDRESS_REQUIRED)
);
defineRule(
"email-address-format",
regex(
/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]{2,})$/,
errorMessages.EMAIL_ADDRESS_FORMAT
)
);
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-address-format", regex(/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]{2,})$/, errorMessages.EMAIL_ADDRESS_FORMAT));
export default {
name: "license-plate-lookup",
@ -146,8 +142,8 @@ export default {
{
resultKey: "cmsContent",
promise: cmsContentPromise,
},
];
}, ];
const resultMap = await settleAllPromises(promiseResultMap);
// Call the "next" function to complete the transition to this page.
next((vm) => {
@ -159,46 +155,33 @@ export default {
},
data() {
return {
isRegistrationZipServiceable: true,
isVinValid: true,
isCarIdDifferent: false,
licensePlate: this.getLicensePlateFromStore(),
registrationZip: this.getRegistrationZipFromStore(),
email: this.getEmailFromStore(),
serviceZip: this.getServiceZipFromStore(),
registrationZipCode: this.getRegistrationZipFromStore(),
email: this.getEmailFromStore(),
serviceZipCode: this.getServiceZipFromStore(),
displayNonServiceableZipAlert: false,
displayVinNotFoundAlert: false,
displayMatchedDifferentVehicleAlert: false,
previouslyEnteredCarId: "",
isSelectedGlassAvailableForVehicle: false,
isCarIdDifferent: false,
customAlertData: {},
isSelectedGlassAvailableForVehicle: true,
zipToDisplay: this.getRegistrationZipFromStore(),
displayInvalidZipAlert: false,
showServiceZipField: this.getServiceZipFromStore(),
isZipServiceable: false,
};
},
mounted() {
this.attachCustomEvents();
},
computed: {
MatchedDifferentVehicleAlertHeader() {
return this.getCmsContent("MatchedDifferentVehicleAlertWidget","HeadlineText").replaceAll("{custom:damage}", getDamageString());
},
MatchedDifferentVehicleAlertBody() {
return this.getCmsContent("MatchedDifferentVehicleAlertWidget","BodyText")
.replaceAll("{custom:damage}", getDamageString())
.replaceAll("{custom:plateLookupYear}",this.customAlertData?.vehicleInfo?.year)
.replaceAll("{custom:plateLookupMake}",this.customAlertData?.vehicleInfo?.make)
.replaceAll("{custom:plateLookupModel}",this.customAlertData?.vehicleInfo?.model);
},
NoServiceZipHeader() {
return this.getCmsContent("NoServiceZipWidget","HeadlineText")
.replaceAll("{custom:zip}", this.zipToDisplay);
},
NoServiceZipBody() {
return this.getCmsContent("NoServiceZipWidget", "BodyText");
},
},
methods: {
arePagePrerequisitesValid() {
return store.getters.vehicle.carId !== null;
},
backButtonAction() {
// route to move backwards
this.$router.navigate(
this.navigationScenarios.CLICKED_BACK,
this.$route
);
},
attachCustomEvents() {
this.prependActionToMethod(this, this.forwardButtonAction, () => {
this.pushEventToGA(
@ -221,11 +204,10 @@ export default {
getServiceZipFromStore() {
return this.$store.getters.order.serviceLocation.zipCode;
},
backButtonAction() {
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
},
async forwardButtonAction() {
const registrationZipValidationResponse = this.dispatchStoreAction(storeActions.VALIDATE_ZIP, {zip: this.registrationZip });
this.resetWarningsAndErrors();
const registrationZipValidationResponse = this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { zip: this.registrationZipCode });
// Settle promises and get results
const promiseResultMap = [
@ -235,73 +217,121 @@ export default {
},
{
resultKey: "serviceZipValidationResponse",
promise: this.serviceZip ? this.dispatchStoreAction(storeActions.VALIDATE_ZIP, {zip: this.serviceZip }) : registrationZipValidationResponse,
promise: this.serviceZipCode ? this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { zip: this.serviceZipCode }) : registrationZipValidationResponse,
}
];
const resultMap = await settleAllPromises(promiseResultMap);
// Lookup vin
const vinLookup = await this.dispatchStoreAction(storeActions.LOOKUP_VIN_BY_PLATE, {licensePlate: this.licensePlate, licenseState: resultMap.registrationZipValidationResponse.state}, false)
.catch(() => {
// No VIN found.
this.displayVinNotFoundAlert = true;
return this.$refs.funnelFooter.removeLoader();
//Handle service zip validations
if (!resultMap.serviceZipValidationResponse.isServiceable) {
this.isVinValid = true;
this.isRegistrationZipServiceable = false;
this.isCarIdDifferent = false;
this.zipToDisplay = this.serviceZip ? this.serviceZip : this.registrationZip;
return this.$refs.funnelFooter.removeLoader();
}
if (!this.serviceZip) {
this.serviceZip = this.registrationZip;
});
// If no VIN was found, stop processing after displaying alert
if (!vinLookup) {
return;
}
//Lookup vin
const vinLookup = await this.dispatchStoreAction(storeActions.LOOKUP_VIN_BY_PLATE, {licensePlate: this.licensePlate, licenseState: resultMap.registrationZipValidationResponse.state}, false)
.catch(() => {
this.isVinValid = false;
this.isCarIdDifferent = false;
// If a Service Zip is entered and it is an invalid zip code (ex. 11111) then show an alert
const isZipValid = resultMap.serviceZipValidationResponse.isValid;
if (this.serviceZipCode && !isZipValid) {
this.displayInvalidZipAlert = true;
return this.$refs.funnelFooter.removeLoader();
});
}
this.displayInvalidZipAlert = false;
// Check if the CarId has changed.
this.isCarIdDifferent = vinLookup.data.vehicle.carId !== this.$store.getters.vehicle.carId;
//Handle changing car
// Handle changing car
if (this.isCarIdDifferent && vinLookup.data.vehicle.carId !== this.previouslyEnteredCarId) {
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.vehicle.carId);
this.$refs.funnelFooter.updateButtonText(`Continue with ${vinLookup.data.vehicle.year} ${vinLookup.data.vehicle.make} ${vinLookup.data.vehicle.model}`);
// Display Alert
this.previouslyEnteredCarId = vinLookup.data.vehicle.carId;
this.customAlertData.vehicleInfo = vinLookup.data.vehicle;
this.isVinValid = true;
this.displayMatchedDifferentVehicleAlert = true;
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.vehicle.carId);
// Update button "Continue with..."
this.$refs.funnelFooter.updateButtonText(`Continue with ${vinLookup.data.vehicle.year} ${vinLookup.data.vehicle.make} ${vinLookup.data.vehicle.model}`);
return this.$refs.funnelFooter.removeLoader();
}
// If the either the registration zip code or service zip code are not serviceable
this.isZipServiceable = resultMap.serviceZipValidationResponse.isServiceable;
if (!this.isZipServiceable) {
this.displayNonServiceableZipAlert = true;
this.showServiceZipField = true;
return this.$refs.funnelFooter.removeLoader();
}
// Save vin, vehicle, customer, service and registration information
await this.dispatchStoreAction(storeActions.SAVE_REGISTRATION_LICENSE_PLATE_LOOKUP, {
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
vehicleInfo: Object.assign(vinLookup.data.vehicle, { vin: vinLookup.data.vin }),
registrationInfo: {
licensePlate: this.licensePlate,
state: resultMap.registrationZipValidationResponse.state,
zipCode: this.registrationZip,
}
}, false);
// If the registration zip code is serviceable and nothing was entered for the service zip code
// then set the service zip code to the registration zip code
if (!this.serviceZipCode) {
this.serviceZipCode = this.registrationZipCode;
}
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.email, false);
await this.dispatchStoreAction(storeActions.SAVE_SERVICE_LOCATION, {
zipCode: this.serviceZip,
state: resultMap.serviceZipValidationResponse.state,
}, false);
// Save vin, vehicle, customer, service and registration information
await this.dispatchStoreAction(storeActions.SAVE_REGISTRATION_LICENSE_PLATE_LOOKUP, {
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
vehicleInfo: Object.assign(vinLookup.data.vehicle, { vin: vinLookup.data.vin }),
registrationInfo: {
licensePlate: this.licensePlate,
state: resultMap.registrationZipValidationResponse.state,
zipCode: this.registrationZipCode,
}
}, false);
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.email, false);
await this.dispatchStoreAction(storeActions.SAVE_SERVICE_LOCATION, {
zipCode: this.serviceZipCode,
state: resultMap.serviceZipValidationResponse.state,
}, false);
return await this.navigateForward();
},
async navigateForward() {
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD,this.$route,{}, {[routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true });
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route, {}, { [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true });
} else {
await this.navigateForwardWithSingleCarMatch();
}
},
resetWarningsAndErrors() {
this.displayVinNotFoundAlert = false;
this.displayNonServiceableZipAlert = false;
this.displayMatchedDifferentVehicleAlert = false;
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
},
},
mounted() {
this.attachCustomEvents();
},
computed: {
AlertNonServiceableZipHeader() {
const zipCode = this.serviceZipCode ? this.serviceZipCode : this.registrationZipCode;
return this.getCmsContent("AlertNonServiceableZipWidget", "HeadlineText").replaceAll("{custom:serviceZip}", zipCode);
},
AlertNonServiceableZipBody() {
return this.getCmsContent("AlertNonServiceableZipWidget", "BodyText");
},
AlertMatchedDifferentVehicleHeader() {
return this.getCmsContent("AlertMatchedDifferentVehicleWidget", "HeadlineText").replaceAll("{custom:damage}", getDamageString());
},
AlertMatchedDifferentVehicleBody() {
return this.getCmsContent("AlertMatchedDifferentVehicleWidget", "BodyText")
.replaceAll("{custom:damage}", getDamageString())
.replaceAll("{custom:plateLookupYear}", this.customAlertData?.vehicleInfo?.year)
.replaceAll("{custom:plateLookupMake}", this.customAlertData?.vehicleInfo?.make)
.replaceAll("{custom:plateLookupModel}", this.customAlertData?.vehicleInfo?.model);
},
},
watch: {
@ -310,26 +340,28 @@ export default {
this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")
);
},
registrationZip() {
registrationZipCode() {
this.$refs.funnelFooter.updateButtonText(
this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")
);
},
serviceZip() {
serviceZipCode() {
// If they modify the service zip code, then hide the error message.
this.displayNonServiceableZipAlert = false;
this.$refs.funnelFooter.updateButtonText(
this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")
);
},
},
components: {
Form,
funnelHeader,
funnelFooter,
vehicleBanner,
funnelSubHeader,
textboxQuestion,
alert,
funnelFooter,
loadingModal,
alert,
loadingModal,
Form
},
};
</script>

View file

@ -224,7 +224,8 @@ function setupMocks({ customMountOptions }) {
function mockOutPromises(carId = 'C00000') {
const apiResponses = {
validateZipResponse: {
serviceZipValidationResponse: {
isValid: true,
isServiceable: true
},
vehicleLookupResponse: {

View file

@ -6,18 +6,15 @@
v-slot="{ meta }"
>
<div class="page-container-grouped-styles">
<loadingModal ref="loadingModal"/>
<loadingModal ref="loadingModal" />
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
<vehicleBanner
cmsWidgetName="VehicleBannerWidget"
:displayGenericVehicleImage="false"
/>
<vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage="false" />
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
<div class="fade-on-route-transition sub-container make-tall">
<div class="row mt-2">
<div class="col">
<textboxQuestion
cmsWidgetName="VinNumber"
cmsWidgetName="VinNumberQuestionWidget"
v-model="vin"
inputId="vin"
isRequired
@ -37,9 +34,9 @@
<div class="row my-2">
<div class="col">
<textboxQuestion
cmsWidgetName="ServiceZIP"
v-model="zip"
inputId="zip"
cmsWidgetName="ServiceZipQuestionWidget"
v-model="serviceZipCode"
inputId="serviceZipCode"
mask="#####"
isRequired
disableAutoFill
@ -50,50 +47,57 @@
<div class="row my-2">
<div class="col">
<textboxQuestion
cmsWidgetName="EmailAddress"
v-model="email"
inputId="email"
cmsWidgetName="EmailAddressQuestionWidget"
v-model="emailAddress"
inputId="emailAddress"
isRequired
disableAutoFill
validationRules="email-address-required|email-address-format"
/>
</div>
</div>
<alert ref="alertInvalidZip"
v-if="displayInvalidZipAlert"
class="my-4"
cmsWidgetName="AlertInvalidZipWidget"
alertClass="alert-danger"
v-bind:isDismissible="false"
/>
<alert
class="my-4"
:manualHeadline="PerfectMatchInsuranceVerifiedAlertHeader"
:manualCopy="PerfectMatchInsuranceVerifiedAlertBody"
:manualHeadline="AlertPerfectMatchInsuranceVerifiedHeader"
:manualCopy="AlertPerfectMatchInsuranceVerifiedBody"
v-model="customAlertData"
v-if="vinPopulatedOnPageLoad && isInsuranceVerified"
alertClass="alert-success"
/>
<alert
class="my-4"
:manualHeadline="MatchedDifferentVehicleAlertHeader"
:manualCopy="MatchedDifferentVehicleAlertBody"
:manualHeadline="AlertMatchedDifferentVehicleHeader"
:manualCopy="AlertMatchedDifferentVehicleBody"
v-model="customAlertData"
v-if="isCarIdDifferent && !vinNotFound && !perfectMatchNewVinAlert"
v-if="displayMatchedDifferentVehicleAlert"
alertClass="alert-warning"
/>
<alert
class="my-4"
:manualHeadline="NoServiceZipHeader"
:manualCopy="NoServiceZipBody"
:manualHeadline="AlertNonServiceableZipHeader"
:manualCopy="AlertNonServiceableZipBody"
v-model="customAlertData"
v-if="noServiceZip"
v-if="displayNonServiceableZipAlert"
alertClass="alert-danger"
/>
<alert
class="my-4"
v-model="customAlertData"
v-if="vinNotFound"
v-if="displayVinNotFoundAlert"
alertClass="alert-danger"
cmsWidgetName="VinNotFound"
cmsWidgetName="AlertVinNotFoundWidget"
/>
<alert
class="my-4"
:manualHeadline="PerfectMatchInsuranceNotVerifiedAlertHeader"
:manualCopy="PerfectMatchInsuranceNotVerifiedAlertBody"
:manualHeadline="AlertPerfectMatchInsuranceNotVerifiedHeader"
:manualCopy="AlertPerfectMatchInsuranceNotVerifiedBody"
v-model="customAlertData"
v-if="vinPopulatedOnPageLoad && !isInsuranceVerified"
alertClass="alert-success"
@ -167,79 +171,20 @@ export default {
},
data() {
return {
isCarIdDifferent: false,
noServiceZip: false,
vinNotFound: false,
vin: this.getVinFromStore(),
zip: this.getZipFromStore(),
email: this.getEmailFromStore(),
serviceZipCode: this.getZipFromStore(),
emailAddress: this.getEmailFromStore(),
isCarIdDifferent: false,
customAlertData: {},
previouslyEnteredCarId: '',
invalidZip: '',
vinPopulatedOnPageLoad: this.getVinFromStore()?.length > 0,
isSelectedGlassAvailableForVehicle: true
isSelectedGlassAvailableForVehicle: false,
displayInvalidZipAlert: false,
displayNonServiceableZipAlert: false,
displayVinNotFoundAlert: false,
displayMatchedDifferentVehicleAlert: false,
};
},
mounted() {
this.attachCustomEvents();
},
watch: {
vin() {
this.vinNotFound = false;
this.$refs.funnelFooter.updateButtonText(this.getCmsContent("FunnelFooterWidget", "ForwardButtonText"));
},
zip() {
this.noServiceZip = false;
},
},
computed: {
MatchedDifferentVehicleAlertHeader(){
const text = this.getCmsContent("MatchedDifferentVehicle",
"HeadlineText").replaceAll("{custom:damage}", getDamageString());
return text;
},
MatchedDifferentVehicleAlertBody(){
const text = this.getCmsContent("MatchedDifferentVehicle",
"BodyText").replaceAll("{custom:damage}", getDamageString()).replaceAll("{custom:vinlookupYear}", this.customAlertData?.vehicleInfo?.year).replaceAll("{custom:vinlookupMake}", this.customAlertData?.vehicleInfo?.make).replaceAll("{custom:vinlookupModel}",
this.customAlertData?.vehicleInfo?.model);
return text;
},
NoServiceZipHeader(){
const text = this.getCmsContent("NoServiceZipWidget", "HeadlineText").replaceAll("{custom:serviceZip}", this.invalidZip);
return text;
},
NoServiceZipBody(){
return this.getCmsContent("NoServiceZipWidget", "BodyText");
},
PerfectMatchInsuranceNotVerifiedAlertHeader() {
return this.getCmsContent("PerfectMatchInsuranceNotVerifiedAlert", "HeadlineText");
},
PerfectMatchInsuranceNotVerifiedAlertBody() {
return this.getCmsContent("PerfectMatchInsuranceNotVerifiedAlert", "BodyText").replaceAll("{custom:damage}",
getDamageString())
},
PerfectMatchInsuranceVerifiedAlertHeader () {
return this.getCmsContent("PerfectMatchInsuranceVerifiedAlert", "HeadlineText");
},
PerfectMatchInsuranceVerifiedAlertBody () {
return this.getCmsContent("PerfectMatchInsuranceVerifiedAlert", "BodyText").replaceAll("{custom:damage}",
getIsWindshieldOnly())
},
isInsuranceVerified() {
return store.getters.payment.insuranceCoverage.isVerified || getFunnelCookie().HasDelayedClaimRegistration;
},
vinMask() {
if (this.vinPopulatedOnPageLoad) {
const lastSixChars = this.vin.substring(11, this.vin.length);
return `!X!X!X!X!X!X!X!X!X!X!X${lastSixChars}`;
}
else {
return 'XXXXXXXXXXXXXXXXX';
}
},
},
methods: {
arePagePrerequisitesValid() {
return store.getters.vehicle.carId !== null;
@ -262,11 +207,7 @@ export default {
true
);
});
},
updateIsCarIdDifferent(isVinPerfectMatch){
if (isVinPerfectMatch) {
this.isCarIdDifferent = false;
}
},
backButtonAction() {
if (this.$store.getters.vehicle.vin) {
@ -275,18 +216,19 @@ export default {
else {
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
}
},
async forwardButtonAction() {
// If this is a new VIN Lookup, do both a Vehicle Lookup and a Zip Validation
if (!this.vinPopulatedOnPageLoad) {
const validateZipResponse = this.dispatchStoreAction(storeActions.VALIDATE_ZIP, {zip: this.zip});
const serviceZipValidationResponse = this.dispatchStoreAction(storeActions.VALIDATE_ZIP, { zip: this.serviceZipCode });
const vehicleLookupResponse = this.dispatchStoreAction(storeActions.LOOKUP_VEHICLE_BY_VIN, { vin: this.vin });
// Settle promises and get results
const promiseResultMap = [
{
resultKey: "validateZipResponse",
promise: validateZipResponse,
resultKey: "serviceZipValidationResponse",
promise: serviceZipValidationResponse,
},
{
resultKey: "vehicleLookupResponse",
@ -295,38 +237,46 @@ export default {
];
const resultMap = await settleAllPromises(promiseResultMap);
// If a Service Zip is entered and it is an invalid zip code (ex. 11111) then show an alert
const isZipValid = resultMap.serviceZipValidationResponse.isValid;
if (this.serviceZipCode && !isZipValid) {
this.displayInvalidZipAlert = true;
return this.$refs.funnelFooter.removeLoader();
}
this.displayInvalidZipAlert = false;
// If either lookup fails, remove the loader and stop processing the page.
if (!resultMap.vehicleLookupResponse || !resultMap.validateZipResponse.isServiceable) {
if (!resultMap.vehicleLookupResponse || !resultMap.serviceZipValidationResponse.isServiceable) {
// If the vehicle result is undefined, the vin entered was invalid.
if(!resultMap.vehicleLookupResponse) {
this.displayVinNotFoundAlert = true;
}
// If the vehicle result is undefined, the vin entered was invalid.
if(!resultMap.vehicleLookupResponse) {
this.vinNotFound = true;
}
// Check if Service Zip entered is serviceable, if not display an alert
if (!resultMap.serviceZipValidationResponse.isServiceable) {
this.displayNonServiceableZipAlert = true;
}
// Check if Service Zip entered is serviceable, if not display an alert
if (!resultMap.validateZipResponse.isServiceable) {
this.setupUiForNonServiceableZip(this.zip);
}
// Remove loader and stop processing the page.
return this.$refs.funnelFooter.removeLoader();
// Remove loader and stop processing the page.
return this.$refs.funnelFooter.removeLoader();
}
// Check if the CarId is different from the lookup vs what is in state currently.
this.isCarIdDifferent = resultMap.vehicleLookupResponse.carId !== this.$store.getters.vehicle.carId;
if (this.isCarIdDifferent && (resultMap.vehicleLookupResponse.carId !== this.previouslyEnteredCarId)) {
this.previouslyEnteredCarId = resultMap.vehicleLookupResponse.carId;
this.customAlertData.vehicleInfo = resultMap.vehicleLookupResponse;
this.$refs.funnelFooter.updateButtonText(`Continue with ${resultMap.vehicleLookupResponse.year} ${resultMap.vehicleLookupResponse.make} ${resultMap.vehicleLookupResponse.model}`);
this.displayMatchedDifferentVehicleAlert = true;
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(resultMap.vehicleLookupResponse.carId);
this.noServiceZip = false;
this.isVinValid = true;
// Update button "Continue with..."
this.$refs.funnelFooter.updateButtonText(`Continue with ${resultMap.vehicleLookupResponse.year} ${resultMap.vehicleLookupResponse.make} ${resultMap.vehicleLookupResponse.model}`);
return this.$refs.funnelFooter.removeLoader();
}
// Save vin, vehicle, customer and service information
@ -335,62 +285,113 @@ export default {
vehicleInfo: Object.assign(resultMap.vehicleLookupResponse, { vin: this.vin })
}, false);
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.email, false);
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailAddress, false);
await this.dispatchStoreAction(storeActions.SAVE_SERVICE_LOCATION, {
zipCode: this.zip,
state: resultMap.validateZipResponse.state,
zipCode: this.serviceZipCode,
state: resultMap.serviceZipValidationResponse.state,
}, false);
return await this.navigateForward();
}
// If a VIN has already been found. Validate the Service Zip (in case of changes)
const zipValidationResponse = await this.dispatchStoreAction(storeActions.VALIDATE_ZIP, {zip: this.zip});
const zipValidationResponse = await this.dispatchStoreAction(storeActions.VALIDATE_ZIP, {zip: this.serviceZipCode});
// Check if Service Zip entered is serviceable
if (zipValidationResponse.data.isServiceable) {
// If the Service Zip entered is serviceable then save the Zip Info and Email Address and navigate forward
if (this.$store.getters.order.serviceLocation.zipCode != this.zip) {
if (this.$store.getters.order.serviceLocation.zipCode != this.serviceZipCode) {
await this.dispatchStoreAction(storeActions.SAVE_SERVICE_LOCATION, {
zipCode: this.zip,
zipCode: this.serviceZipCode,
state: zipValidationResponse.data.state
}, false);
}
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.email, false);
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailAddress, false);
return await this.navigateForward();
}
// If the Service Zip is NOT serviceable then show an alert
this.setupUiForNonServiceableZip(this.zip);
this.displayNonServiceableZipAlert = true;
return this.$refs.funnelFooter.removeLoader();
},
async navigateForward(){
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
this.$router.navigate(this.navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, this.$route, {}, { [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true });
} else {
await this.navigateForwardWithSingleCarMatch();
}
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
this.$router.navigate(this.navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, this.$route, {}, { [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true });
} else {
await this.navigateForwardWithSingleCarMatch();
}
},
setupUiForNonServiceableZip(zip) {
this.customAlertData.zip = zip;
this.invalidZip = zip;
this.noServiceZip = true;
},
mounted() {
this.attachCustomEvents();
},
computed: {
AlertMatchedDifferentVehicleHeader(){
return this.getCmsContent("AlertMatchedDifferentVehicleWidget", "HeadlineText").replaceAll("{custom:damage}", getDamageString());
},
AlertMatchedDifferentVehicleBody(){
return this.getCmsContent("AlertMatchedDifferentVehicleWidget",
"BodyText").replaceAll("{custom:damage}", getDamageString()).replaceAll("{custom:vinlookupYear}", this.customAlertData?.vehicleInfo?.year).replaceAll("{custom:vinlookupMake}", this.customAlertData?.vehicleInfo?.make).replaceAll("{custom:vinlookupModel}",
this.customAlertData?.vehicleInfo?.model);
},
AlertNonServiceableZipHeader(){
return this.getCmsContent("AlertNonServiceableZipWidget", "HeadlineText").replaceAll("{custom:serviceZip}", this.serviceZipCode);
},
AlertNonServiceableZipBody(){
return this.getCmsContent("AlertNonServiceableZipWidget", "BodyText");
},
AlertPerfectMatchInsuranceNotVerifiedHeader() {
return this.getCmsContent("AlertPerfectMatchInsuranceNotVerified", "HeadlineText");
},
AlertPerfectMatchInsuranceNotVerifiedBody() {
return this.getCmsContent("AlertPerfectMatchInsuranceNotVerified", "BodyText").replaceAll("{custom:damage}", getDamageString())
},
AlertPerfectMatchInsuranceVerifiedHeader () {
return this.getCmsContent("AlertPerfectMatchInsuranceVerified", "HeadlineText");
},
AlertPerfectMatchInsuranceVerifiedBody () {
return this.getCmsContent("AlertPerfectMatchInsuranceVerified", "BodyText").replaceAll("{custom:damage}",
getIsWindshieldOnly())
},
isInsuranceVerified() {
return store.getters.payment.insuranceCoverage.isVerified || getFunnelCookie().HasDelayedClaimRegistration;
},
vinMask() {
if (this.vinPopulatedOnPageLoad) {
const lastSixChars = this.vin.substring(11, this.vin.length);
return `!X!X!X!X!X!X!X!X!X!X!X${lastSixChars}`;
}
else {
return 'XXXXXXXXXXXXXXXXX';
}
},
},
watch: {
vin() {
this.displayVinNotFoundAlert = false;
this.$refs.funnelFooter.updateButtonText(this.getCmsContent("FunnelFooterWidget", "ForwardButtonText"));
},
serviceZipCode() {
this.displayNonServiceableZipAlert = false;
},
},
components: {
Form,
funnelHeader,
funnelFooter,
vehicleBanner,
funnelSubHeader,
textboxQuestion,
alert,
funnelFooter,
alert,
vinInformation,
loadingModal,
Form,
},
};
</script>