vin-lookup: added 'Invalid Zip' alert' and refactored to make it more similar to address-lookup

This commit is contained in:
Leah Schumann 2022-07-12 08:55:36 -04:00
parent d7e2f1e0cb
commit e452928c77
3 changed files with 294 additions and 270 deletions

View file

@ -24,9 +24,8 @@
<alert ref="alertInvalidZip"
v-if="displayInvalidZipAlert"
class="mb-4"
cmsWidgetName="AlertInvalidZipWidget"
alertClass="alert-danger"
:manualHeadline="AlertInvalidZipHeader"
:manualCopy="AlertInvalidZipBody"
v-bind:isDismissible="false"
/>
<alert ref="alertNonServiceableZip"
@ -70,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));
@ -126,8 +126,10 @@ export default {
displayMatchedDifferentVehicleAlert: false,
displayVinLookupByHomeAddressNotAllowedAlert: false,
previouslyEnteredCarId: "",
isCarIdDifferent: false,
isSelectedGlassAvailableForVehicle: false,
customAlertData: {},
displayInvalidZipAlert: false,
showServiceZipField: this.getServiceZipFromStore(),
isZipServiceable: false,
}
@ -241,6 +243,7 @@ export default {
// Update button "Continue with..."
this.$refs.funnelFooter.updateButtonText(`Continue with ${carFound.year} ${carFound.make} ${carFound.model}`);
return this.$refs.funnelFooter.removeLoader();
}
// update data if the zip or service zip is serviceable
@ -262,7 +265,7 @@ export default {
}
// If the neither the registration zip code or service zip code are not serviceable
// 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;
@ -297,6 +300,7 @@ export default {
}, false);
return await this.navigateForward(carsFound);
},
async navigateForward(carsFound) {
// Match vehicles found to vehicles in state.
@ -304,7 +308,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) {
@ -312,12 +315,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

@ -46,37 +46,46 @@
/>
</div>
</div>
<alert ref="alertInvalidZip" v-if="displayInvalidZipAlert" class="my-3" alertClass="alert-danger" :manualHeadline="AlertInvalidZipHeader" :manualCopy="AlertInvalidZipBody" v-bind:isDismissible="false" />
<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"
v-if="showServiceZipField"
cmsWidgetName="ServiceZip"
v-model="serviceZip"
inputId="serviceZip"
v-model="serviceZipCode"
inputId="serviceZipCode"
validationRules="zip-required|zip-format"
/>
</div>
</div>
<alert
v-if="displayVinNotFoundAlert"
class="my-3"
cmsWidgetName="NoMatchAlertWidget"
v-if="!isVinValid"
cmsWidgetName="NoMatchAlertWidget"
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"
@ -105,35 +114,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",
@ -147,8 +141,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) => {
@ -160,52 +154,33 @@ export default {
},
data() {
return {
isRegistrationZipServiceable: true,
isVinValid: true,
isCarIdDifferent: false,
licensePlate: this.getLicensePlateFromStore(),
registrationZip: this.getRegistrationZipFromStore(),
email: this.getEmailFromStore(),
serviceZip: this.getServiceZipFromStore(),
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,
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);
},
AlertInvalidZipHeader() {
return this.getCmsContent("AlertInvalidZipWidget","HeadlineText");
},
AlertInvalidZipBody() {
return this.getCmsContent("AlertInvalidZipWidget", "BodyText");
},
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(
@ -228,10 +203,9 @@ export default {
getServiceZipFromStore() {
return this.$store.getters.order.serviceLocation.zipCode;
},
backButtonAction() {
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
},
async forwardButtonAction() {
this.resetWarningsAndErrors();
const registrationZipValidationResponse = this.dispatchStoreAction(storeActions.VALIDATE_ZIP, {zip: this.registrationZip });
// Settle promises and get results
@ -242,81 +216,118 @@ 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 VINS found.
this.displayVinNotFoundAlert = true;
return this.$refs.funnelFooter.removeLoader();
});
// 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.serviceZip && !isZipValid) {
if (this.serviceZipCode && !isZipValid) {
this.displayInvalidZipAlert = true;
return this.$refs.funnelFooter.removeLoader();
}
this.displayInvalidZipAlert = false;
// 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;
}
// 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;
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.registrationZip;
}
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.registrationZip,
}
}, 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;
const text = this.getCmsContent("AlertNonServiceableZipWidget", "HeadlineText").replaceAll("{custom:serviceZip}", zipCode);
return text;
},
AlertNonServiceableZipBody() {
return this.getCmsContent("AlertNonServiceableZipWidget", "BodyText");
},
AlertMatchedDifferentVehicleHeader() {
return this.getCmsContent("MatchedDifferentVehicleAlertWidget", "HeadlineText").replaceAll("{custom:damage}", getDamageString());
},
AlertMatchedDifferentVehicleBody() {
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);
},
},
watch: {
@ -330,21 +341,21 @@ export default {
this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")
);
},
serviceZip() {
serviceZipCode() {
this.$refs.funnelFooter.updateButtonText(
this.getCmsContent("FunnelFooterWidget", "ForwardButtonText")
);
},
},
components: {
Form,
funnelHeader,
funnelFooter,
vehicleBanner,
funnelSubHeader,
textboxQuestion,
alert,
funnelFooter,
loadingModal,
alert,
loadingModal,
Form
},
};
</script>

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,37 +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
@ -334,60 +285,117 @@ 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
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(){
const text = this.getCmsContent("AlertMatchedDifferentVehicleWidget",
"HeadlineText").replaceAll("{custom:damage}", getDamageString());
return text;
},
AlertMatchedDifferentVehicleBody(){
const text = 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);
return text;
},
AlertNonServiceableZipHeader(){
const text = this.getCmsContent("AlertNonServiceableZipWidget", "HeadlineText").replaceAll("{custom:serviceZip}", this.serviceZipCode);
return text;
},
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>