commit
edf758618c
22 changed files with 580 additions and 176 deletions
|
|
@ -17,11 +17,9 @@ module.exports = {
|
|||
"!src/layouts/vin-lookup/vin-lookup.vue",
|
||||
"!src/layouts/vehicle-damage/windshield-damage-type-question/windshield-damage-type-question.vue",
|
||||
"!src/layouts/vehicle-damage/windshield-options/windshield-options.vue",
|
||||
"!src/layouts/address-poc/address-poc.vue",
|
||||
"!src/layouts/nested-radio-poc/nested-radio.vue",
|
||||
"!src/layouts/button-question-examples/**/*.vue",
|
||||
"!src/layouts/part-questions/**/*.vue",
|
||||
"!src/layouts/reveal/**/*.vue",
|
||||
"!src/layouts/estimate/**/*.vue",
|
||||
// REMOVE THESE AFTER WRITING UNIT TESTS
|
||||
"!src/layouts/address-lookup/address-lookup.vue",
|
||||
"!src/layouts/address-lookup/customer-questions/customer-questions.vue",
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@
|
|||
isPrimary
|
||||
:buttonText="buttonText"
|
||||
loaderColor="white"
|
||||
:class="isDisabled && 'form-test-invalid'"
|
||||
:aria-disabled="isDisabled"
|
||||
:isDisabled="isDisabled"
|
||||
:class="isForwardActionDisabled && 'form-test-invalid'"
|
||||
:aria-disabled="isForwardActionDisabled"
|
||||
:isDisabled="isForwardActionDisabled"
|
||||
@click-event="buttonClick"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-auto link-col py-1 text-break">
|
||||
<div v-if="!isBackButtonHidden" class="col-auto link-col py-1 text-break">
|
||||
<textLink
|
||||
linkType="navigation"
|
||||
:text="backLink"
|
||||
|
|
@ -48,8 +48,10 @@ import buttonMain from "@/ux-components/button-main/button-main";
|
|||
export default {
|
||||
name: "funnelFooter",
|
||||
props: {
|
||||
isDisabled: Boolean,
|
||||
isForwardActionDisabled: Boolean,
|
||||
isBackButtonHidden: {type: Boolean, default: false},
|
||||
cmsWidgetName: String,
|
||||
|
||||
},
|
||||
components: {
|
||||
textLink,
|
||||
|
|
|
|||
|
|
@ -1,25 +1,28 @@
|
|||
<template>
|
||||
<div class="textbox-question" :class="(errors.length > 0 || hasError) ? 'has-error' : ''">
|
||||
<div class="textbox-question" :class="[
|
||||
errors.length > 0 ? 'has-error' : '',
|
||||
hasError ? 'has-error' : '',
|
||||
]">
|
||||
<label :for="inputId" :aria-label="questionText" class="form-label" v-html="labelText"></label>
|
||||
<input v-model="value"
|
||||
<input v-model="value"
|
||||
v-maska="mask"
|
||||
:type="type"
|
||||
class="form-control"
|
||||
:ref="inputId"
|
||||
:id="inputId"
|
||||
:type="type"
|
||||
class="form-control"
|
||||
:ref="inputId"
|
||||
:id="inputId"
|
||||
:name="inputId"
|
||||
:placeholder="placeholderText"
|
||||
:aria-disabled="isDisabled"
|
||||
:disabled="isDisabled"
|
||||
:aria-required="isRequired"
|
||||
autocomplete="off"
|
||||
:placeholder="placeholderText"
|
||||
:aria-disabled="isDisabled"
|
||||
:disabled="isDisabled"
|
||||
:aria-required="isRequired"
|
||||
autocomplete="off"
|
||||
:class="[hasIcon ? 'has-icon' : '', iconRight ? 'icon-right' : '']"
|
||||
:validationRules="validationRules"
|
||||
@input="handleChange"
|
||||
@blur="handleBlur" />
|
||||
<div v-show="errorMessage" class="row mt-2 form-test-error">
|
||||
<span role="alert">{{ errorMessage }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -56,7 +59,7 @@ export default {
|
|||
setup(props) {
|
||||
const fieldOptions = {
|
||||
type: "text",
|
||||
value: props.modelValue,
|
||||
value: props.modelValue,
|
||||
};
|
||||
|
||||
const {
|
||||
|
|
@ -64,15 +67,17 @@ export default {
|
|||
handleBlur,
|
||||
handleChange,
|
||||
meta,
|
||||
validate
|
||||
validate,
|
||||
errors,
|
||||
} = useField(props.inputId, props.validationRules, fieldOptions);
|
||||
|
||||
return {
|
||||
return {
|
||||
errorMessage,
|
||||
handleBlur,
|
||||
handleChange,
|
||||
validate,
|
||||
meta,
|
||||
meta,
|
||||
errors,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -86,7 +91,7 @@ export default {
|
|||
set: function(newValue) {
|
||||
this.$emit("update:modelValue", newValue);
|
||||
}
|
||||
},
|
||||
},
|
||||
labelText: {
|
||||
get: function () {
|
||||
let labelText = this.questionText;
|
||||
|
|
@ -98,7 +103,7 @@ export default {
|
|||
|
||||
return labelText;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(newValue) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ const errorMessages = {
|
|||
LAST_NAME_REQUIRED: "Please enter your last name",
|
||||
EMAIL_ADDRESS_REQUIRED: "Please enter your email address",
|
||||
EMAIL_ADDRESS_FORMAT: "Please enter a valid email address",
|
||||
VIN_REQUIRED: "Please enter your VIN",
|
||||
VIN_FORMAT: "Please enter a valid VIN",
|
||||
};
|
||||
|
||||
export { errorMessages };
|
||||
|
||||
export { errorMessages };
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import {getFunnelCookie} from "@/helpers/heritage-integration/cookie-helper.js";
|
||||
import {getFunnelCookie, getDeviceIdValue, getSessionKeyValue} from "@/helpers/heritage-integration/cookie-helper.js";
|
||||
import { removeAllTestCookies, setupCookies } from "@/helpers/unit-test-helper";
|
||||
|
||||
describe("cookies", () => {
|
||||
|
|
@ -100,5 +100,31 @@ describe("cookies", () => {
|
|||
expect(actualCookieValue).toBeNull();
|
||||
});
|
||||
})
|
||||
|
||||
describe("getDeviceIdValue", () => {
|
||||
test("getDeviceIdValue, should return GUID", () => {
|
||||
// Arrange
|
||||
setupCookies({});
|
||||
|
||||
// Act
|
||||
const result = getDeviceIdValue();
|
||||
|
||||
//Assert
|
||||
expect(result).toBe('21b9b94a-ec23-42c1-aaac-e2ae4e4dbffe');
|
||||
|
||||
});
|
||||
|
||||
test("getSessionKeyValue, should return session key int", () => {
|
||||
// Arrange
|
||||
setupCookies({});
|
||||
|
||||
// Act
|
||||
const result = getSessionKeyValue();
|
||||
|
||||
//Assert
|
||||
expect(result).toBe('12345');
|
||||
|
||||
});
|
||||
});
|
||||
})
|
||||
|
||||
|
|
@ -2,55 +2,38 @@ import { queryStrings } from "@/constants/query-strings";
|
|||
import { externalUrls } from "@/router/router-constants/externalUrl-values";
|
||||
import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js";
|
||||
import { saveOrder } from "@/helpers/heritage-integration/order-helper.js";
|
||||
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
||||
import store from "@/store";
|
||||
import router from "@/router";
|
||||
|
||||
/*
|
||||
If the user has visited the funnel before this method will determine the bets place to
|
||||
drop them so they don't start at the beginning again. This method will return 'heritage' if
|
||||
the user has an existing order and they come back in from the Safelite.com CTA.
|
||||
the user has an existing order and they come back in from the Safelite.com CTA.
|
||||
*/
|
||||
export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHeritageOrder = false) {
|
||||
|
||||
// If the user is coming in via the Safelite.Com CTA
|
||||
if (toRoute.query[queryStrings.START_TYPE] === 'fmg') {
|
||||
|
||||
// If they have an existing order, return 'heritage' for the page name.
|
||||
if (existingHeritageOrder) {
|
||||
return 'heritage';
|
||||
}
|
||||
|
||||
return await getLatestPageForRedirection();
|
||||
}
|
||||
|
||||
|
||||
// If this is a non-CTA navigation, determine where to send the user based on page prerequisites.
|
||||
// This also works if a user has a 'fmg' start_type query string but no current order.
|
||||
// That shouldn't happen, but it's possible.
|
||||
const vehicleMakeComponent = (await lazyLoadComponent('vehicle-make')()).default;
|
||||
const vehicleModelComponent = (await lazyLoadComponent('vehicle-model')()).default;
|
||||
const vehicleStyleComponent = (await lazyLoadComponent('vehicle-style')()).default;
|
||||
const vehicleDamageComponent = (await lazyLoadComponent('vehicle-damage')()).default;
|
||||
|
||||
|
||||
if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) {
|
||||
return "vehicle-year";
|
||||
} else if (!vehicleModelComponent.methods.arePagePrerequisitesValid()) {
|
||||
return "vehicle-make";
|
||||
} else if (!vehicleStyleComponent.methods.arePagePrerequisitesValid()) {
|
||||
return "vehicle-model";
|
||||
} else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) {
|
||||
return "vehicle-style";
|
||||
} else if (store.getters.damage.isRepair == null || !store.getters.vehicle.carId) {
|
||||
return 'vehicle-damage'
|
||||
} else {
|
||||
if (store.getters.vehicle.vin) {
|
||||
return 'vehicle-damage';
|
||||
//return "vin-lookup"; (uncomment)
|
||||
} else {
|
||||
return 'vehicle-damage';
|
||||
//return "estimate" (uncomment)
|
||||
}
|
||||
// If navigating to a specific page, and that page is not part of the vin pages.
|
||||
// Return that page, so that it can navigate like normal.
|
||||
if (toRoute.query[queryStrings.FMG_PAGE] !== undefined && !isVinRelatedPage(toRoute)) {
|
||||
return overrideYmmsDirectionIfNeeded(toRoute);
|
||||
}
|
||||
|
||||
// If this is not a direct link to a page using fmgPage, not from Safelite.com CTA or this is a vin related page.
|
||||
// Get the latest page for redirection.
|
||||
const latestPageRoute = await getLatestPageForRedirection();
|
||||
|
||||
return latestPageRoute;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -65,7 +48,81 @@ export async function navigateToHeritageFunnel() {
|
|||
externalUrls.HERITAGE_FUNNEL,
|
||||
{
|
||||
corid: store.getters.order.referralCorrelationId,
|
||||
src: "concept-funnel",
|
||||
src: "concept-funnel"
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Logic for getting the last "valid" page a user visited.
|
||||
*/
|
||||
async function getLatestPageForRedirection() {
|
||||
// If this is a non-CTA navigation, determine where to send the user based on page prerequisites.
|
||||
// This also works if a user has a 'fmg' start_type query string but no current order.
|
||||
// That shouldn't happen, but it's possible.
|
||||
const vehicleMakeComponent = (await lazyLoadComponent('vehicle-make')()).default;
|
||||
const vehicleModelComponent = (await lazyLoadComponent('vehicle-model')()).default;
|
||||
const vehicleStyleComponent = (await lazyLoadComponent('vehicle-style')()).default;
|
||||
const vehicleDamageComponent = (await lazyLoadComponent('vehicle-damage')()).default;
|
||||
|
||||
|
||||
if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) {
|
||||
return fmgPageValues.VEHICLE_YEAR;
|
||||
} else if (!vehicleModelComponent.methods.arePagePrerequisitesValid()) {
|
||||
return fmgPageValues.VEHICLE_MAKE;
|
||||
} else if (!vehicleStyleComponent.methods.arePagePrerequisitesValid()) {
|
||||
return fmgPageValues.VEHICLE_MODEL;
|
||||
} else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) {
|
||||
return fmgPageValues.VEHICLE_STYLE;
|
||||
} else if (store.getters.damage.isRepair == null || !store.getters.vehicle.carId) {
|
||||
return fmgPageValues.VEHICLE_DAMAGE;
|
||||
} else {
|
||||
if (store.getters.vehicle.vin) {
|
||||
return fmgPageValues.VIN_LOOKUP;
|
||||
} else {
|
||||
return fmgPageValues.ESTIMATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Overrides functionality to go to the YMMS pages in certain cases.
|
||||
If this is not one of the cases, it returns the 'to' fmgPage value.
|
||||
*/
|
||||
|
||||
/* istanbul ignore next */
|
||||
function overrideYmmsDirectionIfNeeded(toRoute) {
|
||||
const fmgPageValue = toRoute.query[queryStrings.FMG_PAGE];
|
||||
|
||||
if (store.getters.payment.insuranceCoverage.isVerified) {
|
||||
switch (fmgPageValue) {
|
||||
case fmgPageValues.VEHICLE_YEAR:
|
||||
case fmgPageValues.VEHICLE_MAKE:
|
||||
case fmgPageValues.VEHICLE_MODEL:
|
||||
case fmgPageValues.VEHICLE_STYLE:
|
||||
{
|
||||
return fmgPageValues.VEHICLE_DAMAGE;
|
||||
}
|
||||
default: {
|
||||
return fmgPageValue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return fmgPageValue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Determine if the page is a vin related page.
|
||||
*/
|
||||
|
||||
/* istanbul ignore next */
|
||||
function isVinRelatedPage(toRoute) {
|
||||
const fmgPageValue = toRoute.query[queryStrings.FMG_PAGE];
|
||||
|
||||
return fmgPageValue === fmgPageValues.VIN_LOOKUP ||
|
||||
fmgPageValue === fmgPageValues.LICENSE_PLATE_LOOKUP ||
|
||||
fmgPageValue === fmgPageValues.ADDRESS_LOOKUP ||
|
||||
fmgPageValue === fmgPageValues.ADDRESS_VEHICLES ||
|
||||
fmgPageValue === fmgPageValues.ESTIMATE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,8 +228,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||
|
||||
//Assert
|
||||
//expect(result).toBe('vin-lookup');
|
||||
expect(result).toBe('vehicle-damage');
|
||||
expect(result).toBe('vin-lookup');
|
||||
});
|
||||
|
||||
test("getPageToRouteExistingOrderTo, should return estimate", async () => {
|
||||
|
|
@ -284,8 +283,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||
|
||||
//Assert
|
||||
//expect(result).toBe('estimate');
|
||||
expect(result).toBe('vehicle-damage');
|
||||
expect(result).toBe('estimate');
|
||||
});
|
||||
|
||||
test("getPageToRouteExistingOrderTo, existing order, should return heritage", async () => {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,9 @@ export const cookies = {
|
|||
[cookieNames.FUNNEL_SESSION_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`,
|
||||
"UNIQUE_SESSION_ID": "33756020-b58e-4ec7-b8b8-3f1576719c40",
|
||||
"anotherCookie": "{}",
|
||||
"someOtherCookie": "{}"
|
||||
"someOtherCookie": "{}",
|
||||
"dxdev": "did=21b9b94a-ec23-42c1-aaac-e2ae4e4dbffe",
|
||||
"skey": "12345"
|
||||
};
|
||||
|
||||
export function removeAllTestCookies() {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<customerQuestions ref="customerQuestions" v-model="customerQuestions" />
|
||||
<funnel-footer
|
||||
ref="funnelFooter"
|
||||
:isDisabled="!meta.valid"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
/>
|
||||
</div>
|
||||
</Form>
|
||||
|
|
|
|||
13
src/layouts/estimate/estimate.vue
Normal file
13
src/layouts/estimate/estimate.vue
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<template>
|
||||
<p> Estimate </p>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "estimate",
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
return true;
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
/>
|
||||
<funnel-footer
|
||||
ref="funnelFooter"
|
||||
:isDisabled="!meta.valid"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@back-clicked="backButtonAction"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
<funnelFooter
|
||||
ref="funnelFooter"
|
||||
cmsWidgetName="FunnelFooterWidget"
|
||||
:isDisabled="!meta.valid"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@back-clicked="backButtonAction"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ jest.mock("@/store", () => ({
|
|||
vehicle: {
|
||||
carId: "C00000000",
|
||||
image: "test.jpg",
|
||||
payment: {
|
||||
insuranceCoverage: {
|
||||
isVerified: false
|
||||
}
|
||||
}
|
||||
},
|
||||
eventBusItem: jest.fn(),
|
||||
damage: {
|
||||
|
|
@ -134,6 +139,7 @@ describe("vehicle-damage.vue", () => {
|
|||
store: {
|
||||
getters: {
|
||||
vehicle: {},
|
||||
payment: { insuranceCoverage: { isVerified: false } },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -201,6 +207,7 @@ describe("vehicle-damage.vue", () => {
|
|||
store: {
|
||||
getters: {
|
||||
vehicle: {},
|
||||
payment: { insuranceCoverage: { isVerified: false } },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -291,6 +298,7 @@ describe("vehicle-damage.vue", () => {
|
|||
store: {
|
||||
getters: {
|
||||
vehicle: {},
|
||||
payment: { insuranceCoverage: { isVerified: false } },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -336,6 +344,7 @@ describe("vehicle-damage.vue", () => {
|
|||
store: {
|
||||
getters: {
|
||||
vehicle: {},
|
||||
payment: { insuranceCoverage: { isVerified: false } },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -734,6 +743,7 @@ function setupMocks({
|
|||
store: {
|
||||
getters: {
|
||||
vehicle: {},
|
||||
payment: { insuranceCoverage: { isVerified: false } },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@
|
|||
/>
|
||||
<funnel-footer
|
||||
cmsWidgetName="FunnelFooterWidget"
|
||||
:isDisabled="!meta.valid"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
:isBackButtonHidden=shouldHideBackButton
|
||||
@back-clicked="backButtonAction"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
/>
|
||||
|
|
@ -145,9 +146,11 @@ export default {
|
|||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
resetDependentState() {
|
||||
store.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
||||
},
|
||||
|
||||
backButtonAction() {
|
||||
// route to move backwards
|
||||
this.$router.navigate(
|
||||
|
|
@ -155,6 +158,7 @@ export default {
|
|||
this.$route
|
||||
);
|
||||
},
|
||||
|
||||
getDamageLocationsFromStore() {
|
||||
var glassSelections = [];
|
||||
|
||||
|
|
@ -275,13 +279,20 @@ export default {
|
|||
},
|
||||
|
||||
navigateForward(partsData){
|
||||
// CSR-98 TEMP
|
||||
|
||||
// Temporary easter egg to navigate to heritage funnel.
|
||||
const vehicleYearsToShowHeritageFunnel = [ 2001, 2002, 2010 ];
|
||||
if (vehicleYearsToShowHeritageFunnel.includes(store.getters.vehicle.year)) {
|
||||
navigateToHeritageFunnel();
|
||||
return;
|
||||
}
|
||||
|
||||
// If vin already exists, navigate directly to vin-lookup
|
||||
if(this.$store.getters.vehicle.vin){
|
||||
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_VIN, this.$route);
|
||||
return;
|
||||
}
|
||||
|
||||
//found problem questions
|
||||
if (partsData.data.partsOrQuestions.some(pq => pq.partQuestions != null && pq.partQuestions.length > 0)){
|
||||
this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS, this.$route, {}, {}, partsData.data);
|
||||
|
|
@ -398,6 +409,9 @@ export default {
|
|||
})
|
||||
);
|
||||
},
|
||||
shouldHideBackButton(){
|
||||
return this.$store.getters.payment.insuranceCoverage.isVerified;
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
|
|
|
|||
|
|
@ -1,41 +1,272 @@
|
|||
<template>
|
||||
<div class="container-fluid shadow rounded-3 px-5 position-relative make-tall">
|
||||
<funnelHeader ref="funnelHeader" />
|
||||
<vehicleBanner ref="vehicleBanner" />
|
||||
<funnelSubHeader ref="funnelSubHeader" />
|
||||
<vinInformation
|
||||
class="mb-5"
|
||||
/>
|
||||
<funnel-footer
|
||||
ref="funnelFooter"
|
||||
:isDisabled="!meta.valid"
|
||||
@back-clicked="backButtonAction"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
/>
|
||||
</div>
|
||||
<Form
|
||||
@submit="onSubmit"
|
||||
@invalid-submit="onInvalidSubmit"
|
||||
ref="theForm"
|
||||
v-slot="{ meta }"
|
||||
>
|
||||
<div class="container-fluid shadow rounded-3 p-2 position-relative make-tall px-5">
|
||||
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
|
||||
<vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage="false" />
|
||||
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<textboxQuestion cmsWidgetName="VinNumber" v-model="vin" inputId="vin" disableAutoFill validationRules="vin-required|vin-format" :isDisabled=isVinFieldReadOnly />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<vinInformation />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<textboxQuestion cmsWidgetName="ServiceZIP" v-model="zip" inputId="zip" mask="#####" disableAutoFill validationRules="zip-required" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row my-2">
|
||||
<div class="col">
|
||||
<textboxQuestion cmsWidgetName="EmailAddress" v-model="email" inputId="email" disableAutoFill validationRules="email-address-required|email-address-format" />
|
||||
</div>
|
||||
</div>
|
||||
<alert
|
||||
class="my-3"
|
||||
v-model="customAlertData"
|
||||
v-if="matchedDifferentVehicle"
|
||||
alertClass="alert-danger"
|
||||
cmsWidgetName="MatchedDifferentVehicle"
|
||||
/>
|
||||
<alert
|
||||
class="my-3"
|
||||
v-model="customAlertData"
|
||||
v-if="noMatchAlert"
|
||||
alertClass="alert-warning"
|
||||
cmsWidgetName="NoMatchAlertWidget"
|
||||
/>
|
||||
<alert
|
||||
class="my-3"
|
||||
v-model="customAlertData"
|
||||
v-if="noServiceZip"
|
||||
alertClass="alert-warning"
|
||||
cmsWidgetName="NoServiceZipWidget"
|
||||
/>
|
||||
<alert
|
||||
class="my-3"
|
||||
v-model="customAlertData"
|
||||
v-if="vinFound"
|
||||
alertClass="alert-warning"
|
||||
cmsWidgetName="VinFoundWidget"
|
||||
/>
|
||||
<alert
|
||||
class="my-3"
|
||||
v-model="customAlertData"
|
||||
v-if="vinFoundReadOnly"
|
||||
alertClass="alert-warning"
|
||||
cmsWidgetName="VinFoundReadOnlyWidget"
|
||||
/>
|
||||
<alert
|
||||
class="my-3"
|
||||
v-model="customAlertData"
|
||||
v-if="foundWindshieldAlert"
|
||||
alertClass="alert-warning"
|
||||
cmsWidgetName="FoundWindshieldAlert"
|
||||
/>
|
||||
<alert
|
||||
class="my-3"
|
||||
v-model="customAlertData"
|
||||
v-if="vinNotFound"
|
||||
alertClass="alert-warning"
|
||||
cmsWidgetName="VinNotFound"
|
||||
/>
|
||||
<alert
|
||||
class="my-3"
|
||||
v-model="customAlertData"
|
||||
v-if="perfectMatchNewVinAlert"
|
||||
alertClass="alert-warning"
|
||||
cmsWidgetName="PerfectMatchNewVinAlert"
|
||||
/>
|
||||
<funnelFooter
|
||||
cmsWidgetName="FunnelFooterWidget"
|
||||
ref="funnelFooter"
|
||||
:isDisabled="!meta.valid"
|
||||
@back-clicked="backButtonAction"
|
||||
@ForwardClicked="forwardButtonAction"
|
||||
/>
|
||||
</div>
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Components
|
||||
import funnelHeader from "@/common-components/funnel-header/funnel-header";
|
||||
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
|
||||
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
|
||||
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
|
||||
import alert from "@/ux-components/alert/alert";
|
||||
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
|
||||
import vinInformation from "@/layouts/vin-lookup/vin-information/vin-information";
|
||||
|
||||
// Supporting files
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||
import store from "@/store";
|
||||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
import { storeActions } from "@/constants/store-actions";
|
||||
import { storeMutations } from "@/constants/store-mutations";
|
||||
import { errorMessages } from "@/constants/error-messages";
|
||||
import { required, regex } from "@/helpers/validation-rules";
|
||||
import { Form, defineRule } from "vee-validate";
|
||||
|
||||
// DEFINE VALIDATION RULES
|
||||
defineRule("zip-required", required(errorMessages.ZIP_REQUIRED));
|
||||
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("vin-required", required(errorMessages.VIN_REQUIRED));
|
||||
defineRule("vin-format", regex(/^[A-HJ-NPR-Z0-9]{17}$/, errorMessages.VIN_FORMAT));
|
||||
|
||||
export default {
|
||||
name: "vin-lookup",
|
||||
async beforeRouteEnter(to, from, next) {
|
||||
// Call APIs
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
||||
|
||||
|
||||
// Settle promises and get results
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: "cmsContent",
|
||||
promise: cmsContentPromise,
|
||||
},
|
||||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
||||
// Call the "next" function to complete the transition to this page.
|
||||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
});
|
||||
},
|
||||
props: {
|
||||
validationRules: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
matchedDifferentVehicle: false,
|
||||
noMatchAlert: false,
|
||||
noServiceZip: false,
|
||||
vinFound: false,
|
||||
vinFoundReadOnly: false,
|
||||
foundWindshieldAlert: false,
|
||||
vinNotFound: false,
|
||||
perfectMatchNewVinAlert: false,
|
||||
vin: '',
|
||||
zip: '',
|
||||
email: '',
|
||||
customAlertData: {},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisitesValid() {
|
||||
return store.getters.vehicle.carId !== null;
|
||||
},
|
||||
resetDependentState() {
|
||||
store.commit(storeMutations.UPDATE_REGISTRATION_ADDRESS, null);
|
||||
store.commit(storeMutations.UPDATE_REGISTRATION_CITY, null);
|
||||
store.commit(storeMutations.UPDATE_REGISTRATION_FIRST_NAME, null);
|
||||
store.commit(storeMutations.UPDATE_REGISTRATION_LAST_NAME, null);
|
||||
store.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
||||
},
|
||||
backButtonAction() {
|
||||
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||
},
|
||||
async forwardButtonAction() {
|
||||
const zipValidation = await this.validateZip(this.zip);
|
||||
if (!zipValidation.data.isServiceable) {
|
||||
this.customAlertData.zip = this.zip;
|
||||
this.$refs.funnelFooter.removeLoader();
|
||||
this.noServiceZip = true;
|
||||
return;
|
||||
}
|
||||
const vinLookup = await this.lookupVin(this.vin).catch(() => {
|
||||
this.$refs.funnelFooter.removeLoader();
|
||||
this.noMatchAlert = true;
|
||||
return;
|
||||
});
|
||||
if (vinLookup.data.carId !== store.getters.vehicle.carId) {
|
||||
this.customAlertData.vehicleInfo = vinLookup.data.vehicle;
|
||||
this.$refs.funnelFooter.removeLoader();
|
||||
this.foundWindshieldAlert = true;
|
||||
return;
|
||||
}
|
||||
const carInfo = this.vinDoesNotMatchCarId ? vinLookup.data : store.getters.vehicle;
|
||||
this.updateStore(carInfo)
|
||||
const partsData = await baseMixin.methods.dispatchNonBlockingStoreAction(
|
||||
this.storeActions.GET_PARTS_OR_QUESTIONS,
|
||||
{
|
||||
carId: store.getters.vehicle.carId,
|
||||
glassArray: store.getters.damage.glassToReplace,
|
||||
zipCode: this.zip,
|
||||
vin: vinLookup.vin
|
||||
},
|
||||
false
|
||||
);
|
||||
this.navigateForward(partsData);
|
||||
},
|
||||
navigateForward(partsData){
|
||||
if(partsData.data.partsOrQuestions[0].partQuestions && partsData.data.partsOrQuestions[0].partQuestions.length > 0){
|
||||
this.$router.navigateAfterSave(this.navigationScenarios.CONTINUING_WITH_PARTS_QUESTION, this.$route, {}, {}, partsData.data);
|
||||
return;
|
||||
} else if((!partsData.data.partsOrQuestions[0].partQuestions || partsData.data.partsOrQuestions[0].partQuestions.length < 1) && partsData.data.partsOrQuestions[0].parts.length > 1) {
|
||||
this.$router.navigateAfterSave(this.navigationScenarios.CONTINUING_WITH_MULTIPLE_PARTS, this.$route, {}, {}, partsData.data);
|
||||
return;
|
||||
} else {
|
||||
this.$router.navigate(this.navigationScenarios.CONTINUING_WITH_SINGLE_PART, this.$route);
|
||||
}
|
||||
},
|
||||
validateZip(zip) {
|
||||
return baseMixin.methods.dispatchNonBlockingStoreAction(
|
||||
storeActions.VALIDATE_ZIP,
|
||||
{ zip }
|
||||
);
|
||||
},
|
||||
lookupVin(vin) {
|
||||
return baseMixin.methods.dispatchNonBlockingStoreAction(
|
||||
storeActions.LOOKUP_VEHICLE_BY_VIN,
|
||||
{ vin }
|
||||
);
|
||||
},
|
||||
updateStore(carInfo) {
|
||||
// if(vehicleDamage){
|
||||
// store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||
// }
|
||||
store.commit(storeMutations.UPDATE_VEHICLE_VIN, this.vin);
|
||||
store.commit(storeMutations.UPDATE_YEAR, carInfo.year);
|
||||
store.commit(storeMutations.UPDATE_MAKE, carInfo.make);
|
||||
store.commit(storeMutations.UPDATE_MODEL, carInfo.model);
|
||||
store.commit(storeMutations.UPDATE_STYLE, carInfo.style);
|
||||
store.commit(storeMutations.UPDATE_CAR_ID, carInfo.carId);
|
||||
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, carInfo.category);
|
||||
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, carInfo.imageUrl);
|
||||
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, carInfo.imageVifNumber);
|
||||
store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, carInfo.imageColor);
|
||||
store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP, this.zip);
|
||||
store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, this.email);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isVinFieldReadOnly(){
|
||||
return this.$store.getters.payment.insuranceCoverage.isVerified;
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Form,
|
||||
funnelHeader,
|
||||
vehicleBanner,
|
||||
funnelSubHeader,
|
||||
vinInformation,
|
||||
textboxQuestion,
|
||||
alert,
|
||||
funnelFooter,
|
||||
vinInformation,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import { globalEvents, globalEventTypes } from "@/constants/events";
|
|||
|
||||
// Heritage integration
|
||||
import { isSavedSessionStillActive } from "@/helpers/heritage-integration/session-helper";
|
||||
import { updateOrCreateFunnelCookie,getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||
import { updateOrCreateFunnelCookie, getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||
import { loadOrderIfPresent, saveOrder } from "@/helpers/heritage-integration/order-helper";
|
||||
import { getPageToRouteExistingOrderTo, navigateToHeritageFunnel} from "@/helpers/heritage-integration/navigation-helper";
|
||||
import { getPageToRouteExistingOrderTo, navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||
|
||||
import baseMixin from "@/mixins/base-mixin";
|
||||
import eventBus from "@/helpers/event-bus/event-bus";
|
||||
|
|
@ -35,84 +35,79 @@ const routes = [
|
|||
name: "root",
|
||||
async beforeEnter(to, from, next) {
|
||||
// If we have no query string, or we don't have the FmgPage query string.
|
||||
if (to.query.fmgPage === undefined) {
|
||||
await GoToFunnelStartOn404(next);
|
||||
} else {
|
||||
try {
|
||||
try {
|
||||
|
||||
// If the saved session has timed out, clear the session, execute 404 logic.
|
||||
if (getFunnelCookie() !== null && !isSavedSessionStillActive()) {
|
||||
await GoToFunnelStartOn404(next);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// On entering the funnel "fresh", read cookie information, decide what to do next.
|
||||
if (from.redirectedFrom === undefined) {
|
||||
const loadOrderResponse = await loadOrderIfPresent();
|
||||
const pageToRedirectTo = await getPageToRouteExistingOrderTo(to, loadOrderResponse);
|
||||
|
||||
// If getPageToRouteExistingOrderTo determines that the return user needs to
|
||||
// go back to heritage funnel, send them there and stop our current navigation.
|
||||
if (pageToRedirectTo === 'heritage') {
|
||||
await navigateToHeritageFunnel();
|
||||
return next(false);
|
||||
}
|
||||
|
||||
// Assign our fmgPage so it will load normally like the other pages.
|
||||
to.query.fmgPage = pageToRedirectTo;
|
||||
}
|
||||
|
||||
// Process funnel cookie.
|
||||
updateOrCreateFunnelCookie();
|
||||
|
||||
// If we already have our route, go to it.
|
||||
if (router.hasRoute(to.query.fmgPage)) {
|
||||
// Since our route is already in scope, we can grab the component from it and call the arePagePrerequisitesValid function.
|
||||
let component = router.getRoutes().filter((x) => x.name === to.query.fmgPage)[0].components;
|
||||
|
||||
// If the component hasn't been loaded fully, load it before we check prerequisites.
|
||||
if (component.default.methods === undefined) {
|
||||
component = await component.default();
|
||||
}
|
||||
|
||||
if (!arePagePrerequisitesValid(component)) {
|
||||
await GoToFunnelStartOn404(next);
|
||||
}
|
||||
|
||||
return next({ name: to.query.fmgPage, query: to.query, params: to.params });
|
||||
}
|
||||
|
||||
// Get route info for the given url. Names will have a 1:1 relationship with names in the Cms.
|
||||
const routeData = await GetRouteInfoFromPageName(to.query.fmgPage);
|
||||
|
||||
// Add our dynamic route.
|
||||
router.addRoute({
|
||||
path: routeData[0].path, // Always the same path, because we control it with query strings.
|
||||
name: routeData[0].name,
|
||||
component: routeData[0].component,
|
||||
});
|
||||
|
||||
// Call the next components arePagePrerequisitesValid method before load.
|
||||
// If it returns false, use the 404 logic.
|
||||
const nextComponent = await router.getRoutes().filter((x) => x.name === routeData[0].name)[0].components.default();
|
||||
|
||||
if (!arePagePrerequisitesValid(nextComponent)) {
|
||||
await GoToFunnelStartOn404(next);
|
||||
}
|
||||
|
||||
// Assign current query string parameters, as well as our fmgPage one.
|
||||
next({
|
||||
name: routeData[0].name,
|
||||
query: Object.assign(to.query, { fmgPage: routeData[0].name }),
|
||||
params: to.params
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
// If we don't have a route, go to our 404 page.
|
||||
// If the saved session has timed out, clear the session, execute 404 logic.
|
||||
if (getFunnelCookie() !== null && !isSavedSessionStillActive()) {
|
||||
await GoToFunnelStartOn404(next);
|
||||
}
|
||||
|
||||
// On entering the funnel "fresh", read cookie information, decide what to do next.
|
||||
if (from.redirectedFrom === undefined) {
|
||||
const loadOrderResponse = await loadOrderIfPresent();
|
||||
const pageToRedirectTo = await getPageToRouteExistingOrderTo(to, loadOrderResponse);
|
||||
|
||||
// If getPageToRouteExistingOrderTo determines that the return user needs to
|
||||
// go back to heritage funnel, send them there and stop our current navigation.
|
||||
if (pageToRedirectTo === 'heritage') {
|
||||
await navigateToHeritageFunnel();
|
||||
return next(false);
|
||||
}
|
||||
|
||||
|
||||
// Assign our fmgPage so it will load normally like the other pages.
|
||||
to.query.fmgPage = pageToRedirectTo;
|
||||
}
|
||||
|
||||
// Process funnel cookie.
|
||||
updateOrCreateFunnelCookie();
|
||||
|
||||
// If we already have our route, go to it.
|
||||
if (router.hasRoute(to.query.fmgPage)) {
|
||||
// Since our route is already in scope, we can grab the component from it and call the arePagePrerequisitesValid function.
|
||||
let component = router.getRoutes().filter((x) => x.name === to.query.fmgPage)[0].components;
|
||||
|
||||
// If the component hasn't been loaded fully, load it before we check prerequisites.
|
||||
if (component.default.methods === undefined) {
|
||||
component = await component.default();
|
||||
}
|
||||
|
||||
if (!arePagePrerequisitesValid(component)) {
|
||||
await GoToFunnelStartOn404(next);
|
||||
}
|
||||
|
||||
return next({ name: to.query.fmgPage, query: to.query, params: to.params });
|
||||
}
|
||||
|
||||
// Get route info for the given url. Names will have a 1:1 relationship with names in the Cms.
|
||||
const routeData = await GetRouteInfoFromPageName(to.query.fmgPage);
|
||||
|
||||
// Add our dynamic route.
|
||||
router.addRoute({
|
||||
path: routeData[0].path, // Always the same path, because we control it with query strings.
|
||||
name: routeData[0].name,
|
||||
component: routeData[0].component,
|
||||
});
|
||||
|
||||
// Call the next components arePagePrerequisitesValid method before load.
|
||||
// If it returns false, use the 404 logic.
|
||||
const nextComponent = await router.getRoutes().filter((x) => x.name === routeData[0].name)[0].components.default();
|
||||
|
||||
if (!arePagePrerequisitesValid(nextComponent)) {
|
||||
await GoToFunnelStartOn404(next);
|
||||
}
|
||||
|
||||
// Assign current query string parameters, as well as our fmgPage one.
|
||||
next({
|
||||
name: routeData[0].name,
|
||||
query: Object.assign(to.query, { fmgPage: routeData[0].name }),
|
||||
params: to.params
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
// If we don't have a route, go to our 404 page.
|
||||
await GoToFunnelStartOn404(next);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ const fmgPageValues = {
|
|||
LICENSE_PLATE_LOOKUP: "license-plate-lookup",
|
||||
REVEAL: "reveal",
|
||||
ESTIMATE: "estimate",
|
||||
ADDRESS_VEHICLES: "address-vehicles",
|
||||
};
|
||||
|
||||
export { fmgPageValues };
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ const navigationScenarios = {
|
|||
SELECTED_MAKE: "SELECTED_MAKE",
|
||||
SELECTED_STYLE: "SELECTED_STYLE",
|
||||
CLICKED_BACK: "CLICKED_BACK",
|
||||
CLICKED_BACK_WITH_VIN: "CLICKED_BACK_WITH_VIN",
|
||||
CLICKED_FORWARD: "CLICKED_FORWARD",
|
||||
CLICKED_FORWARD_WITH_VIN: "CLICKED_FORWARD_WITH_VIN",
|
||||
SELECTED_PARTS: "SELECTED_PARTS",
|
||||
SELECTED_DAMAGE_WITH_SINGLE_PART: "SELECTED_DAMAGE_WITH_SINGLE_PART",
|
||||
SELECTED_DAMAGE_WITH_MULTIPLE_PARTS: "SELECTED_DAMAGE_WITH_MULTIPLE_PARTS",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
||||
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
|
||||
import { applicationConfig } from "@/constants/application-config";
|
||||
|
||||
const routingTable = [
|
||||
{
|
||||
|
|
@ -58,9 +57,13 @@ const routingTable = [
|
|||
scenario: navigationScenarios.CLICKED_BACK,
|
||||
destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_VIN,
|
||||
destinationFmgPageValue: fmgPageValues.VIN_LOOKUP,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.SELECTED_DAMAGE_WITH_SINGLE_PART,
|
||||
destinationFmgPageValue: fmgPageValues.REVEAL
|
||||
destinationFmgPageValue: fmgPageValues.VIN_LOOKUP,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.SELECTED_DAMAGE_WITH_MULTIPLE_PARTS,
|
||||
|
|
@ -68,7 +71,7 @@ const routingTable = [
|
|||
},
|
||||
{
|
||||
scenario: navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS,
|
||||
destinationFmgPageValue: fmgPageValues.PART_QUESTIONS,
|
||||
destinationFmgPageValue: fmgPageValues.VIN_LOOKUP,//This might be temporary
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -107,6 +110,10 @@ const routingTable = [
|
|||
maps: [
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_BACK,
|
||||
destinationFmgPageValue: fmgPageValues.REVEAL,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_BACK_WITH_VIN,
|
||||
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,6 +45,12 @@ const getDefaultState = () => {
|
|||
glassParts: null,
|
||||
otherParts: null
|
||||
},
|
||||
payment:{
|
||||
isInsurance: null,
|
||||
insuranceCoverage: {
|
||||
isVerified: null
|
||||
}
|
||||
},
|
||||
referralNumber: null,
|
||||
referralDate: null,
|
||||
referralCorrelationId: null,
|
||||
|
|
@ -120,6 +126,12 @@ export const mutations = {
|
|||
updateParentAcctNumber(state, parentAcctNumber) {
|
||||
state.order.parentAccountNumber = parentAcctNumber;
|
||||
},
|
||||
updateIsInsurance(state, isInsurance) {
|
||||
state.order.payment.isInsurance = isInsurance;
|
||||
},
|
||||
updateInsuranceVerifiedStatus(state, isVerified) {
|
||||
state.order.payment.insuranceCoverage.isVerified = isVerified;
|
||||
},
|
||||
|
||||
|
||||
// EVENT BUS MUTATIONS
|
||||
|
|
@ -176,23 +188,30 @@ export const mutations = {
|
|||
state.order.referralNumber = orderInformation.referralNumber;
|
||||
state.order.referralDate = orderInformation.referralDate;
|
||||
state.order.referralCorrelationId = orderInformation.referralCorrelationId;
|
||||
|
||||
state.order.vehicle = Object.assign(state.order.vehicle, {
|
||||
year: orderInformation.vehicle?.year,
|
||||
make: orderInformation.vehicle?.make,
|
||||
model: orderInformation.vehicle?.model,
|
||||
style: orderInformation.vehicle?.style,
|
||||
vin: orderInformation.vehicle?.vin,
|
||||
carId: orderInformation.vehicle?.carId,
|
||||
category: orderInformation.vehicle?.category,
|
||||
imageUrl: orderInformation.vehicle?.imageUrl,
|
||||
imageVifNumber: orderInformation.vehicle?.imageVifNumber,
|
||||
imageColor: orderInformation.vehicle?.imageVifColor
|
||||
imageColor: orderInformation.vehicle?.imageVifColor,
|
||||
});
|
||||
|
||||
state.order.damage.glassToReplace = orderInformation.glassToReplace;
|
||||
state.order.damage.isRepair = orderInformation.isRepair;
|
||||
state.order.damage.numberOfChips = orderInformation.numberOfChips;
|
||||
|
||||
state.order.lineItems.glassParts = orderInformation.parts;
|
||||
state.order.parentAccountNumber = orderInformation.parentAccountNumber;
|
||||
state.order.serviceLocation.zipCode = orderInformation.zipCode;
|
||||
|
||||
state.order.payment.isInsurance = orderInformation.IsInsuranceOrder;
|
||||
state.order.payment.insuranceCoverage.isVerified = orderInformation?.insuranceInfo.coverageVerified;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -210,11 +229,10 @@ export const getters = {
|
|||
eventBus: (state) => state.applicationUser.eventBus,
|
||||
damage: (state) => state.order.damage,
|
||||
lineItems: (state) => state.order.lineItems,
|
||||
pageData: (state) => (page) => {
|
||||
return state.applicationUser.pageData[page];
|
||||
},
|
||||
pageData: (state) => (page) => { return state.applicationUser.pageData[page]; },
|
||||
applicationUser: (state) => state.applicationUser,
|
||||
order: (state) => state.order,
|
||||
payment: (state) => state.order.payment,
|
||||
}
|
||||
|
||||
// Export Actions
|
||||
|
|
|
|||
|
|
@ -222,6 +222,7 @@ describe("Mutations", () => {
|
|||
numberOfChips: 0,
|
||||
parts: [],
|
||||
parentAccountNumber: "123456789",
|
||||
insuranceInfo: {}
|
||||
});
|
||||
|
||||
// Assert
|
||||
|
|
@ -232,6 +233,17 @@ describe("Mutations", () => {
|
|||
expect(storeState.order.vehicle.model).toEqual("ILX");
|
||||
});
|
||||
|
||||
it("updateInsuranceVerifiedStatus, should set isVerified flag", () => {
|
||||
// Arrange
|
||||
const storeState = state;
|
||||
|
||||
// Act
|
||||
mutations.updateInsuranceVerifiedStatus(storeState, true);
|
||||
|
||||
// Assert
|
||||
expect(storeState.order.payment.insuranceCoverage.isVerified).toEqual(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Actions", () => {
|
||||
|
|
@ -690,4 +702,15 @@ describe("Getters", () => {
|
|||
|
||||
});
|
||||
|
||||
it("Payment getter, should return payment data", () => {
|
||||
// Arrange
|
||||
const storeState = state;
|
||||
|
||||
//Act
|
||||
mutations.updateInsuranceVerifiedStatus(storeState, true );
|
||||
|
||||
//Assert
|
||||
expect(getters.payment(storeState).insuranceCoverage.isVerified).toEqual(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
:class="[isDismissible ? 'alert-dismissible' : '', this.alertClass]"
|
||||
>
|
||||
<p class="m-0 fw-bold small alert-heading">{{ alertHeadline }}</p>
|
||||
<p class="m-0 text-body small" v-html="alertCopy"></p>
|
||||
<p class="m-0 text-body small">{{ alertCopy }}</p>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-close p-2"
|
||||
|
|
|
|||
Loading…
Reference in a new issue