diff --git a/src/common-components/funnel-footer/funnel-footer.vue b/src/common-components/funnel-footer/funnel-footer.vue
index 43b471e81..2a6119681 100644
--- a/src/common-components/funnel-footer/funnel-footer.vue
+++ b/src/common-components/funnel-footer/funnel-footer.vue
@@ -15,10 +15,6 @@
data-bs-target="#footerModal"
data-bs-dismiss="modal" />
-
-
{
+ methods: {
+ resetButtonStyle() {
this.$refs.buttonMain.resetButtonStyle();
- });
+ },
},
components: {
buttonMain,
diff --git a/src/common-components/question-chain/question-chain.vue b/src/common-components/question-chain/question-chain.vue
index 11874670b..bf68a4363 100644
--- a/src/common-components/question-chain/question-chain.vue
+++ b/src/common-components/question-chain/question-chain.vue
@@ -100,7 +100,7 @@ export default {
return false;
}
- // Example returnedAnswers:
+ // returnedAnswer examples:
// "1|nextQuestion|3|No"
// "5|answer|DW02104|Yes"
@@ -108,15 +108,12 @@ export default {
const questionNum = parseInt(returnedAnswerArray[0]);
const questionType = returnedAnswerArray[1];
const questionAnswer = returnedAnswerArray[2];
- const questionAnswerText = returnedAnswerArray[3];
const answeredQuestions = [];
this.questions.forEach((q) => {
// find this question and mark it as "answered" by populating answerSelected
if (q.questionSequence === questionNum) {
q.answerSelected = returnedAnswer;
- q.answerNumber = questionNum;
- q.selectedAnswerText = questionAnswerText;
}
// remove all answers AFTER this question...
// (needed in case user is changing previously answered questions)
@@ -126,6 +123,7 @@ export default {
if (q.answerSelected) {
answeredQuestions.push({
questionText: q.questionText,
+ selectedAnswer: q.answerSelected,
selectedAnswerText: q.answerSelected.split("|")[3],
questionNum: q.questionSequence,
});
diff --git a/src/common-components/textbox-question/textbox-question.spec.js b/src/common-components/textbox-question/textbox-question.spec.js
index bfc65da16..d5d1de4e6 100644
--- a/src/common-components/textbox-question/textbox-question.spec.js
+++ b/src/common-components/textbox-question/textbox-question.spec.js
@@ -53,7 +53,7 @@ describe("textboxQuestion.vue", () => {
expect(paragraph.attributes("class")).toContain("rounded-pill");
});
- it.only("Should return form-control class", async () => {
+ it("Should return form-control class", async () => {
// Act
const wrapper = shallowMount(textboxQuestion, {
global: {
diff --git a/src/constants/application-config.js b/src/constants/application-config.js
index f4840a91a..8f12760fc 100644
--- a/src/constants/application-config.js
+++ b/src/constants/application-config.js
@@ -8,6 +8,7 @@ const applicationConfig = {
APPLICATION_NAME: "FixMyGlass",
APPLICATION_ABBREVIATION: "fmg",
SITE_ENTRY_TRIGGER_VALUE: "FixMyGlass",
+ CASH_ACCOUNT_NUMBER: 167132,
};
export { applicationConfig };
diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js
index 473f9f616..b286f85f2 100644
--- a/src/constants/endpoints.js
+++ b/src/constants/endpoints.js
@@ -96,7 +96,7 @@ const endpoints = {
},
PriceOrderItems: {
url: "/price/api/v1/price/order-items",
- method: "POST",
+ method: "GET",
},
LogExperimentExposureIfAssigned: {
url: "/experiments/api/v1/experiments/log-exposure",
diff --git a/src/constants/experiments.js b/src/constants/experiments.js
index f2e5d4928..f6d25f1a7 100644
--- a/src/constants/experiments.js
+++ b/src/constants/experiments.js
@@ -4,6 +4,7 @@ const experimentUniverses = {
const experimentSettings = {
GOOGLE_CUSTOM_DIMENSION_INDEX: "Google Custom Dimension Index",
+ SUPPRESS_VIN_CAPTURE: "SuppressVinCapture",
};
const experimentTriggers = {
diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js
index 49b171551..d5780d96b 100644
--- a/src/constants/store-actions.js
+++ b/src/constants/store-actions.js
@@ -67,6 +67,10 @@ const storeActions = {
SAVE_MOLDING_QUESTION_ANSWERS: "saveMoldingQuestionAnswers",
SAVE_CAPABILITY_QUESTION_ANSWERS: "saveCapabilityQuestionAnswers",
SAVE_QUOTE_PAGE_SELECTIONS: "saveQuotePageSelections",
+ SAVE_PAYMENT_TYPE: "savePaymentType",
+ SAVE_ACCOUNT_NUMBER: "saveAccountNumber",
+ SAVE_SUPPORTING_ITEMS: "saveSupportingItems",
+ SAVE_VAPS: "saveVaps",
};
export { storeActions };
diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js
index ca3ea642e..840aff30d 100644
--- a/src/constants/store-mutations.js
+++ b/src/constants/store-mutations.js
@@ -21,6 +21,7 @@ const storeMutations = {
UPDATE_GLASS_PARTS: "updateGlassParts",
UPDATE_VAPS: "updateVaps",
UPDATE_SUPPORTING_ITEMS: "updateSupportingItems",
+ UPDATE_LINE_ITEMS_SERVER_DATA: "updateLineItemsServerData",
UPDATE_REGISTRATION_LICENSE_PLATE: "updateRegistrationLicensePlate",
UPDATE_REGISTRATION_ADDRESS: "updateRegistrationAddress",
@@ -31,8 +32,6 @@ const storeMutations = {
UPDATE_REGISTRATION_LAST_NAME: "updateRegistrationLastName",
UPDATE_REGISTRATION: "updateRegistration",
- UPDATE_SERVICE_LOCATION_ZIP_CODE: "updateServiceLocationZipCode",
- UPDATE_SERVICE_LOCATION_STATE: "updateServiceLocationState",
UPDATE_SERVICE_LOCATION: "updateServiceLocation",
UPDATE_CUSTOMER_EMAIL_ADDRESS: "updateCustomerEmailAddress",
@@ -56,8 +55,6 @@ const storeMutations = {
RESET_DAMAGE_STATE: "resetDamageState",
RESET_REGISTRATION_STATE: "resetRegistrationState",
RESET_GLASS_PARTS_STATE: "resetGlassPartsState",
- RESET_SUPPORTING_ITEMS_STATE: "resetSupportingItemsState",
- RESET_VAPS_STATE: "resetVapsState",
RESET_STATE: "resetState",
RESET_SAVE_SESSION_PROMISE: "resetSaveSessionPromise",
diff --git a/src/constants/tint-mapper.js b/src/constants/tint-mapper.js
index 308b9a92d..fab6d508f 100644
--- a/src/constants/tint-mapper.js
+++ b/src/constants/tint-mapper.js
@@ -78,7 +78,7 @@ const tintMap = {
// Returns undefined if no items are found.
export function getTintImage(glassLocation, colorString) {
// Windshield glass has special images, all other glass uses the same though.
- if (glassLocation.toLowerCase() !== "windshield") {
+ if (glassLocation?.toLowerCase() !== "windshield") {
glassLocation = "other";
}
diff --git a/src/helpers/damage-helper.js b/src/helpers/damage-helper.js
index 85cadca60..22e312939 100644
--- a/src/helpers/damage-helper.js
+++ b/src/helpers/damage-helper.js
@@ -37,7 +37,9 @@ export function getDamageString() {
export function getIsWindshieldOnly() {
const damageLocations = store.getters.damage.glassToReplace;
const returnString =
- damageLocations.length === 1 && damageLocations[0]?.glassLocation === "Windshield"
+ damageLocations &&
+ damageLocations.length === 1 &&
+ damageLocations[0]?.glassLocation === "Windshield"
? "windshield"
: "glass";
return returnString;
diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js
index 2c28d1d49..7030ba193 100644
--- a/src/helpers/heritage-integration/navigation-helper.js
+++ b/src/helpers/heritage-integration/navigation-helper.js
@@ -5,6 +5,8 @@ import { saveSession } from "@/helpers/heritage-integration/order-helper.js";
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
import { storeActions } from "@/constants/store-actions.js";
import { settleAllPromises } from "@/helpers/layout-helper";
+import experimentMixin from "@/mixins/experiment-mixin";
+import { experimentSettings } from "@/constants/experiments";
import store from "@/store";
import router from "@/router";
@@ -41,19 +43,51 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita
Used to navigate to the heritage funnel with the correct query string and url.
*/
-export async function navigateToHeritageFunnel(shouldSaveSession = true) {
+export async function navigateToHeritageFunnel({ shouldSaveSession = true, loadingModal }) {
// Create the order (or save existing order) when navigating to Heritage Funnel.
if (shouldSaveSession) {
await saveSession();
}
+ if (loadingModal && loadingModal.showModal) {
+ loadingModal.showModal();
+ }
+
router.navigateToExternalUrl(externalUrls.HERITAGE_FUNNEL, {
corid: store.getters.order.referralCorrelationId,
src: "concept-funnel",
conceptsqid: store.getters.applicationUser.savedSessionId,
+ isInsurance: store.getters.payment.isInsurance,
});
}
+export async function skipVinLookup() {
+ const isVinOptionalVehicle = store.getters.order.vehicle.make
+ ? await store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE)
+ : false;
+
+ return (
+ store.getters.damage.isRepair ||
+ isVinOptionalVehicle ||
+ experimentMixin.methods.hasSettingEqualTo(experimentSettings.SUPPRESS_VIN_CAPTURE, "true")
+ );
+}
+
+export async function skipVinLookupNotRepair() {
+ const isVinOptionalVehicle = store.getters.order.vehicle.make
+ ? await store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE)
+ : false;
+
+ return (
+ !store.getters.damage.isRepair &&
+ (isVinOptionalVehicle ||
+ experimentMixin.methods.hasSettingEqualTo(
+ experimentSettings.SUPPRESS_VIN_CAPTURE,
+ "true"
+ ))
+ );
+}
+
/*
Logic for getting the last "valid" page a user visited.
*/
@@ -74,9 +108,7 @@ async function getLatestPageForRedirection() {
fmgPageValues.CAPABILITY_QUESTIONS
);
- const isVinOptionalVehicle = store.getters.order.vehicle.make
- ? await store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE)
- : false;
+ const skipVin = await skipVinLookup();
if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) {
return fmgPageValues.VEHICLE_YEAR;
@@ -98,12 +130,13 @@ async function getLatestPageForRedirection() {
} else if (partQuestionsComponent.methods.arePagePrerequisitesValid()) {
return fmgPageValues.PART_QUESTIONS;
} else if (
+ // capture vin
vinLookupComponent.methods.arePagePrerequisitesValid() &&
- !store.getters.damage.isRepair &&
- !isVinOptionalVehicle
+ !skipVin
) {
return fmgPageValues.VIN_LOOKUP;
} else {
+ // do not capture vin
return fmgPageValues.ESTIMATE;
}
}
diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js
index 263fd054f..f9b3b1017 100644
--- a/src/helpers/heritage-integration/navigation-helper.spec.js
+++ b/src/helpers/heritage-integration/navigation-helper.spec.js
@@ -144,6 +144,16 @@ describe("getPageToRouteExistingOrderTo", () => {
store.commit(storeMutations.UPDATE_IS_REPAIR, false);
store.commit(storeMutations.UPDATE_MAKE, "acura");
+ const mockExperimentsList = [
+ {
+ universeName: "ConceptFunnel",
+ settings: {
+ SuppressVinCapture: false,
+ },
+ },
+ ];
+ store.commit(storeMutations.UPDATE_EXPERIMENTS, mockExperimentsList);
+
// Mock out the lazy load calls for all components.
mockLazyLoadComponentReturnValues({
[fmgPageValues.VEHICLE_MAKE]: true,
@@ -367,7 +377,7 @@ describe("navigateToHeritageFunnel", () => {
router.navigateToExternalUrl = jest.fn();
// Act
- await navigateToHeritageFunnel();
+ await navigateToHeritageFunnel({});
// Assert
expect(saveSessionFunction).toHaveBeenCalled();
@@ -414,7 +424,7 @@ describe("navigateToHeritageFunnel", () => {
router.navigateToExternalUrl = jest.fn();
// Act
- await navigateToHeritageFunnel();
+ await navigateToHeritageFunnel({});
// Assert
expect(router.navigateToExternalUrl).toHaveBeenCalled();
@@ -426,7 +436,7 @@ describe("navigateToHeritageFunnel", () => {
);
});
- test("should not save session, but should still navigate", async () => {
+ test("shouldSaveSession is false => should not save session, but should still navigate", async () => {
// Arrange
const mockReferralNumber = "2";
const mockCorrelationId = "55";
@@ -452,7 +462,7 @@ describe("navigateToHeritageFunnel", () => {
router.navigateToExternalUrl = jest.fn();
// Act
- await navigateToHeritageFunnel(false);
+ await navigateToHeritageFunnel({ shouldSaveSession: false });
// Assert
expect(saveSessionFunction).not.toHaveBeenCalled();
diff --git a/src/helpers/heritage-integration/order-helper.js b/src/helpers/heritage-integration/order-helper.js
index 9a24e9c24..1f0930477 100644
--- a/src/helpers/heritage-integration/order-helper.js
+++ b/src/helpers/heritage-integration/order-helper.js
@@ -30,7 +30,14 @@ export async function loadSessionIfPresent() {
}
// Loads session including referral if there is a cookie, and it doesn't indicate it needs a state reset.
- return (await loadSession(funnelCookie.SavedSessionId)).data;
+ return (
+ await loadSession(
+ funnelCookie.SavedSessionId,
+ funnelCookie.ReferralNumber,
+ funnelCookie.ReferralParentAccountNumber,
+ funnelCookie.ReferralCorrelationId
+ )
+ ).data;
}
/*
@@ -61,13 +68,16 @@ export async function saveSession() {
Calls API to load session given the referral number, referralDate, and referralCorrelationId
and returns the response.
*/
-async function loadSession(savedSessionId) {
+async function loadSession(savedSessionId, referralNumber, accountNumber, referralCorrelationId) {
// await the saveSessionPromise in the store to make sure we're loading up to date information
await store.getters.applicationUser.saveSessionPromise;
const response = await baseMixin.methods.dispatchStoreAction(
storeActions.LOAD_SESSION,
{
savedSessionId: savedSessionId?.toString(),
+ referralNumber,
+ accountNumber,
+ referralCorrelationId,
},
false
);
@@ -84,12 +94,13 @@ async function saveSessionHelper() {
await baseMixin.methods.dispatchStoreAction(
storeActions.UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE,
{
- referralNumber: savedSessionInfo.data.referralNumber.toString(),
+ referralNumber: savedSessionInfo.data.referralNumber?.toString(),
referralCorrelationId: savedSessionInfo.data.referralCorrelationId,
referralDate: savedSessionInfo.data.referralDate,
- accountNumber: savedSessionInfo.data.accountNumber.toString(),
+ accountNumber: savedSessionInfo.data.accountNumber?.toString(),
savedSessionId: savedSessionInfo.data.savedSessionId,
- crmCustomerId: savedSessionInfo.data.crmCustomerId.toString(),
+ crmCustomerId: savedSessionInfo.data.crmCustomerId?.toString(),
+ eon: savedSessionInfo.data.eon,
},
false
);
diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js
index bc9839803..2c4b44950 100644
--- a/src/layouts/address-lookup/address-lookup.spec.js
+++ b/src/layouts/address-lookup/address-lookup.spec.js
@@ -560,6 +560,7 @@ describe("address-lookup.vue", () => {
// Act
await wrapper.vm.forwardButtonAction();
+ //FIX THIS
// Assert
expect(wrapper.vm.dispatchStoreAction).not.toHaveBeenCalledWith(
storeActions.UPDATE_SERVICE_LOCATION_WITH_VEHICLE_REGISTRATION
diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue
index d7ced0576..0eb130eba 100644
--- a/src/layouts/address-lookup/address-lookup.vue
+++ b/src/layouts/address-lookup/address-lookup.vue
@@ -344,6 +344,7 @@ export default {
city: this.customerQuestions.addressQuestions.city,
zipCode: this.serviceZipCode,
state: resultMap.serviceZipValidationResponse.state,
+ zipCodeCtu: resultMap.serviceZipValidationResponse.zipCodeCtu,
},
false
);
diff --git a/src/layouts/address-vehicles/address-vehicles.spec.js b/src/layouts/address-vehicles/address-vehicles.spec.js
index 33718ff32..cf485aa97 100644
--- a/src/layouts/address-vehicles/address-vehicles.spec.js
+++ b/src/layouts/address-vehicles/address-vehicles.spec.js
@@ -21,7 +21,7 @@ describe("addressVehicles.vue", () => {
// Arrange
const { wrapper } = setupMocks({});
store.commit(storeMutations.UPDATE_CAR_ID, "NOT NULL");
- store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP_CODE, "12345");
+ store.commit(storeMutations.UPDATE_SERVICE_LOCATION, { zipCode: "12345" });
store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, "test@test.com");
// Act
diff --git a/src/layouts/capability-questions/capability-questions.spec.js b/src/layouts/capability-questions/capability-questions.spec.js
index c59857182..f29be44e6 100644
--- a/src/layouts/capability-questions/capability-questions.spec.js
+++ b/src/layouts/capability-questions/capability-questions.spec.js
@@ -84,12 +84,14 @@ const baseStoreGettersDamage = () => {
{
questionText:
"Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?",
+ selectedAnswer: "1|nextQuestion|3|Yes",
selectedAnswerText: "Yes",
questionNum: 1,
},
{
questionText:
"Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?",
+ selectedAnswer: "2|nextQuestion|3|Yes",
selectedAnswerText: "Yes",
questionNum: 2,
},
@@ -101,6 +103,7 @@ const baseStoreGettersDamage = () => {
store.getters = {
pageData: baseStoreGettersPageData,
damage: baseStoreGettersDamage,
+ payment: { insuranceCoverage: {} },
};
store.commit = jest.fn();
@@ -109,6 +112,7 @@ afterEach(() => {
store.getters = {
pageData: baseStoreGettersPageData,
damage: baseStoreGettersDamage,
+ payment: { insuranceCoverage: {} },
};
});
@@ -166,10 +170,10 @@ describe("capabilityQuestions.vue", () => {
});
describe("watch on selectedAnswers should be set up...", () => {
- test("Should trigger handleAnswerUpdates if watched data changes", async () => {
+ test("Should trigger handleCompletedQuestionChainAnswers if watched data changes", async () => {
// Arrange
const { wrapper } = setupMocks({});
- const spy = jest.spyOn(wrapper.vm, "handleAnswerUpdates");
+ const spy = jest.spyOn(wrapper.vm, "handleCompletedQuestionChainAnswers");
// Act
wrapper.setData({
@@ -180,12 +184,14 @@ describe("capabilityQuestions.vue", () => {
{
questionText:
"Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?",
+ selectedAnswer: "1|nextQuestion|3|Yes",
selectedAnswerText: "Yes",
questionNum: 1,
},
{
questionText:
"Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?",
+ selectedAnswer: "2|nextQuestion|3|Yes",
selectedAnswerText: "Yes",
questionNum: 2,
},
diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue
index c3122b9a3..d67f73838 100644
--- a/src/layouts/capability-questions/capability-questions.vue
+++ b/src/layouts/capability-questions/capability-questions.vue
@@ -112,7 +112,7 @@ export default {
"selectedAnswers." + glass.answerKey,
(newValue) => {
if (newValue && Object.keys(newValue).length > 0) {
- this.handleAnswerUpdates(newValue, glass.answerKey);
+ this.handleCompletedQuestionChainAnswers(newValue, glass.answerKey);
}
},
{ deep: true }
@@ -174,9 +174,7 @@ export default {
).parts = partFromCapabilityQuestionAnswer;
}
- // this.navigateForward(partsOrQuestions);
- // TODO KO delete after quote MVP
- this.navigateForward(partsOrQuestions, null, this.shouldGoToHeritageQuote);
+ this.navigateForward(partsOrQuestions);
},
},
components: {
diff --git a/src/layouts/estimate/estimate.spec.js b/src/layouts/estimate/estimate.spec.js
index 4e533bb70..c4b92830a 100644
--- a/src/layouts/estimate/estimate.spec.js
+++ b/src/layouts/estimate/estimate.spec.js
@@ -219,27 +219,32 @@ describe("estimate.vue", () => {
});
});
-describe("skipVinLookup", () => {
+describe("test alertInfo and isRepair", () => {
const skipOptions = [
- [true, true, true],
- [true, false, true],
- [false, true, true],
- [false, false, false],
+ [true, false, "AlertQuoteReady"],
+ [false, true, "AlertQuoteVinOptional"],
+ [false, false, "AlertQuoteReady"],
+ [true, true, "AlertQuoteVinOptional"],
];
test.each(skipOptions)(
- "isRepair %s and isVinOptional %s should return %s",
- async (isRepair, isVinOptionalVehicle, expectedVinSkip) => {
- const { wrapper } = setupMocks({ isVinOptionalVehicle: isVinOptionalVehicle });
+ "isRepair %s, skipVinNotRepair %s alertInfo should return %s",
+ async (isRepair, skipVinNotRepair, expectedAlertInfo) => {
+ const { wrapper } = setupMocks({});
+ await wrapper.setData({
+ skipVinNotRepair: skipVinNotRepair,
+ });
+
store.commit(storeMutations.UPDATE_IS_REPAIR, isRepair);
- expect(wrapper.vm.skipVinLookup).toEqual(expectedVinSkip);
+ expect(wrapper.vm.alertInfo).toEqual(expectedAlertInfo);
+ expect(wrapper.vm.isRepair).toEqual(isRepair);
}
);
});
function setupMocks({
groupName = "estimate",
- isVinOptionalVehicle = false,
+ skipVin = false,
cmsQuestionText = "Let's get your VIN. Or we can look it up for you!",
cmsAnswers = [
{ Name: "Provide my VIN manually Most specific to your vehicle" },
@@ -271,7 +276,10 @@ function setupMocks({
mountOptions["attachTo"] = document.body;
const wrapper = shallowMount(estimate, mountOptions);
- wrapper.vm.isVinOptionalVehicle = isVinOptionalVehicle;
+ wrapper.vm.skipVin = skipVin;
+ wrapper.vm.getZipCodeData = jest
+ .fn()
+ .mockReturnValue({ isValid: true, isServiceable: true, state: "OH" });
return { wrapper, apiPromise };
}
diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue
index 3d0d16b4a..e2e3cbb07 100644
--- a/src/layouts/estimate/estimate.vue
+++ b/src/layouts/estimate/estimate.vue
@@ -1,11 +1,12 @@