Merge remote-tracking branch 'origin/develop' into feature/CSR-1012
This commit is contained in:
commit
9fa85f6295
21 changed files with 283 additions and 150 deletions
|
|
@ -5,7 +5,10 @@ https://safelite.atlassian.net/wiki/spaces/DC/pages/76644418/Button+Question+Com
|
|||
:class="
|
||||
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>
|
||||
</div>
|
||||
|
||||
|
|
@ -124,6 +127,7 @@ export default {
|
|||
useTextForValue: Boolean,
|
||||
valueToLogType: String,
|
||||
additionalButtonStyling: String,
|
||||
isSmallQuestionText: Boolean,
|
||||
},
|
||||
beforeMount() {
|
||||
if (this.buttonTypeObject) {
|
||||
|
|
@ -137,13 +141,15 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
getFieldSetClasses() {
|
||||
if (this.isOverflowScrollable) {
|
||||
return "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0";
|
||||
} else if (this.buttonTypeString == "listCard") {
|
||||
return "w-100";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
const baseClasses = this.isOverflowScrollable
|
||||
? "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0"
|
||||
: this.buttonTypeString == "listCard"
|
||||
? "w-100"
|
||||
: "";
|
||||
const withSmallQuestionClass = this.isSmallQuestionText
|
||||
? baseClasses + " small-question-text"
|
||||
: baseClasses;
|
||||
return withSmallQuestionClass;
|
||||
},
|
||||
getComponentLoopWrapperClasses() {
|
||||
let classes;
|
||||
|
|
@ -210,7 +216,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
formatString(str) {
|
||||
return str?.replaceAll(" ", "-");
|
||||
return String(str).replaceAll(" ", "-");
|
||||
},
|
||||
setLastValuePushedToGa(lastValuePushedToGa) {
|
||||
this.lastValuePushedToGa = lastValuePushedToGa;
|
||||
|
|
@ -260,19 +266,18 @@ export default {
|
|||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.vehicle-parts {
|
||||
.question-text {
|
||||
.small-question-text {
|
||||
&.question-text {
|
||||
span {
|
||||
font-size: 0.875rem;
|
||||
text-align: left;
|
||||
margin: 0 0 0.5rem 0;
|
||||
margin: 1rem 0 0.5rem 0;
|
||||
}
|
||||
}
|
||||
.question-text {
|
||||
&.question-text {
|
||||
margin: 0;
|
||||
}
|
||||
fieldset {
|
||||
& fieldset {
|
||||
.ui-radio {
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
|
@ -107,6 +111,7 @@ async function getLatestPageForRedirection() {
|
|||
const capabilityQuestionsComponent = await getLazyLoadedComponent(
|
||||
fmgPageValues.CAPABILITY_QUESTIONS
|
||||
);
|
||||
const quoteComponent = await getLazyLoadedComponent(fmgPageValues.QUOTE);
|
||||
|
||||
const skipVin = await skipVinLookup();
|
||||
|
||||
|
|
@ -121,7 +126,9 @@ async function getLatestPageForRedirection() {
|
|||
} else if (!estimateComponent.methods.arePagePrerequisitesValid()) {
|
||||
return fmgPageValues.VEHICLE_DAMAGE;
|
||||
} else {
|
||||
if (capabilityQuestionsComponent.methods.arePagePrerequisitesValid()) {
|
||||
if (quoteComponent.methods.arePagePrerequisitesValid()) {
|
||||
return fmgPageValues.QUOTE;
|
||||
} else if (capabilityQuestionsComponent.methods.arePagePrerequisitesValid()) {
|
||||
return fmgPageValues.CAPABILITY_QUESTIONS;
|
||||
} else if (moldingQuestionsComponent.methods.arePagePrerequisitesValid()) {
|
||||
return fmgPageValues.MOLDING_QUESTIONS;
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export async function loadSessionIfPresent(isConceptInsurance) {
|
|||
funnelCookie.ReferralCorrelationId,
|
||||
isConceptInsurance
|
||||
)
|
||||
).data;
|
||||
)?.data;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIR
|
|||
defineRule(
|
||||
"email-address-format",
|
||||
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
|
||||
)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIR
|
|||
defineRule(
|
||||
"email-address-format",
|
||||
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
|
||||
)
|
||||
);
|
||||
|
|
@ -223,6 +223,25 @@ export default {
|
|||
} else if (this.$store.getters.order.referralNumber?.length === 6) {
|
||||
await this.navigateForwardWithSingleCarMatch();
|
||||
} 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
|
||||
await saveSession({});
|
||||
return this.$router.navigateWithoutSaving(
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIR
|
|||
defineRule(
|
||||
"email-address-format",
|
||||
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
|
||||
)
|
||||
);
|
||||
|
|
|
|||
128
src/layouts/quote/quote.spec.js
Normal file
128
src/layouts/quote/quote.spec.js
Normal 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 };
|
||||
}
|
||||
|
|
@ -183,6 +183,7 @@ export default {
|
|||
false
|
||||
);
|
||||
}
|
||||
|
||||
if (this.$store.getters.order.accountNumber != applicationConfig.CASH_ACCOUNT_NUMBER) {
|
||||
this.supportingItems = this.filterOutFees(this.supportingItems);
|
||||
}
|
||||
|
|
@ -193,7 +194,15 @@ export default {
|
|||
);
|
||||
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: {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
availableLineItems() {
|
||||
if (this.$store.getters.lineItems.supportingItems) {
|
||||
if (this.$store.getters.lineItems.vaps) {
|
||||
this.selectDefaultPackage();
|
||||
}
|
||||
},
|
||||
|
|
@ -213,18 +213,20 @@ export default {
|
|||
selectDefaultPackage() {
|
||||
const vapsFromStore = this.$store.getters.lineItems.vaps;
|
||||
let lowestTierForPackage = packageNames.TIER_ONE;
|
||||
vapsFromStore.every((vapsItem) => {
|
||||
let lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem);
|
||||
if (lowestTierForThisItem === packageNames.TIER_THREE) {
|
||||
lowestTierForPackage = packageNames.TIER_THREE;
|
||||
return false;
|
||||
} else if (lowestTierForThisItem === packageNames.TIER_TWO) {
|
||||
lowestTierForPackage = packageNames.TIER_TWO;
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (vapsFromStore.length > 0) {
|
||||
vapsFromStore.every((vapsItem) => {
|
||||
let lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem);
|
||||
if (lowestTierForThisItem === packageNames.TIER_THREE) {
|
||||
lowestTierForPackage = packageNames.TIER_THREE;
|
||||
return false;
|
||||
} else if (lowestTierForThisItem === packageNames.TIER_TWO) {
|
||||
lowestTierForPackage = packageNames.TIER_TWO;
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
this.selectedPackageName = lowestTierForPackage;
|
||||
},
|
||||
getLowestTierForThisItem(vapsItem) {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
|
||||
<div class="page-container-grouped-styles">
|
||||
<loadingModal ref="loadingModal" />
|
||||
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
|
||||
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
|
||||
<serviceZipModalQuestion
|
||||
|
|
@ -17,6 +18,7 @@
|
|||
workspaceRequirementsWidgetName="WorkspaceRequirementsWidget" />
|
||||
<funnel-footer
|
||||
cmsWidgetName="FunnelFooterWidget"
|
||||
ref="funnelFooter"
|
||||
:isForwardActionDisabled="!meta.valid"
|
||||
@back-clicked="backButtonAction"
|
||||
@ForwardClicked="forwardButtonAction" />
|
||||
|
|
@ -31,11 +33,11 @@ import mobileLocationModalQuestions from "@/layouts/service-location/mobile-loca
|
|||
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
||||
import funnelFooter from "@/fmg-components/funnel-footer/funnel-footer";
|
||||
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
||||
|
||||
//Supporting Files
|
||||
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
|
||||
import { Form } from "vee-validate";
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||
|
||||
export default {
|
||||
name: "service-location",
|
||||
|
|
@ -119,8 +121,13 @@ export default {
|
|||
arePagePrerequisitesValid() {
|
||||
return true;
|
||||
},
|
||||
backButtonAction() {},
|
||||
forwardButtonAction() {},
|
||||
|
||||
backButtonAction() {
|
||||
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||
},
|
||||
forwardButtonAction() {
|
||||
navigateToHeritageFunnel({ loadingModal: this.$refs.loadingModal });
|
||||
},
|
||||
},
|
||||
components: {
|
||||
serviceZipModalQuestion,
|
||||
|
|
@ -129,6 +136,7 @@ export default {
|
|||
funnelFooter,
|
||||
funnelSubHeader,
|
||||
Form,
|
||||
loadingModal,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
textPosition="text-start"
|
||||
:loaderEnabled="false"
|
||||
isRequired
|
||||
isSmallQuestionText
|
||||
:groupName="`${glassLocation}-${glassName}-${selectedTint}`"
|
||||
:validationRules="partValidationRules" />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<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" />
|
||||
<funnelHeader ref="funnelHeader" cmsWidgetName="FunnelHeaderWidget" />
|
||||
<vehicleBanner
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
fmg
|
||||
<template>
|
||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
|
||||
<div class="page-container-grouped-styles">
|
||||
|
|
@ -145,7 +144,7 @@ defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIR
|
|||
defineRule(
|
||||
"email-address-format",
|
||||
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
|
||||
)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -64,17 +64,14 @@ export default {
|
|||
};
|
||||
},
|
||||
getTierOnePackagePrice(lineItems) {
|
||||
let totalPrice = 0;
|
||||
lineItems.forEach((lineItem) => {
|
||||
const partType = lineItem.partType.toUpperCase();
|
||||
if (
|
||||
partType != partTypeStrings.FRONT_WIPER &&
|
||||
partType != partTypeStrings.REAR_WIPER &&
|
||||
partType != partTypeStrings.RAIN_DEFENSE
|
||||
) {
|
||||
totalPrice += this.getTotalLineItemPrice(lineItem);
|
||||
}
|
||||
let lineItemsToPrice = lineItems.filter((lineItem) => {
|
||||
return (
|
||||
lineItem.partType != partTypeStrings.FRONT_WIPER &&
|
||||
lineItem.partType != partTypeStrings.REAR_WIPER &&
|
||||
lineItem.partType != partTypeStrings.RAIN_DEFENSE
|
||||
);
|
||||
});
|
||||
let totalPrice = this.getTotalPriceOfAllLineItemsAndChildParts(lineItemsToPrice);
|
||||
return totalPrice;
|
||||
},
|
||||
filterOutFees(lineItems) {
|
||||
|
|
@ -86,6 +83,18 @@ export default {
|
|||
});
|
||||
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) {
|
||||
return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -485,11 +485,10 @@ export default {
|
|||
this.hasGlassLocationWithMultipleParts(allPartsOrQuestions);
|
||||
const hasChildPartQuestions = this.hasChildPartQuestions(allPartsOrQuestions);
|
||||
const hasCapabilityQuestions = this.hasCapabilityQuestions(allPartsOrQuestions);
|
||||
const skipVinLookup = await store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE);
|
||||
|
||||
const vin = self.$store.getters.vehicle.vin;
|
||||
let backNavigationScenario =
|
||||
!vin || vin === "" || skipVinLookup
|
||||
!vin || vin === ""
|
||||
? navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS
|
||||
: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ const fmgPageValues = {
|
|||
MOLDING_QUESTIONS: "molding-questions",
|
||||
CAPABILITY_QUESTIONS: "capability-questions",
|
||||
LICENSE_PLATE_LOOKUP: "license-plate-lookup",
|
||||
REVEAL: "reveal",
|
||||
ESTIMATE: "estimate",
|
||||
ADDRESS_VEHICLES: "address-vehicles",
|
||||
QUOTE: "quote",
|
||||
SERVICE_LOCATION: "service-location",
|
||||
HERITAGE: "heritage",
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ const navigationScenarios = {
|
|||
// General
|
||||
CLICKED_BACK: "CLICKED_BACK",
|
||||
CLICKED_FORWARD: "CLICKED_FORWARD",
|
||||
CLICKED_FORWARD_WITH_CASH: "CLICKED_FORWARD_WITH_CASH",
|
||||
|
||||
// YMMS
|
||||
SELECTED_YEAR: "SELECTED_YEAR",
|
||||
|
|
|
|||
|
|
@ -79,15 +79,6 @@ const routingTable = function (store) {
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
fmgPageValue: fmgPageValues.REVEAL,
|
||||
maps: [
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_BACK,
|
||||
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
fmgPageValue: fmgPageValues.VIN_LOOKUP,
|
||||
maps: [
|
||||
|
|
@ -305,10 +296,6 @@ const routingTable = function (store) {
|
|||
{
|
||||
fmgPageValue: fmgPageValues.VEHICLE_PARTS,
|
||||
maps: [
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||
destinationFmgPageValue: fmgPageValues.REVEAL,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS,
|
||||
destinationFmgPageValue: fmgPageValues.PART_QUESTIONS,
|
||||
|
|
@ -420,6 +407,19 @@ const routingTable = function (store) {
|
|||
scenario: navigationScenarios.CLICKED_BACK_WITH_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,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { experimentTriggers } from "@/constants/experiments";
|
|||
import { damageLocationsSelected } from "@/constants/damage-locations-selected";
|
||||
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
||||
import router from "@/router";
|
||||
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper.js";
|
||||
|
||||
// Export State
|
||||
const getDefaultState = () => {
|
||||
|
|
@ -1059,23 +1060,32 @@ export const actions = {
|
|||
referralCorrelationId: referralCorrelationId,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
// Flatten location and name properties
|
||||
response.data.order.damage?.glassToReplace?.map((glass) => {
|
||||
glass.glassLocation = glass.location;
|
||||
glass.glassName = glass.name;
|
||||
delete glass.location;
|
||||
delete glass.name;
|
||||
return glass;
|
||||
});
|
||||
.then(
|
||||
(response) => {
|
||||
// Flatten location and name properties
|
||||
response.data.order.damage?.glassToReplace?.map((glass) => {
|
||||
glass.glassLocation = glass.location;
|
||||
glass.glassName = glass.name;
|
||||
delete glass.location;
|
||||
delete glass.name;
|
||||
return glass;
|
||||
});
|
||||
|
||||
// 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) {
|
||||
// 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) {
|
||||
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.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data);
|
||||
return response;
|
||||
});
|
||||
);
|
||||
},
|
||||
|
||||
// Business domain actions
|
||||
|
|
@ -1422,7 +1432,7 @@ export const actions = {
|
|||
`${availableLineItemsFormattedForRequest}`;
|
||||
const lineItemServerData = context.getters.order.lineItems.serverData;
|
||||
if (lineItemServerData) {
|
||||
queryString += `&ServerData=${lineItemServerData}`;
|
||||
queryString += `&ServerData=${encodeURIComponent(lineItemServerData)}`;
|
||||
}
|
||||
const response = await globalMethods.callHttpClient({
|
||||
method: endpoints.PriceOrderItems.method,
|
||||
|
|
|
|||
|
|
@ -182,7 +182,9 @@ html {
|
|||
.form-test-error {
|
||||
color: $red;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
.small {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.form-test-invalid {
|
||||
|
|
|
|||
Loading…
Reference in a new issue