Merged from CSR-1012

This commit is contained in:
Leah Schumann 2023-02-14 08:25:04 -05:00
commit 6b24f56a2b
24 changed files with 290 additions and 150 deletions

View file

@ -5,7 +5,10 @@ https://safelite.atlassian.net/wiki/spaces/DC/pages/76644418/Button+Question+Com
:class=" :class="
isOverflowScrollable ? 'button-question button-question-overflow' : 'button-question' isOverflowScrollable ? 'button-question button-question-overflow' : 'button-question'
"> ">
<div v-if="questionText && answers && answers.length > 0" class="question-text d-flex"> <div
v-if="questionText && answers && answers.length > 0"
class="question-text d-flex"
:class="{ 'small-question-text': isSmallQuestionText }">
<span class="fw-bold w-100">{{ questionText }}</span> <span class="fw-bold w-100">{{ questionText }}</span>
</div> </div>
@ -124,6 +127,7 @@ export default {
useTextForValue: Boolean, useTextForValue: Boolean,
valueToLogType: String, valueToLogType: String,
additionalButtonStyling: String, additionalButtonStyling: String,
isSmallQuestionText: Boolean,
}, },
beforeMount() { beforeMount() {
if (this.buttonTypeObject) { if (this.buttonTypeObject) {
@ -137,13 +141,15 @@ export default {
}, },
computed: { computed: {
getFieldSetClasses() { getFieldSetClasses() {
if (this.isOverflowScrollable) { const baseClasses = this.isOverflowScrollable
return "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0"; ? "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0"
} else if (this.buttonTypeString == "listCard") { : this.buttonTypeString == "listCard"
return "w-100"; ? "w-100"
} else { : "";
return ""; const withSmallQuestionClass = this.isSmallQuestionText
} ? baseClasses + " small-question-text"
: baseClasses;
return withSmallQuestionClass;
}, },
getComponentLoopWrapperClasses() { getComponentLoopWrapperClasses() {
let classes; let classes;
@ -210,7 +216,7 @@ export default {
}, },
methods: { methods: {
formatString(str) { formatString(str) {
return str?.replaceAll(" ", "-"); return String(str).replaceAll(" ", "-");
}, },
setLastValuePushedToGa(lastValuePushedToGa) { setLastValuePushedToGa(lastValuePushedToGa) {
this.lastValuePushedToGa = lastValuePushedToGa; this.lastValuePushedToGa = lastValuePushedToGa;
@ -260,19 +266,18 @@ export default {
text-align: center; text-align: center;
} }
} }
.small-question-text {
.vehicle-parts { &.question-text {
.question-text {
span { span {
font-size: 0.875rem; font-size: 0.875rem;
text-align: left; text-align: left;
margin: 0 0 0.5rem 0; margin: 1rem 0 0.5rem 0;
} }
} }
.question-text { &.question-text {
margin: 0; margin: 0;
} }
fieldset { & fieldset {
.ui-radio { .ui-radio {
margin: 0; margin: 0;
} }

View file

@ -1,10 +1,13 @@
import { shallowMount } from "@vue/test-utils"; import { shallowMount } from "@vue/test-utils";
import Modal from "./modal"; import Modal from "./modal";
import crypto from "crypto";
const modalId = "modal-one"; const modalId = "modal-one";
const footerButtonText = "Sample footer text here."; const footerButtonText = "Sample footer text here.";
const headerText = "Sample header text here."; const headerText = "Sample header text here.";
global.crypto = crypto;
describe("modal.vue", () => { describe("modal.vue", () => {
it("Should display footer button text when footerButtonText is defined", async () => { it("Should display footer button text when footerButtonText is defined", async () => {
const wrapper = shallowMount(Modal, { const wrapper = shallowMount(Modal, {

View file

@ -1,5 +1,8 @@
import { mount } from "@vue/test-utils"; import { mount } from "@vue/test-utils";
import contentGroupModal from "./content-group-modal"; import contentGroupModal from "./content-group-modal";
import crypto from "crypto";
global.crypto = crypto;
describe("content-group-modal.vue", () => { describe("content-group-modal.vue", () => {
it("Should display header text when HeaderText is defined in the CMS", async () => { it("Should display header text when HeaderText is defined in the CMS", async () => {

View file

@ -28,7 +28,11 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita
// If navigating to a specific page, and that page is not part of the vin pages. // 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. // Return that page, so that it can navigate like normal.
if (toRoute.query[queryStrings.FMG_PAGE] !== undefined && !isVinRelatedPage(toRoute)) { if (
toRoute.query[queryStrings.FMG_PAGE] !== undefined &&
toRoute.query[queryStrings.FMG_PAGE] !== fmgPageValues.QUOTE &&
!isVinRelatedPage(toRoute)
) {
return overrideYmmsDirectionIfNeeded(toRoute); return overrideYmmsDirectionIfNeeded(toRoute);
} }
@ -107,6 +111,7 @@ async function getLatestPageForRedirection() {
const capabilityQuestionsComponent = await getLazyLoadedComponent( const capabilityQuestionsComponent = await getLazyLoadedComponent(
fmgPageValues.CAPABILITY_QUESTIONS fmgPageValues.CAPABILITY_QUESTIONS
); );
const quoteComponent = await getLazyLoadedComponent(fmgPageValues.QUOTE);
const skipVin = await skipVinLookup(); const skipVin = await skipVinLookup();
@ -121,7 +126,9 @@ async function getLatestPageForRedirection() {
} else if (!estimateComponent.methods.arePagePrerequisitesValid()) { } else if (!estimateComponent.methods.arePagePrerequisitesValid()) {
return fmgPageValues.VEHICLE_DAMAGE; return fmgPageValues.VEHICLE_DAMAGE;
} else { } else {
if (capabilityQuestionsComponent.methods.arePagePrerequisitesValid()) { if (quoteComponent.methods.arePagePrerequisitesValid()) {
return fmgPageValues.QUOTE;
} else if (capabilityQuestionsComponent.methods.arePagePrerequisitesValid()) {
return fmgPageValues.CAPABILITY_QUESTIONS; return fmgPageValues.CAPABILITY_QUESTIONS;
} else if (moldingQuestionsComponent.methods.arePagePrerequisitesValid()) { } else if (moldingQuestionsComponent.methods.arePagePrerequisitesValid()) {
return fmgPageValues.MOLDING_QUESTIONS; return fmgPageValues.MOLDING_QUESTIONS;

View file

@ -44,7 +44,7 @@ export async function loadSessionIfPresent(isConceptInsurance) {
funnelCookie.ReferralCorrelationId, funnelCookie.ReferralCorrelationId,
isConceptInsurance isConceptInsurance
) )
).data; )?.data;
} }
/* /*

View file

@ -56,7 +56,7 @@ defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIR
defineRule( defineRule(
"email-address-format", "email-address-format",
regex( regex(
/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]{2,})$/, /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/,
errorMessages.EMAIL_ADDRESS_FORMAT errorMessages.EMAIL_ADDRESS_FORMAT
) )
); );

View file

@ -120,7 +120,7 @@ defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIR
defineRule( defineRule(
"email-address-format", "email-address-format",
regex( regex(
/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]{2,})$/, /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/,
errorMessages.EMAIL_ADDRESS_FORMAT errorMessages.EMAIL_ADDRESS_FORMAT
) )
); );
@ -223,6 +223,25 @@ export default {
} else if (this.$store.getters.order.referralNumber?.length === 6) { } else if (this.$store.getters.order.referralNumber?.length === 6) {
await this.navigateForwardWithSingleCarMatch(); await this.navigateForwardWithSingleCarMatch();
} else if (this.isRepair) { } else if (this.isRepair) {
const supportingItemsPromise = await this.dispatchStoreAction(
storeActions.GET_SUPPORTING_ITEMS
);
const promiseResultMap = [
{
resultKey: "supportingItems",
promise: supportingItemsPromise,
},
];
const resultMap = await settleAllPromises(promiseResultMap);
this.dispatchStoreAction(
this.storeActions.SAVE_SUPPORTING_ITEMS,
resultMap.supportingItems,
false
);
// call saveSession here - navigateWithSaving saves too late in the flow // call saveSession here - navigateWithSaving saves too late in the flow
await saveSession({}); await saveSession({});
return this.$router.navigateWithoutSaving( return this.$router.navigateWithoutSaving(

View file

@ -120,7 +120,7 @@ defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIR
defineRule( defineRule(
"email-address-format", "email-address-format",
regex( regex(
/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]{2,})$/, /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/,
errorMessages.EMAIL_ADDRESS_FORMAT errorMessages.EMAIL_ADDRESS_FORMAT
) )
); );

View file

@ -0,0 +1,128 @@
import { shallowMount, flushPromises } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { applicationConfig } from "@/constants/application-config";
import quote from "@/layouts/quote/quote.vue";
import store from "@/store";
import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper";
jest.mock("@/store", () => ({
commit: jest.fn(),
dispatch: jest.fn(),
}));
// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
settleAllPromises: jest.fn(),
}));
// Mock fetchCmsContentForPage
jest.mock("@/helpers/cms-content-helper", () => ({
fetchCmsContentForPage: jest.fn(),
}));
jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({
navigateToHeritageFunnel: jest.fn(),
}));
jest.mock(
"@/store",
() => {
return {};
},
{ virtual: true }
);
store.getters = {
order: {
accountNumber: applicationConfig.CASH_ACCOUNT_NUMBER,
},
payment: {
insuranceCoverage: {},
isInsurance: false,
},
};
afterEach(() => {
// reset store after each test
store.getters = {
order: {
accountNumber: applicationConfig.CASH_ACCOUNT_NUMBER,
},
payment: {
insuranceCoverage: {},
isInsurance: false,
},
};
});
describe("quote.vue", () => {
test("IsInsurance false should navigateWithSaving", async () => {
//Arrange
const { wrapper } = setupMocks({
customMountOptions: {
router: {
navigateWithSaving: jest.fn(),
},
route: { quote },
},
});
store.getters.payment = {
insuranceCoverage: {},
isInsurance: false,
};
wrapper.vm.dispatchStoreAction = jest.fn(() => {
return {
data: [],
};
});
//Act
await wrapper.vm.forwardButtonAction();
//Assert
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
});
test("IsInsurance true should navigateToHeritageFunnel", async () => {
//Arrange
const { wrapper } = setupMocks({
customMountOptions: {
router: {
navigateWithSaving: jest.fn(),
},
route: { quote },
},
});
store.getters.payment = {
insuranceCoverage: {},
isInsurance: true,
};
wrapper.vm.dispatchStoreAction = jest.fn(() => {
return {
data: [],
};
});
//Act
await wrapper.vm.forwardButtonAction();
//Assert
expect(navigateToHeritage.navigateToHeritageFunnel).toHaveBeenCalled();
});
});
function setupMocks({ customMountOptions }) {
const mountOptions = getMountOptions({
...customMountOptions,
});
mountOptions.global.mocks["$store"] = store;
mountOptions["attachTo"] = document.body;
const wrapper = shallowMount(quote, mountOptions);
return { wrapper };
}

View file

@ -183,6 +183,7 @@ export default {
false false
); );
} }
if (this.$store.getters.order.accountNumber != applicationConfig.CASH_ACCOUNT_NUMBER) { if (this.$store.getters.order.accountNumber != applicationConfig.CASH_ACCOUNT_NUMBER) {
this.supportingItems = this.filterOutFees(this.supportingItems); this.supportingItems = this.filterOutFees(this.supportingItems);
} }
@ -193,7 +194,15 @@ export default {
); );
this.dispatchStoreAction(this.storeActions.SAVE_VAPS, this.selectedVaps, false); this.dispatchStoreAction(this.storeActions.SAVE_VAPS, this.selectedVaps, false);
navigateToHeritageFunnel({ loadingModal: this.$refs.loadingModal }); const payment = this.$store.getters.payment;
if (payment.isInsurance) {
navigateToHeritageFunnel({ loadingModal: this.$refs.loadingModal });
} else {
this.$router.navigateWithSaving(
this.navigationScenarios.CLICKED_FORWARD_WITH_CASH,
this.$route
);
}
}, },
}, },
components: { components: {

View file

@ -43,7 +43,7 @@ export default {
}, },
watch: { watch: {
availableLineItems() { availableLineItems() {
if (this.$store.getters.lineItems.supportingItems) { if (this.$store.getters.lineItems.vaps) {
this.selectDefaultPackage(); this.selectDefaultPackage();
} }
}, },
@ -213,18 +213,20 @@ export default {
selectDefaultPackage() { selectDefaultPackage() {
const vapsFromStore = this.$store.getters.lineItems.vaps; const vapsFromStore = this.$store.getters.lineItems.vaps;
let lowestTierForPackage = packageNames.TIER_ONE; let lowestTierForPackage = packageNames.TIER_ONE;
vapsFromStore.every((vapsItem) => { if (vapsFromStore.length > 0) {
let lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem); vapsFromStore.every((vapsItem) => {
if (lowestTierForThisItem === packageNames.TIER_THREE) { let lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem);
lowestTierForPackage = packageNames.TIER_THREE; if (lowestTierForThisItem === packageNames.TIER_THREE) {
return false; lowestTierForPackage = packageNames.TIER_THREE;
} else if (lowestTierForThisItem === packageNames.TIER_TWO) { return false;
lowestTierForPackage = packageNames.TIER_TWO; } else if (lowestTierForThisItem === packageNames.TIER_TWO) {
return true; lowestTierForPackage = packageNames.TIER_TWO;
} else { return true;
return true; } else {
} return true;
}); }
});
}
this.selectedPackageName = lowestTierForPackage; this.selectedPackageName = lowestTierForPackage;
}, },
getLowestTierForThisItem(vapsItem) { getLowestTierForThisItem(vapsItem) {

View file

@ -1,66 +0,0 @@
<template>
<div class="container-fluid shadow rounded-3 p-2 position-relative make-tall">
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
<h1>Reveal Confetti Page Placeholder</h1>
<funnelFooter
cmsWidgetName="FunnelFooterWidget"
ref="funnelFooter"
@back-clicked="backButtonAction" />
</div>
</template>
<script>
// Components
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import funnelFooter from "@/fmg-components/funnel-footer/funnel-footer";
// Supporting Files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import { storeMutations } from "@/constants/store-mutations";
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
export default {
name: "quote",
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);
});
},
methods: {
backButtonAction() {
// route to move backwards
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
},
arePagePrerequisitesValid() {
return true;
},
resetDependentState() {
// Set
store.commit(storeMutations.UPDATE_GLASS_PARTS, null);
// Invokes
store.dispatch(storeActions.RESET_PARTS_AND_DEPS);
},
},
data() {},
components: {
funnelHeader,
funnelFooter,
},
};
</script>

View file

@ -1,6 +1,7 @@
<template> <template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }"> <Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<div class="page-container-grouped-styles"> <div class="page-container-grouped-styles">
<loadingModal ref="loadingModal" />
<funnelHeader cmsWidgetName="FunnelHeaderWidget" /> <funnelHeader cmsWidgetName="FunnelHeaderWidget" />
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" /> <funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
<serviceZipModalQuestion <serviceZipModalQuestion
@ -17,6 +18,7 @@
workspaceRequirementsWidgetName="WorkspaceRequirementsWidget" /> workspaceRequirementsWidgetName="WorkspaceRequirementsWidget" />
<funnel-footer <funnel-footer
cmsWidgetName="FunnelFooterWidget" cmsWidgetName="FunnelFooterWidget"
ref="funnelFooter"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@back-clicked="backButtonAction" @back-clicked="backButtonAction"
@ForwardClicked="forwardButtonAction" /> @ForwardClicked="forwardButtonAction" />
@ -31,11 +33,11 @@ import mobileLocationModalQuestions from "@/layouts/service-location/mobile-loca
import funnelHeader from "@/fmg-components/funnel-header/funnel-header"; import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import funnelFooter from "@/fmg-components/funnel-footer/funnel-footer"; import funnelFooter from "@/fmg-components/funnel-footer/funnel-footer";
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header"; import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
//Supporting Files
import { Form } from "vee-validate"; import { Form } from "vee-validate";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper"; import { settleAllPromises } from "@/helpers/layout-helper";
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
export default { export default {
name: "service-location", name: "service-location",
@ -119,8 +121,13 @@ export default {
arePagePrerequisitesValid() { arePagePrerequisitesValid() {
return true; return true;
}, },
backButtonAction() {},
forwardButtonAction() {}, backButtonAction() {
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
},
forwardButtonAction() {
navigateToHeritageFunnel({ loadingModal: this.$refs.loadingModal });
},
}, },
components: { components: {
serviceZipModalQuestion, serviceZipModalQuestion,
@ -129,6 +136,7 @@ export default {
funnelFooter, funnelFooter,
funnelSubHeader, funnelSubHeader,
Form, Form,
loadingModal,
}, },
}; };
</script> </script>

View file

@ -120,6 +120,7 @@ export default {
}, },
onModalOpened() { onModalOpened() {
this.serviceZipCodeInput = this.serviceZipModel.zipCode;
this.focusOnZipInput(); this.focusOnZipInput();
}, },

View file

@ -25,6 +25,7 @@
textPosition="text-start" textPosition="text-start"
:loaderEnabled="false" :loaderEnabled="false"
isRequired isRequired
isSmallQuestionText
:groupName="`${glassLocation}-${glassName}-${selectedTint}`" :groupName="`${glassLocation}-${glassName}-${selectedTint}`"
:validationRules="partValidationRules" /> :validationRules="partValidationRules" />
</div> </div>

View file

@ -1,6 +1,6 @@
<template> <template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm"> <Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm">
<div class="page-container-grouped-styles vehicle-parts"> <div class="page-container-grouped-styles vehicle-parts small-question-text">
<loadingModal ref="loadingModal" /> <loadingModal ref="loadingModal" />
<funnelHeader ref="funnelHeader" cmsWidgetName="FunnelHeaderWidget" /> <funnelHeader ref="funnelHeader" cmsWidgetName="FunnelHeaderWidget" />
<vehicleBanner <vehicleBanner

View file

@ -1,4 +1,3 @@
fmg
<template> <template>
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }"> <Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
<div class="page-container-grouped-styles"> <div class="page-container-grouped-styles">
@ -145,7 +144,7 @@ defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIR
defineRule( defineRule(
"email-address-format", "email-address-format",
regex( regex(
/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]{2,})$/, /^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/,
errorMessages.EMAIL_ADDRESS_FORMAT errorMessages.EMAIL_ADDRESS_FORMAT
) )
); );

View file

@ -64,17 +64,14 @@ export default {
}; };
}, },
getTierOnePackagePrice(lineItems) { getTierOnePackagePrice(lineItems) {
let totalPrice = 0; let lineItemsToPrice = lineItems.filter((lineItem) => {
lineItems.forEach((lineItem) => { return (
const partType = lineItem.partType.toUpperCase(); lineItem.partType != partTypeStrings.FRONT_WIPER &&
if ( lineItem.partType != partTypeStrings.REAR_WIPER &&
partType != partTypeStrings.FRONT_WIPER && lineItem.partType != partTypeStrings.RAIN_DEFENSE
partType != partTypeStrings.REAR_WIPER && );
partType != partTypeStrings.RAIN_DEFENSE
) {
totalPrice += this.getTotalLineItemPrice(lineItem);
}
}); });
let totalPrice = this.getTotalPriceOfAllLineItemsAndChildParts(lineItemsToPrice);
return totalPrice; return totalPrice;
}, },
filterOutFees(lineItems) { filterOutFees(lineItems) {
@ -86,6 +83,18 @@ export default {
}); });
return filteredLineItems; return filteredLineItems;
}, },
getTotalPriceOfAllLineItemsAndChildParts(lineItems) {
let totalPrice = 0;
lineItems.forEach((lineItem) => {
totalPrice += this.getTotalLineItemPrice(lineItem);
if (lineItem.childParts) {
totalPrice += this.getTotalPriceOfAllLineItemsAndChildParts(
lineItem.childParts
);
}
});
return totalPrice;
},
getTotalLineItemPrice(lineItem) { getTotalLineItemPrice(lineItem) {
return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice; return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice;
}, },

View file

@ -485,11 +485,10 @@ export default {
this.hasGlassLocationWithMultipleParts(allPartsOrQuestions); this.hasGlassLocationWithMultipleParts(allPartsOrQuestions);
const hasChildPartQuestions = this.hasChildPartQuestions(allPartsOrQuestions); const hasChildPartQuestions = this.hasChildPartQuestions(allPartsOrQuestions);
const hasCapabilityQuestions = this.hasCapabilityQuestions(allPartsOrQuestions); const hasCapabilityQuestions = this.hasCapabilityQuestions(allPartsOrQuestions);
const skipVinLookup = await store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE);
const vin = self.$store.getters.vehicle.vin; const vin = self.$store.getters.vehicle.vin;
let backNavigationScenario = let backNavigationScenario =
!vin || vin === "" || skipVinLookup !vin || vin === ""
? navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS ? navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS
: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS; : navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS;

View file

@ -11,10 +11,10 @@ const fmgPageValues = {
MOLDING_QUESTIONS: "molding-questions", MOLDING_QUESTIONS: "molding-questions",
CAPABILITY_QUESTIONS: "capability-questions", CAPABILITY_QUESTIONS: "capability-questions",
LICENSE_PLATE_LOOKUP: "license-plate-lookup", LICENSE_PLATE_LOOKUP: "license-plate-lookup",
REVEAL: "reveal",
ESTIMATE: "estimate", ESTIMATE: "estimate",
ADDRESS_VEHICLES: "address-vehicles", ADDRESS_VEHICLES: "address-vehicles",
QUOTE: "quote", QUOTE: "quote",
SERVICE_LOCATION: "service-location",
HERITAGE: "heritage", HERITAGE: "heritage",
}; };

View file

@ -10,6 +10,7 @@ const navigationScenarios = {
// General // General
CLICKED_BACK: "CLICKED_BACK", CLICKED_BACK: "CLICKED_BACK",
CLICKED_FORWARD: "CLICKED_FORWARD", CLICKED_FORWARD: "CLICKED_FORWARD",
CLICKED_FORWARD_WITH_CASH: "CLICKED_FORWARD_WITH_CASH",
// YMMS // YMMS
SELECTED_YEAR: "SELECTED_YEAR", SELECTED_YEAR: "SELECTED_YEAR",

View file

@ -79,15 +79,6 @@ const routingTable = function (store) {
}, },
], ],
}, },
{
fmgPageValue: fmgPageValues.REVEAL,
maps: [
{
scenario: navigationScenarios.CLICKED_BACK,
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
},
],
},
{ {
fmgPageValue: fmgPageValues.VIN_LOOKUP, fmgPageValue: fmgPageValues.VIN_LOOKUP,
maps: [ maps: [
@ -305,10 +296,6 @@ const routingTable = function (store) {
{ {
fmgPageValue: fmgPageValues.VEHICLE_PARTS, fmgPageValue: fmgPageValues.VEHICLE_PARTS,
maps: [ maps: [
{
scenario: navigationScenarios.CLICKED_FORWARD,
destinationFmgPageValue: fmgPageValues.REVEAL,
},
{ {
scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS,
destinationFmgPageValue: fmgPageValues.PART_QUESTIONS, destinationFmgPageValue: fmgPageValues.PART_QUESTIONS,
@ -420,6 +407,19 @@ const routingTable = function (store) {
scenario: navigationScenarios.CLICKED_BACK_WITH_CAPABILITY_QUESTIONS, scenario: navigationScenarios.CLICKED_BACK_WITH_CAPABILITY_QUESTIONS,
destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS, destinationFmgPageValue: fmgPageValues.CAPABILITY_QUESTIONS,
}, },
{
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CASH,
destinationFmgPageValue: fmgPageValues.SERVICE_LOCATION,
},
],
},
{
fmgPageValue: fmgPageValues.SERVICE_LOCATION,
maps: [
{
scenario: navigationScenarios.CLICKED_BACK,
destinationFmgPageValue: fmgPageValues.QUOTE,
},
], ],
}, },
]; ];

View file

@ -10,6 +10,7 @@ import { experimentTriggers } from "@/constants/experiments";
import { damageLocationsSelected } from "@/constants/damage-locations-selected"; import { damageLocationsSelected } from "@/constants/damage-locations-selected";
import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
import router from "@/router"; import router from "@/router";
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper.js";
// Export State // Export State
const getDefaultState = () => { const getDefaultState = () => {
@ -1059,23 +1060,32 @@ export const actions = {
referralCorrelationId: referralCorrelationId, referralCorrelationId: referralCorrelationId,
}, },
}) })
.then((response) => { .then(
// Flatten location and name properties (response) => {
response.data.order.damage?.glassToReplace?.map((glass) => { // Flatten location and name properties
glass.glassLocation = glass.location; response.data.order.damage?.glassToReplace?.map((glass) => {
glass.glassName = glass.name; glass.glassLocation = glass.location;
delete glass.location; glass.glassName = glass.name;
delete glass.name; delete glass.location;
return glass; delete glass.name;
}); return glass;
});
// clear the state if the existing EON does not equal what is returned from loadSession // clear the state if the existing EON does not equal what is returned from loadSession
if (context.state.order.eon && context.state.order.eon != response.data.eon) { if (context.state.order.eon && context.state.order.eon != response.data.eon) {
context.commit(storeMutations.RESET_STATE);
}
context.commit(
storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION,
response.data
);
return response;
},
(error) => {
deleteFunnelCookie();
context.commit(storeMutations.RESET_STATE); context.commit(storeMutations.RESET_STATE);
} }
context.commit(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data); );
return response;
});
}, },
// Business domain actions // Business domain actions
@ -1422,7 +1432,7 @@ export const actions = {
`${availableLineItemsFormattedForRequest}`; `${availableLineItemsFormattedForRequest}`;
const lineItemServerData = context.getters.order.lineItems.serverData; const lineItemServerData = context.getters.order.lineItems.serverData;
if (lineItemServerData) { if (lineItemServerData) {
queryString += `&ServerData=${lineItemServerData}`; queryString += `&ServerData=${encodeURIComponent(lineItemServerData)}`;
} }
const response = await globalMethods.callHttpClient({ const response = await globalMethods.callHttpClient({
method: endpoints.PriceOrderItems.method, method: endpoints.PriceOrderItems.method,

View file

@ -182,7 +182,9 @@ html {
.form-test-error { .form-test-error {
color: $red; color: $red;
font-size: 0.875rem; font-size: 0.875rem;
font-weight: 500; .small {
font-weight: 500;
}
} }
.form-test-invalid { .form-test-invalid {