Merge branch 'develop' into feature/CASH-48-frontend
This commit is contained in:
commit
7b6a8eeeae
15 changed files with 469 additions and 84 deletions
|
|
@ -27,7 +27,6 @@ module.exports = {
|
||||||
"!src/layouts/insurance/*.vue", // Temp test exclusion while in development
|
"!src/layouts/insurance/*.vue", // Temp test exclusion while in development
|
||||||
"!src/layouts/insurance-company/*.vue", // Temp test exclusion while in development
|
"!src/layouts/insurance-company/*.vue", // Temp test exclusion while in development
|
||||||
"!src/layouts/insurance-company/insurance-company-question/*.vue", // Temp test exclusion while in development
|
"!src/layouts/insurance-company/insurance-company-question/*.vue", // Temp test exclusion while in development
|
||||||
"!src/layouts/return-user/*.vue", // Temp test exclusion while in development
|
|
||||||
// END
|
// END
|
||||||
], // ! means exclude from coverage.
|
], // ! means exclude from coverage.
|
||||||
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ const storeMutations = {
|
||||||
UPDATE_VEHICLE_IMAGE_COLOR: "updateVehicleImageColor",
|
UPDATE_VEHICLE_IMAGE_COLOR: "updateVehicleImageColor",
|
||||||
UPDATE_VEHICLE_VIN: "updateVehicleVin",
|
UPDATE_VEHICLE_VIN: "updateVehicleVin",
|
||||||
UPDATE_VEHICLE: "updateVehicle",
|
UPDATE_VEHICLE: "updateVehicle",
|
||||||
|
UPDATE_VEHICLE_MOBILE_STATIC_RECALIBRATION_APPLICABLE:
|
||||||
|
"updateIsMobileStaticRecalibrationApplicable",
|
||||||
|
|
||||||
UPDATE_IS_REPAIR: "updateIsRepair",
|
UPDATE_IS_REPAIR: "updateIsRepair",
|
||||||
UPDATE_NUMBER_OF_CHIPS: "updateNumberOfChips",
|
UPDATE_NUMBER_OF_CHIPS: "updateNumberOfChips",
|
||||||
|
|
|
||||||
|
|
@ -97,16 +97,16 @@ export default {
|
||||||
document.onkeydown = function (e) {
|
document.onkeydown = function (e) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
// check session expired and initSession to recreate cookies
|
// check session expired and initSession to recreate cookies
|
||||||
if (analyticsMixin.methods.sessionExpired()) {
|
if (analyticsMixin.methods.sessionExpired()) {
|
||||||
this.routeReturnUser();
|
this.routeReturnUser();
|
||||||
} else {
|
} else {
|
||||||
this.$emit("ForwardClicked");
|
this.$emit("ForwardClicked");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
linkClick() {
|
linkClick() {
|
||||||
// check session expired and initSession to recreate cookies
|
// check session expired and initSession to recreate cookies
|
||||||
if (analyticsMixin.methods.sessionExpired()) {
|
if (analyticsMixin.methods.sessionExpired()) {
|
||||||
this.routeReturnUser();
|
this.routeReturnUser();
|
||||||
} else {
|
} else {
|
||||||
this.$emit("BackClicked");
|
this.$emit("BackClicked");
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,17 @@ export function getQuerystringParameter(key) {
|
||||||
|
|
||||||
return lowerCaseParams.get(key) ? lowerCaseParams.get(key) : null;
|
return lowerCaseParams.get(key) ? lowerCaseParams.get(key) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if you add the fmgPage to the querystringobject before calling, then pass true for skipFmgPageName
|
||||||
|
export function buildQuerystringObject(qso, skipFmgPageName=false) {
|
||||||
|
const queryString = window.location.search;
|
||||||
|
const urlParams = new URLSearchParams(queryString);
|
||||||
|
|
||||||
|
for (const [name, value] of urlParams) {
|
||||||
|
if (name.toLowerCase() === "fmgpage" && skipFmgPageName) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
qso[name] = value;
|
||||||
|
}
|
||||||
|
return qso;
|
||||||
|
}
|
||||||
312
src/layouts/return-user/return-user.spec.js
Normal file
312
src/layouts/return-user/return-user.spec.js
Normal file
|
|
@ -0,0 +1,312 @@
|
||||||
|
// Components
|
||||||
|
import returnUser from "@/layouts/return-user/return-user.vue";
|
||||||
|
|
||||||
|
// Supporting Files
|
||||||
|
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
||||||
|
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper";
|
||||||
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
|
import { dispatchStoreAction } from "@/mixins/base-mixin.js";
|
||||||
|
import store from "@/store";
|
||||||
|
import router from "@/router";
|
||||||
|
import navbar from "@/fmg-components/nav-bar/nav-bar";
|
||||||
|
import { Form } from "vee-validate";
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||||
|
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||||
|
import { saveSession } from "@/helpers/heritage-integration/order-helper.js";
|
||||||
|
|
||||||
|
import { experimentSettings } from "../../constants/experiments";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
import buttonMain from "@/ux-components/button-main/button-main";
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
|
||||||
|
// Setup global mocks
|
||||||
|
let mockStoreActionData = {};
|
||||||
|
|
||||||
|
let mockStoreData = {};
|
||||||
|
let mockExperimentSettings = {
|
||||||
|
experiments: [
|
||||||
|
{
|
||||||
|
universeName: "ConceptFunnel",
|
||||||
|
settings: {
|
||||||
|
SuppressVinCapture: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
function resetMockStoreData() {
|
||||||
|
mockStoreData = {
|
||||||
|
vehicle: {
|
||||||
|
year: "2000",
|
||||||
|
make: "TestMake",
|
||||||
|
model: "TestModel",
|
||||||
|
style: "TestStyle",
|
||||||
|
carId: "TestID",
|
||||||
|
vin: null,
|
||||||
|
registration: {
|
||||||
|
licensePlate: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
address: null,
|
||||||
|
address2: null,
|
||||||
|
city: null,
|
||||||
|
state: null,
|
||||||
|
zipCode: null,
|
||||||
|
zipCodeCtu: null,
|
||||||
|
appointmentType: null,
|
||||||
|
isVehicleProtected: null,
|
||||||
|
provider: {
|
||||||
|
providerNumber: null,
|
||||||
|
address: {
|
||||||
|
streetAddress: null,
|
||||||
|
city: null,
|
||||||
|
state: null,
|
||||||
|
zipCode: null,
|
||||||
|
zipCodeCtu: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
techNotes: null,
|
||||||
|
},
|
||||||
|
customer: {
|
||||||
|
firstName: null,
|
||||||
|
lastName: null,
|
||||||
|
emailAddress: null,
|
||||||
|
phoneNumber: null,
|
||||||
|
isSmsOptIn: null,
|
||||||
|
},
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
numberOfChips: null,
|
||||||
|
glassToReplace: [{ glassLocation: "Windshield", glassName: "windshield" }],
|
||||||
|
partQuestionAnswers: null,
|
||||||
|
moldingQuestionAnswers: null,
|
||||||
|
capabilityQuestionAnswers: null,
|
||||||
|
dateOfLoss: null,
|
||||||
|
damageCause: null,
|
||||||
|
},
|
||||||
|
lineItems: {
|
||||||
|
glassParts: [
|
||||||
|
{
|
||||||
|
canSafeliteRecalibrate: true,
|
||||||
|
childParts: [
|
||||||
|
{
|
||||||
|
kitPrice: 0,
|
||||||
|
laborAmount: 23.55,
|
||||||
|
partNumber: "GGG FW4896",
|
||||||
|
salesTax: 1.77,
|
||||||
|
sellingPrice: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
color: "Green Tint",
|
||||||
|
description:
|
||||||
|
"solar, soundproofing, lane keep assist, lane departure warning system, w/adaptive cruise control",
|
||||||
|
id: "db22fd44-10dd-456f-979b-ff88cf68cca6",
|
||||||
|
kitPrice: 0,
|
||||||
|
laborAmount: 60,
|
||||||
|
partNumber: "FW04896GTYN",
|
||||||
|
partType: "WINDSHIELD",
|
||||||
|
recalibrationType: "STATIC",
|
||||||
|
requiresCapabilityQuestions: false,
|
||||||
|
requiresRecalibration: true,
|
||||||
|
salesTax: 63.86,
|
||||||
|
sellingPrice: 791.46,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
supportingItems: null,
|
||||||
|
vaps: null,
|
||||||
|
serverData: null,
|
||||||
|
promos: null,
|
||||||
|
},
|
||||||
|
payment: {
|
||||||
|
isInsurance: null,
|
||||||
|
insuranceCoverage: {
|
||||||
|
isVerified: null,
|
||||||
|
coverageStatus: null,
|
||||||
|
coverageType: null,
|
||||||
|
coverageVerificationType: null,
|
||||||
|
},
|
||||||
|
parentAccountNumber: 0,
|
||||||
|
billToAccountNumber: null,
|
||||||
|
isPia: null,
|
||||||
|
piaType: null,
|
||||||
|
inactivePromos: null,
|
||||||
|
paypalToken: null,
|
||||||
|
nextGenSettledAmount: 0,
|
||||||
|
ccToken: {
|
||||||
|
subscriptionId: null,
|
||||||
|
expMonth: null,
|
||||||
|
expYear: null,
|
||||||
|
cardType: null,
|
||||||
|
billToPostalCode: null,
|
||||||
|
billToFirstName: null,
|
||||||
|
billToLastName: null,
|
||||||
|
referenceNumber: null,
|
||||||
|
authCode: null,
|
||||||
|
transactionId: null,
|
||||||
|
transReferenceNumber: null,
|
||||||
|
lastFour: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
policy: {
|
||||||
|
currentDeductible: 0,
|
||||||
|
policyNumber: null,
|
||||||
|
isItac: false,
|
||||||
|
additionalAuthFlag: null,
|
||||||
|
isNoComp: false,
|
||||||
|
insuranceCompanyName: null,
|
||||||
|
},
|
||||||
|
schedule: {
|
||||||
|
date: null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
routeCode: null,
|
||||||
|
jobMaxMinutes: null,
|
||||||
|
jobMinMinutes: null,
|
||||||
|
},
|
||||||
|
externalParameterServiceZip: {
|
||||||
|
zipCode: null,
|
||||||
|
emailAddress: null,
|
||||||
|
},
|
||||||
|
externalParameterState: { isExternalParameter: false },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyMockStoreDataToGetters() {
|
||||||
|
store.getters = {
|
||||||
|
vehicle: mockStoreData.vehicle,
|
||||||
|
};
|
||||||
|
store.state.order = mockStoreData;
|
||||||
|
store.state.applicationUser.experiments = mockExperimentSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function mockDispatchStoreAction(actionName) {
|
||||||
|
return mockStoreActionData[actionName];
|
||||||
|
}
|
||||||
|
|
||||||
|
jest.mock("@/mixins/base-mixin.js", () => ({
|
||||||
|
methods: {
|
||||||
|
dispatchStoreAction: jest.fn(),
|
||||||
|
dispatchStoreActionWithLogging: jest.fn().mockImplementation(mockDispatchStoreAction),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/helpers/cms-content-helper", () => ({
|
||||||
|
fetchCmsContentForPage: () => Promise.resolve("content"),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/helpers/heritage-integration/order-helper.js", () => ({
|
||||||
|
saveSession: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@/helpers/heritage-integration/cookie-helper", () => ({
|
||||||
|
deleteFunnelCookie: jest.fn(),
|
||||||
|
getFunnelCookie: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
router.navigateWithoutSaving = jest.fn();
|
||||||
|
router.navigateWithSaving = jest.fn();
|
||||||
|
|
||||||
|
// Tests
|
||||||
|
describe("return-user.vue", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
resetMockStoreData();
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Test prerequisites are valid and child components are rendered", () => {
|
||||||
|
test("expect pagePrerequisites are valid to be called", () => {
|
||||||
|
// Arrange
|
||||||
|
const wrapper = setupMocks({});
|
||||||
|
|
||||||
|
applyMockStoreDataToGetters();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const pagePrerequisitesSpy = jest.spyOn(wrapper.vm, "arePagePrerequisitesValid");
|
||||||
|
|
||||||
|
wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(pagePrerequisitesSpy).toBeCalled();
|
||||||
|
expect(getFunnelCookie).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders child components", () => {
|
||||||
|
const wrapper = setupMocks({});
|
||||||
|
|
||||||
|
expect(wrapper.findComponent(funnelHeader).exists()).toBe(true);
|
||||||
|
expect(wrapper.findComponent(funnelSubHeader).exists()).toBe(true);
|
||||||
|
expect(wrapper.findComponent(navbar).exists()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Navigation", () => {
|
||||||
|
test("Check forwardButtonAction is working", async () => {
|
||||||
|
// Arrange
|
||||||
|
const wrapper = setupMocks({});
|
||||||
|
// Act
|
||||||
|
|
||||||
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.$router.navigateWithoutSaving).toBeCalledWith(
|
||||||
|
navigationScenarios.CLICKED_FORWARD,
|
||||||
|
wrapper.vm.$route
|
||||||
|
);
|
||||||
|
});
|
||||||
|
test("expect functions in startOver to be called", async () => {
|
||||||
|
//Arrange
|
||||||
|
const wrapper = setupMocks({});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const dispatchStoreActionSpy = jest.spyOn(wrapper.vm, "dispatchStoreAction");
|
||||||
|
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
await wrapper.vm.startOver();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.$router.navigateWithoutSaving).toBeCalledWith(
|
||||||
|
navigationScenarios.CLICKED_FORWARD,
|
||||||
|
wrapper.vm.$route
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(dispatchStoreActionSpy).toHaveBeenCalledWith(storeActions.RESET_STATE);
|
||||||
|
expect(deleteFunnelCookie).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function setupMocks({ customMountOptions }) {
|
||||||
|
const route = { query: { fmgPage: "return-user" }, params: {} };
|
||||||
|
|
||||||
|
baseMixin.methods.ResetExternalParamsAndHideModal = jest.fn();
|
||||||
|
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
...customMountOptions,
|
||||||
|
route: route,
|
||||||
|
});
|
||||||
|
|
||||||
|
mountOptions.global.mocks["$store"] = store;
|
||||||
|
mountOptions.global.mocks["$router"] = router;
|
||||||
|
baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true);
|
||||||
|
mountOptions["attachTo"] = document.body;
|
||||||
|
|
||||||
|
const wrapper = shallowMount(returnUser, mountOptions, {
|
||||||
|
stubs: {
|
||||||
|
Form,
|
||||||
|
funnelHeader,
|
||||||
|
funnelSubHeader,
|
||||||
|
navbar,
|
||||||
|
loadingModal: true,
|
||||||
|
buttonMain,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,10 @@ export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) {
|
||||||
// Get the Mobile Fee Part
|
// Get the Mobile Fee Part
|
||||||
const mobileFeePart = await baseMixin.methods.dispatchStoreActionWithLogging(
|
const mobileFeePart = await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||||
storeActions.GET_MOBILE_FEE_PART,
|
storeActions.GET_MOBILE_FEE_PART,
|
||||||
null,
|
{
|
||||||
|
serviceZipCode: serviceZipCode,
|
||||||
|
serviceZipCodeCtu: zipCodeData.zipCodeCtu,
|
||||||
|
},
|
||||||
pageNameToLog,
|
pageNameToLog,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -241,57 +241,46 @@ export default {
|
||||||
this.displayMismatchStateAndZipAlert = false;
|
this.displayMismatchStateAndZipAlert = false;
|
||||||
},
|
},
|
||||||
async setMobileLocation() {
|
async setMobileLocation() {
|
||||||
if (
|
this.resetAlerts();
|
||||||
this.internalModel.addressQuestions.zipCode !==
|
// Validate the Zip Code
|
||||||
this.modelValue.addressQuestions.zipCode
|
const zipCodeData = await this.getZipCodeData(
|
||||||
) {
|
this.internalModel.addressQuestions.zipCode,
|
||||||
this.resetAlerts();
|
"service-location"
|
||||||
// Validate the Zip Code
|
);
|
||||||
const zipCodeData = await this.getZipCodeData(
|
|
||||||
this.internalModel.addressQuestions.zipCode,
|
if (!zipCodeData.isValid) {
|
||||||
|
this.displayInvalidZipAlert = true;
|
||||||
|
this.resetModalButtonStyle();
|
||||||
|
} else if (zipCodeData.state != this.internalModel.addressQuestions.state) {
|
||||||
|
this.displayMismatchStateAndZipAlert = true;
|
||||||
|
this.resetModalButtonStyle();
|
||||||
|
} else {
|
||||||
|
// retrieve mobile fee part
|
||||||
|
const serviceZipCode = this.internalModel.addressQuestions.zipCode;
|
||||||
|
const mobileFeePart = await getPricedMobileFeePart(
|
||||||
|
serviceZipCode,
|
||||||
"service-location"
|
"service-location"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!zipCodeData.isValid) {
|
// retrieve serviceability details
|
||||||
this.displayInvalidZipAlert = true;
|
const serviceabilityDetails = await getServiceabilityDetails(
|
||||||
this.resetModalButtonStyle();
|
serviceZipCode,
|
||||||
} else if (zipCodeData.state != this.internalModel.addressQuestions.state) {
|
null,
|
||||||
this.displayMismatchStateAndZipAlert = true;
|
"service-location"
|
||||||
this.resetModalButtonStyle();
|
);
|
||||||
} else {
|
|
||||||
// retrieve mobile fee part
|
|
||||||
const serviceZipCode = this.internalModel.addressQuestions.zipCode;
|
|
||||||
const mobileFeePart = await getPricedMobileFeePart(
|
|
||||||
serviceZipCode,
|
|
||||||
"service-location"
|
|
||||||
);
|
|
||||||
|
|
||||||
// retrieve serviceability details
|
const billToAccountNumber = await getBillToAccountNumber(
|
||||||
const serviceabilityDetails = await getServiceabilityDetails(
|
this.internalModel.zipCodeCtu
|
||||||
serviceZipCode,
|
);
|
||||||
null,
|
|
||||||
"service-location"
|
|
||||||
);
|
|
||||||
|
|
||||||
const billToAccountNumber = await getBillToAccountNumber(
|
// update content related to service zip code
|
||||||
this.internalModel.zipCodeCtu
|
this.$emit("updated-mobile-fee-part", mobileFeePart);
|
||||||
);
|
this.$emit("updated-serviceability", serviceabilityDetails.data);
|
||||||
|
this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase);
|
||||||
|
this.$emit("updated-mobile-ctu", zipCodeData.zipCodeCtu);
|
||||||
|
this.$emit("updated-bill-to-account-number", billToAccountNumber);
|
||||||
|
|
||||||
// update content related to service zip code
|
// update the page level model
|
||||||
this.$emit("updated-mobile-fee-part", mobileFeePart);
|
|
||||||
this.$emit("updated-serviceability", serviceabilityDetails.data);
|
|
||||||
this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase);
|
|
||||||
this.$emit("updated-mobile-ctu", zipCodeData.zipCodeCtu);
|
|
||||||
this.$emit("updated-bill-to-account-number", billToAccountNumber);
|
|
||||||
|
|
||||||
// update the page level model
|
|
||||||
this.$emit("update:modelValue", this.internalModel);
|
|
||||||
|
|
||||||
//Page advance to Schedule page
|
|
||||||
this.$emit("mobileLocationSelected");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Update the page level model
|
|
||||||
this.$emit("update:modelValue", this.internalModel);
|
this.$emit("update:modelValue", this.internalModel);
|
||||||
|
|
||||||
//Page advance to Schedule page
|
//Page advance to Schedule page
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,9 @@ beforeEach(() => {
|
||||||
zipCode: "43235",
|
zipCode: "43235",
|
||||||
state: "OH",
|
state: "OH",
|
||||||
},
|
},
|
||||||
|
vehicle: {
|
||||||
|
isMobileStaticRecalibrationApplicable: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
damage: {
|
damage: {
|
||||||
isRepair: false,
|
isRepair: false,
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,7 @@ import { defineRule } from "vee-validate";
|
||||||
import { errorMessages } from "@/constants/error-messages";
|
import { errorMessages } from "@/constants/error-messages";
|
||||||
|
|
||||||
const MOBILE_FEE_PART_TYPE = "MOBILE FEE";
|
const MOBILE_FEE_PART_TYPE = "MOBILE FEE";
|
||||||
|
const MOBILE_STATIC_RECAL_FEE_PART_NUMBER = "RECAL MOBILE";
|
||||||
|
|
||||||
// DEFINE VALIDATION RULES
|
// DEFINE VALIDATION RULES
|
||||||
defineRule("mobile-location-required", (value) => {
|
defineRule("mobile-location-required", (value) => {
|
||||||
|
|
@ -188,6 +189,8 @@ export default {
|
||||||
isRecalibrationServiceableInshop: null,
|
isRecalibrationServiceableInshop: null,
|
||||||
isGlassServiceableMobile: null,
|
isGlassServiceableMobile: null,
|
||||||
isRecalibrationServiceableMobile: null,
|
isRecalibrationServiceableMobile: null,
|
||||||
|
isVehicleMobileStaticRecalibrationApplicable:
|
||||||
|
this.getIsVehicleMobileStaticRecalibrationApplicableFromStore(),
|
||||||
selectedAppointmentType: this.getSelectedAppointmentType(),
|
selectedAppointmentType: this.getSelectedAppointmentType(),
|
||||||
selectedProvider: this.getSelectedProvider(),
|
selectedProvider: this.getSelectedProvider(),
|
||||||
mobileFeePart: null,
|
mobileFeePart: null,
|
||||||
|
|
@ -306,11 +309,21 @@ export default {
|
||||||
},
|
},
|
||||||
isServiceableMobile() {
|
isServiceableMobile() {
|
||||||
if (this.isRecalibrationServiceableMobile !== null) {
|
if (this.isRecalibrationServiceableMobile !== null) {
|
||||||
return this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile;
|
return (
|
||||||
|
(this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile) ||
|
||||||
|
this.isMobileStaticRecalibrationApplicable
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return this.isGlassServiceableMobile;
|
return this.isGlassServiceableMobile;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
isMobileStaticRecalibrationApplicable() {
|
||||||
|
return (
|
||||||
|
this.isVehicleMobileStaticRecalibrationApplicable &&
|
||||||
|
this.mobileFeePart?.partNumber == MOBILE_STATIC_RECAL_FEE_PART_NUMBER &&
|
||||||
|
(this.isInsurance ? this.mobileFeePart?.isInsurable : true)
|
||||||
|
);
|
||||||
|
},
|
||||||
mobileFeeApplies() {
|
mobileFeeApplies() {
|
||||||
if (
|
if (
|
||||||
this.mobileFeePart?.laborAmount > 0 ||
|
this.mobileFeePart?.laborAmount > 0 ||
|
||||||
|
|
@ -349,7 +362,8 @@ export default {
|
||||||
return (
|
return (
|
||||||
this.isServiceableInshop &&
|
this.isServiceableInshop &&
|
||||||
this.isGlassServiceableMobile &&
|
this.isGlassServiceableMobile &&
|
||||||
this.isRecalibrationServiceableMobile === false
|
this.isRecalibrationServiceableMobile === false &&
|
||||||
|
!this.isMobileStaticRecalibrationApplicable
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
displayRecalibrationWarning() {
|
displayRecalibrationWarning() {
|
||||||
|
|
@ -485,6 +499,9 @@ export default {
|
||||||
getSelectedProvider() {
|
getSelectedProvider() {
|
||||||
return store.getters.order.serviceLocation.provider;
|
return store.getters.order.serviceLocation.provider;
|
||||||
},
|
},
|
||||||
|
getIsVehicleMobileStaticRecalibrationApplicableFromStore() {
|
||||||
|
return store.getters.order.vehicle.isMobileStaticRecalibrationApplicable;
|
||||||
|
},
|
||||||
resetMobileLocation() {
|
resetMobileLocation() {
|
||||||
this.streetAddress = "";
|
this.streetAddress = "";
|
||||||
this.apartmentNumberOrBusinessName = "";
|
this.apartmentNumberOrBusinessName = "";
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ export default {
|
||||||
modelOptions: [],
|
modelOptions: [],
|
||||||
styleOptions: [],
|
styleOptions: [],
|
||||||
displayNoServiceAlert: false,
|
displayNoServiceAlert: false,
|
||||||
|
isMobileStaticRecalibrationApplicable: this.getIsMobileStaticRecalibrationApplicable(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -438,6 +439,8 @@ export default {
|
||||||
this.imageVifNumber = result?.data.imageVifNumber;
|
this.imageVifNumber = result?.data.imageVifNumber;
|
||||||
this.imageVifColor = result?.data.imageVifColor;
|
this.imageVifColor = result?.data.imageVifColor;
|
||||||
this.displayNoServiceAlert = !result?.data.canSafeliteService;
|
this.displayNoServiceAlert = !result?.data.canSafeliteService;
|
||||||
|
this.isMobileStaticRecalibrationApplicable =
|
||||||
|
result?.data.isMobileStaticRecalibrationApplicable;
|
||||||
},
|
},
|
||||||
resetAlert() {
|
resetAlert() {
|
||||||
this.displayNoServiceAlert = false;
|
this.displayNoServiceAlert = false;
|
||||||
|
|
@ -456,6 +459,8 @@ export default {
|
||||||
imageUrl: this.imageUrl,
|
imageUrl: this.imageUrl,
|
||||||
imageVifNumber: this.imageVifNumber,
|
imageVifNumber: this.imageVifNumber,
|
||||||
imageVifColor: this.imageVifColor,
|
imageVifColor: this.imageVifColor,
|
||||||
|
isMobileStaticRecalibrationApplicable:
|
||||||
|
this.isMobileStaticRecalibrationApplicable,
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
@ -531,6 +536,9 @@ export default {
|
||||||
getImageVifColorfromStore() {
|
getImageVifColorfromStore() {
|
||||||
return store.getters.vehicle.imageVifColor;
|
return store.getters.vehicle.imageVifColor;
|
||||||
},
|
},
|
||||||
|
getIsMobileStaticRecalibrationApplicable() {
|
||||||
|
return store.getters.vehicle.isMobileStaticRecalibrationApplicable;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -712,16 +712,10 @@ export default {
|
||||||
return !areAllSessionCookiesSet();
|
return !areAllSessionCookiesSet();
|
||||||
},
|
},
|
||||||
|
|
||||||
// sessionExpired is true when one of the analytics cookies(sid, dxdev) has expired but we still have the funnelSessionInfo cookie
|
// sessionExpired is true when one of the analytics cookies(sid, dxdev) has expired but we still have the vehicle year in vuex
|
||||||
sessionExpired() {
|
sessionExpired() {
|
||||||
const fromHeritage = getQuerystringParameter(queryStrings.FROM_HERITAGE) === "true";
|
const fromHeritage = getQuerystringParameter(queryStrings.FROM_HERITAGE) === "true";
|
||||||
const funnelCookieLastTouched = getFunnelCookie()?.LastTouched;
|
if (this.noSession() && !fromHeritage && store.getters.order.vehicle?.year > 0) {
|
||||||
if (
|
|
||||||
this.noSession() &&
|
|
||||||
!fromHeritage &&
|
|
||||||
funnelCookieLastTouched !== null &&
|
|
||||||
funnelCookieLastTouched !== undefined
|
|
||||||
) {
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"
|
||||||
import { routingTable } from "@/router/router-constants/routing-table.js";
|
import { routingTable } from "@/router/router-constants/routing-table.js";
|
||||||
import { globalEvents, globalEventTypes } from "@/constants/events";
|
import { globalEvents, globalEventTypes } from "@/constants/events";
|
||||||
import { queryStrings } from "@/constants/query-strings";
|
import { queryStrings } from "@/constants/query-strings";
|
||||||
import { getQuerystringParameter } from "@/helpers/querystring-helper";
|
import { getQuerystringParameter, buildQuerystringObject } from "@/helpers/querystring-helper";
|
||||||
import { getDeviceIdValue } from "@/helpers/heritage-integration/cookie-helper";
|
import { getDeviceIdValue } from "@/helpers/heritage-integration/cookie-helper";
|
||||||
import { showFmgLoadingModal } from "@/helpers/loading-modal-helper";
|
import { showFmgLoadingModal } from "@/helpers/loading-modal-helper";
|
||||||
import { fmgPageValues, funnelStartPageName } from "@/router/router-constants/fmgPage-values";
|
import { fmgPageValues, funnelStartPageName } from "@/router/router-constants/fmgPage-values";
|
||||||
|
|
@ -100,27 +100,24 @@ const routes = [
|
||||||
}
|
}
|
||||||
// On entering the funnel "fresh", read cookie information, decide what to do next.
|
// On entering the funnel "fresh", read cookie information, decide what to do next.
|
||||||
else if (from.redirectedFrom === undefined || fromReturnUser) {
|
else if (from.redirectedFrom === undefined || fromReturnUser) {
|
||||||
// if entering the funnel from the content site, check and see if there is already a funnel cookie.
|
// if entering the funnel from the content site, check and see if there is already a vehicle year in vuex.
|
||||||
// if so, send them to return-user page.
|
// if so, send them to return-user page.
|
||||||
const funnelCookieLastTouched = getFunnelCookie()?.LastTouched;
|
|
||||||
if (
|
if (
|
||||||
fromContentSite &&
|
fromContentSite &&
|
||||||
funnelCookieLastTouched !== null &&
|
!toReturnUserPage &&
|
||||||
funnelCookieLastTouched !== undefined &&
|
store.getters.order.vehicle?.year > 0
|
||||||
!toReturnUserPage
|
|
||||||
) {
|
) {
|
||||||
log(" --from content site navigate to return user");
|
log(" --from content site navigate to return user");
|
||||||
var qso = {
|
var qso = {
|
||||||
fmgPage: fmgPageValues.RETURN_USER,
|
fmgPage: fmgPageValues.RETURN_USER,
|
||||||
};
|
};
|
||||||
const lg = getQuerystringParameter(queryStrings.LOG);
|
|
||||||
if (lg) {
|
const newQueryString = buildQuerystringObject(qso, true);
|
||||||
qso[queryStrings.LOG] = true;
|
log(" -- returnUser add querystring: " + JSON.stringify(newQueryString));
|
||||||
}
|
|
||||||
|
|
||||||
router.push({
|
router.push({
|
||||||
path: "/",
|
path: "/",
|
||||||
query: Object.assign({}, qso),
|
query: Object.assign({}, newQueryString),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -178,8 +175,7 @@ const routes = [
|
||||||
// clear part related state because heritage selected a new vehicle
|
// clear part related state because heritage selected a new vehicle
|
||||||
if (
|
if (
|
||||||
to.query.fmgPage === fmgPageValues.VEHICLE &&
|
to.query.fmgPage === fmgPageValues.VEHICLE &&
|
||||||
eval(getFunnelCookie()?.HasDelayedClaimRegistration &&
|
eval(getFunnelCookie()?.HasDelayedClaimRegistration && !fromReturnUser)
|
||||||
!fromReturnUser)
|
|
||||||
) {
|
) {
|
||||||
store.commit(storeMutations.RESET_GLASS_PARTS_STATE);
|
store.commit(storeMutations.RESET_GLASS_PARTS_STATE);
|
||||||
}
|
}
|
||||||
|
|
@ -187,7 +183,7 @@ const routes = [
|
||||||
// if coming from the return user page, clear the destination page so implicit navigation runs
|
// if coming from the return user page, clear the destination page so implicit navigation runs
|
||||||
log(" --to.query ", JSON.stringify(to.query));
|
log(" --to.query ", JSON.stringify(to.query));
|
||||||
if (fromReturnUser && to.query) {
|
if (fromReturnUser && to.query) {
|
||||||
log( " --clear to.query");
|
log(" --clear to.query");
|
||||||
delete to.query[queryStrings.FMG_PAGE];
|
delete to.query[queryStrings.FMG_PAGE];
|
||||||
|
|
||||||
//to.query[queryStrings.FMG_PAGE] = "";
|
//to.query[queryStrings.FMG_PAGE] = "";
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ const getDefaultState = () => {
|
||||||
registration: {
|
registration: {
|
||||||
licensePlate: null,
|
licensePlate: null,
|
||||||
},
|
},
|
||||||
|
isMobileStaticRecalibrationApplicable: false,
|
||||||
},
|
},
|
||||||
serviceLocation: {
|
serviceLocation: {
|
||||||
address: null,
|
address: null,
|
||||||
|
|
@ -225,6 +226,10 @@ export const mutations = {
|
||||||
updateVehicleVin(state, vin) {
|
updateVehicleVin(state, vin) {
|
||||||
state.order.vehicle.vin = vin;
|
state.order.vehicle.vin = vin;
|
||||||
},
|
},
|
||||||
|
updateIsMobileStaticRecalibrationApplicable(state, isMobileStaticRecalibrationApplicable) {
|
||||||
|
state.order.vehicle.isMobileStaticRecalibrationApplicable =
|
||||||
|
isMobileStaticRecalibrationApplicable;
|
||||||
|
},
|
||||||
updateIsRepair(state, isRepair) {
|
updateIsRepair(state, isRepair) {
|
||||||
state.order.damage.isRepair = isRepair;
|
state.order.damage.isRepair = isRepair;
|
||||||
},
|
},
|
||||||
|
|
@ -350,6 +355,8 @@ export const mutations = {
|
||||||
state.order.vehicle.imageUrl = vehicleInfo.imageUrl;
|
state.order.vehicle.imageUrl = vehicleInfo.imageUrl;
|
||||||
state.order.vehicle.imageVifNumber = vehicleInfo.imageVifNumber;
|
state.order.vehicle.imageVifNumber = vehicleInfo.imageVifNumber;
|
||||||
state.order.vehicle.imageColor = vehicleInfo.imageVifColor;
|
state.order.vehicle.imageColor = vehicleInfo.imageVifColor;
|
||||||
|
state.order.vehicle.isMobileStaticRecalibrationApplicable =
|
||||||
|
vehicleInfo.isMobileStaticRecalibrationApplicable;
|
||||||
},
|
},
|
||||||
updateRegistration(state, registrationInfo) {
|
updateRegistration(state, registrationInfo) {
|
||||||
state.order.vehicle.registration.licensePlate = registrationInfo?.licensePlate;
|
state.order.vehicle.registration.licensePlate = registrationInfo?.licensePlate;
|
||||||
|
|
@ -534,6 +541,7 @@ export const mutations = {
|
||||||
state.order.vehicle.imageUrl = null;
|
state.order.vehicle.imageUrl = null;
|
||||||
state.order.vehicle.imageVifNumber = null;
|
state.order.vehicle.imageVifNumber = null;
|
||||||
state.order.vehicle.imageColor = null;
|
state.order.vehicle.imageColor = null;
|
||||||
|
state.order.vehicle.isMobileStaticRecalibrationApplicable = false;
|
||||||
},
|
},
|
||||||
resetDamageState(state) {
|
resetDamageState(state) {
|
||||||
state.order.damage.isRepair = null;
|
state.order.damage.isRepair = null;
|
||||||
|
|
@ -1634,7 +1642,7 @@ export const actions = {
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
|
|
||||||
getMobileFeePart(context, { pageNameToLog }) {
|
getMobileFeePart(context, { payload: { serviceZipCode, serviceZipCodeCtu }, pageNameToLog }) {
|
||||||
const serviceType = context.getters.damage.isRepair ? "Repair" : "Install";
|
const serviceType = context.getters.damage.isRepair ? "Repair" : "Install";
|
||||||
const facilityType = "Mobile";
|
const facilityType = "Mobile";
|
||||||
const parentAccountNumber = context.getters.payment.parentAccountNumber;
|
const parentAccountNumber = context.getters.payment.parentAccountNumber;
|
||||||
|
|
@ -1646,16 +1654,31 @@ export const actions = {
|
||||||
const coverageStatus = coverageStatusEnum(order.payment?.insuranceCoverage?.coverageStatus);
|
const coverageStatus = coverageStatusEnum(order.payment?.insuranceCoverage?.coverageStatus);
|
||||||
const coverageType = coverageTypeEnum(order.payment?.insuranceCoverage?.coverageType);
|
const coverageType = coverageTypeEnum(order.payment?.insuranceCoverage?.coverageType);
|
||||||
const isItacOptimized = order.policy?.isItac ?? false;
|
const isItacOptimized = order.policy?.isItac ?? false;
|
||||||
|
const isMobileStaticRecalibrationApplicable =
|
||||||
|
order.vehicle?.isMobileStaticRecalibrationApplicable;
|
||||||
const zipCode =
|
const zipCode =
|
||||||
order.serviceLocation?.provider?.address?.zipCode ?? order.serviceLocation?.zipCode;
|
serviceZipCode ??
|
||||||
|
order.serviceLocation?.provider?.address?.zipCode ??
|
||||||
|
order.serviceLocation?.zipCode;
|
||||||
|
|
||||||
var providerNumber =
|
var providerNumber =
|
||||||
order.serviceLocation?.provider?.providerNumber ?? order.serviceLocation?.zipCodeCtu;
|
serviceZipCodeCtu ??
|
||||||
|
order.serviceLocation?.provider?.providerNumber ??
|
||||||
|
order.serviceLocation?.zipCodeCtu;
|
||||||
if (providerNumber.startsWith("00") && providerNumber.length > 5) {
|
if (providerNumber.startsWith("00") && providerNumber.length > 5) {
|
||||||
providerNumber = providerNumber.substring(1);
|
providerNumber = providerNumber.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItacOptimized=${isItacOptimized}&zipCode=${zipCode}`;
|
var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItacOptimized=${isItacOptimized}&zipCode=${zipCode}`;
|
||||||
|
|
||||||
|
if (isMobileStaticRecalibrationApplicable) {
|
||||||
|
const staticRecalPartNumber = getStaticRecalPartNumber(order.lineItems?.glassParts[0]);
|
||||||
|
const carId = order.vehicle?.carId;
|
||||||
|
if (staticRecalPartNumber && carId) {
|
||||||
|
endPoint = `${endPoint}&partNumbers=${staticRecalPartNumber}&carId=${carId}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (coverageStatus) {
|
if (coverageStatus) {
|
||||||
endPoint = `${endPoint}&coverageStatus=${coverageStatus}`;
|
endPoint = `${endPoint}&coverageStatus=${coverageStatus}`;
|
||||||
}
|
}
|
||||||
|
|
@ -2256,7 +2279,18 @@ export const actions = {
|
||||||
// Vehicle
|
// Vehicle
|
||||||
saveVehicle(
|
saveVehicle(
|
||||||
context,
|
context,
|
||||||
{ year, make, model, style, carId, category, imageUrl, imageVifNumber, imageVifColor }
|
{
|
||||||
|
year,
|
||||||
|
make,
|
||||||
|
model,
|
||||||
|
style,
|
||||||
|
carId,
|
||||||
|
category,
|
||||||
|
imageUrl,
|
||||||
|
imageVifNumber,
|
||||||
|
imageVifColor,
|
||||||
|
isMobileStaticRecalibrationApplicable,
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
context.state.order.vehicle.year != year ||
|
context.state.order.vehicle.year != year ||
|
||||||
|
|
@ -2277,6 +2311,10 @@ export const actions = {
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, imageUrl);
|
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, imageUrl);
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, imageVifNumber);
|
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, imageVifNumber);
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, imageVifColor);
|
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, imageVifColor);
|
||||||
|
context.commit(
|
||||||
|
storeMutations.UPDATE_VEHICLE_MOBILE_STATIC_RECALIBRATION_APPLICABLE,
|
||||||
|
isMobileStaticRecalibrationApplicable
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -3680,3 +3718,13 @@ function getExternalParameterDefaultState() {
|
||||||
function saveExternalParameterState(externalParameterState) {
|
function saveExternalParameterState(externalParameterState) {
|
||||||
window.sessionStorage.setItem("externalParameterState", JSON.stringify(externalParameterState));
|
window.sessionStorage.setItem("externalParameterState", JSON.stringify(externalParameterState));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//This function checks if static recalibration is available for the vehicle and returns the part number for it.
|
||||||
|
function getStaticRecalPartNumber(glassPartsArray) {
|
||||||
|
const recalPart = glassPartsArray.childParts.find((item) => item.partNumber === "RECAL STATIC");
|
||||||
|
if (recalPart) {
|
||||||
|
return recalPart.partNumber;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue