Merge branch 'develop' into feature/digital/SSR-405
This commit is contained in:
commit
fab40c327a
13 changed files with 470 additions and 85 deletions
|
|
@ -21,7 +21,7 @@ export default {
|
||||||
url: cfDistroUrl + endpoint,
|
url: cfDistroUrl + endpoint,
|
||||||
data: payloadAndAnalyticsData,
|
data: payloadAndAnalyticsData,
|
||||||
crossDomain: true,
|
crossDomain: true,
|
||||||
responseType: {},
|
responseType: 'json',
|
||||||
headers: headers,
|
headers: headers,
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
|
|
|
||||||
69
src/layouts/order-confirmation/order-confirmation.vue
Normal file
69
src/layouts/order-confirmation/order-confirmation.vue
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
<template>
|
||||||
|
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
||||||
|
<div class="page-container-grouped-styles">
|
||||||
|
<div class="fade-on-route-transition position-relative">
|
||||||
|
<siteHeader cmsWidgetName="SiteHeaderWidget"/>
|
||||||
|
<div class="container-fluid pb-2">
|
||||||
|
<p>Placeholder for order confirmation page</p>
|
||||||
|
<siteFooter
|
||||||
|
cmsWidgetName="SiteFooterWidget"
|
||||||
|
ref="siteFooter"
|
||||||
|
:isForwardActionDisabled="!meta.valid"
|
||||||
|
@ForwardClicked="forwardButtonAction"
|
||||||
|
@back-clicked="backButtonAction"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
// Components
|
||||||
|
import siteHeader from '@/iss-components/site-header/site-header';
|
||||||
|
import siteFooter from "@/iss-components/site-footer/site-footer";
|
||||||
|
// Supporting files
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import { Form } from "vee-validate";
|
||||||
|
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||||
|
export default {
|
||||||
|
name: "order-confirmation",
|
||||||
|
mixins: [BaseFormMixin],
|
||||||
|
async beforeRouteEnter(to, from, next)
|
||||||
|
{
|
||||||
|
// Call APIs
|
||||||
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
// Settle promises and get results
|
||||||
|
const promiseResultMap = [
|
||||||
|
{
|
||||||
|
resultKey: "cmsContent",
|
||||||
|
promise: cmsContentPromise,
|
||||||
|
},];
|
||||||
|
//use resultMap to populate layout content.
|
||||||
|
let resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
next((vm) => {
|
||||||
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods:
|
||||||
|
{
|
||||||
|
backButtonAction() {
|
||||||
|
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||||
|
},
|
||||||
|
forwardButtonAction() {
|
||||||
|
return this.navigateForward();
|
||||||
|
},
|
||||||
|
navigateForward() {
|
||||||
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.CLICKED_FORWARD,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
siteHeader,
|
||||||
|
siteFooter,
|
||||||
|
Form,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<template>
|
||||||
|
<buttonQuestion
|
||||||
|
:questionText="questionText"
|
||||||
|
ref="policyVehiclesQuestion"
|
||||||
|
buttonTypeString="listButton"
|
||||||
|
isOverflowScrollable
|
||||||
|
:answers="answers"
|
||||||
|
isRequired />
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import buttonQuestion from "@/digital-components/button-question/button-question";
|
||||||
|
|
||||||
|
export default ({
|
||||||
|
name: "policy-vehicles-question",
|
||||||
|
components: {
|
||||||
|
buttonQuestion,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
questionText() {
|
||||||
|
return this.getCmsContent("PolicyVehiclesQuestion", "QuestionText");
|
||||||
|
},
|
||||||
|
answers(){
|
||||||
|
return this.getCmsContent("PolicyVehiclesQuestion", "Answers");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
71
src/layouts/policy-vehicles/policy-vehicles.vue
Normal file
71
src/layouts/policy-vehicles/policy-vehicles.vue
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
<template>
|
||||||
|
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
||||||
|
<div class="page-container-grouped-styles">
|
||||||
|
<div class="fade-on-route-transition position-relative">
|
||||||
|
<siteHeader cmsWidgetName="SiteHeaderWidget"/>
|
||||||
|
<div class="select-car">
|
||||||
|
<div class="container-fluid pb-2">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="select-car-form rounded text-center">
|
||||||
|
<vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage="true" class="mb-3" />
|
||||||
|
<policyVehiclesQuestion class="px-4" cmsWidgetName="PolicyVehiclesQuestion"/>
|
||||||
|
<siteFooter cmsWidgetName="SiteFooterWidget" ref="siteFooter" :isForwardActionDisabled="!meta.valid" @ForwardClicked="forwardButtonAction" @back-clicked="backButtonAction"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
// Components
|
||||||
|
import siteHeader from '@/iss-components/site-header/site-header';
|
||||||
|
import siteFooter from "@/iss-components/site-footer/site-footer";
|
||||||
|
import vehicleBanner from "@/iss-components/vehicle-banner/vehicle-banner";
|
||||||
|
import policyVehiclesQuestion from "@/layouts/policy-vehicles/policy-vehicles-question/policy-vehicles-question";
|
||||||
|
// Supporting files
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import { Form } from "vee-validate";
|
||||||
|
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||||
|
export default {
|
||||||
|
name: "policy-vehicles",
|
||||||
|
mixins: [BaseFormMixin],
|
||||||
|
async beforeRouteEnter(to, from, next)
|
||||||
|
{
|
||||||
|
// Call APIs
|
||||||
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
// Settle promises and get results
|
||||||
|
const promiseResultMap = [
|
||||||
|
{
|
||||||
|
resultKey: "cmsContent",
|
||||||
|
promise: cmsContentPromise,
|
||||||
|
},];
|
||||||
|
//use resultMap to populate layout content.
|
||||||
|
let resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
next((vm) => {
|
||||||
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods:
|
||||||
|
{
|
||||||
|
backButtonAction() {
|
||||||
|
},
|
||||||
|
forwardButtonAction() {
|
||||||
|
return this.navigateForward();
|
||||||
|
},
|
||||||
|
navigateForward() {
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
siteHeader,
|
||||||
|
siteFooter,
|
||||||
|
vehicleBanner,
|
||||||
|
policyVehiclesQuestion,
|
||||||
|
Form,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -1,6 +1,34 @@
|
||||||
import { shallowMount } from "@vue/test-utils";
|
import { shallowMount } from "@vue/test-utils";
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
import serviceLocation from "@/layouts/service-location/service-location.vue";
|
import serviceLocation from "@/layouts/service-location/service-location.vue";
|
||||||
|
import { getServiceabilityDetails, getZipCodeData } from "@/helpers/service-location-helper";
|
||||||
|
|
||||||
|
// Define Mocks
|
||||||
|
jest.mock("@/helpers/cms-content-helper", () => ({
|
||||||
|
fetchCmsContentForPage: jest.fn(() => {
|
||||||
|
return Promise.resolve("content");
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const mockGetServiceabilityDetails = (mockServiceZipCode) => {
|
||||||
|
const serviceabilityDetails = {
|
||||||
|
isGlassServiceableInshop: true,
|
||||||
|
isRecalibrationServiceableInshop: true,
|
||||||
|
isGlassServiceableMobile: true,
|
||||||
|
isRecalibrationServiceableMobile: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Promise.resolve(serviceabilityDetails);
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.mock(
|
||||||
|
"@/helpers/service-location-helper",
|
||||||
|
() => ({
|
||||||
|
getServiceabilityDetails: jest.fn((mockServiceZipCode) => {
|
||||||
|
return mockGetServiceabilityDetails(mockServiceZipCode);
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const mockMixin = {
|
const mockMixin = {
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -26,6 +54,14 @@ const mockMixin = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zip === "45433") {
|
||||||
|
return Promise.resolve({
|
||||||
|
containsMilitaryBase: true,
|
||||||
|
isValid: true,
|
||||||
|
state: "OH",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
containsMilitaryBase: false,
|
containsMilitaryBase: false,
|
||||||
isValid: false,
|
isValid: false,
|
||||||
|
|
@ -98,6 +134,34 @@ describe("updating service zip", () => {
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.selectedAppointmentType).toStrictEqual(null);
|
expect(wrapper.vm.selectedAppointmentType).toStrictEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("displays military zip message when zip is updated", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
const mobileLocationQuestionsComponent = wrapper.findComponent({
|
||||||
|
ref: "mobileLocationQuestions",
|
||||||
|
});
|
||||||
|
mobileLocationQuestionsComponent.resetComponent = jest.fn();
|
||||||
|
|
||||||
|
const serviceZipCodeComponent = wrapper.findComponent({
|
||||||
|
ref: "serviceZipCodeQuestion",
|
||||||
|
});
|
||||||
|
serviceZipCodeComponent.resetMobileFeePart = jest.fn();
|
||||||
|
|
||||||
|
expect(wrapper.vm.zipContainsMilitaryBase).toBe(false);
|
||||||
|
|
||||||
|
const newServiceZipCodeQuestion = {
|
||||||
|
zipCode: "45433",
|
||||||
|
state: "OH",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
serviceZipCodeComponent.vm.$emit("updated-contains-military-base", true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.zipContainsMilitaryBase).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks()
|
function setupMocks()
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,15 @@
|
||||||
<serviceZipModalQuestion
|
<serviceZipModalQuestion
|
||||||
v-model="serviceZipCodeQuestion"
|
v-model="serviceZipCodeQuestion"
|
||||||
ref="serviceZipCodeQuestion"
|
ref="serviceZipCodeQuestion"
|
||||||
|
@updated-serviceability="setServiceabilityDetails"
|
||||||
|
@updated-contains-military-base="setContainsMilitaryBase"
|
||||||
modalWidgetName="ServiceZipModalWidget" />
|
modalWidgetName="ServiceZipModalWidget" />
|
||||||
|
<alert
|
||||||
|
ref="alertMilitaryBaseZip"
|
||||||
|
class="my-5"
|
||||||
|
cmsWidgetName="AlertMilitaryBaseZipWidget"
|
||||||
|
v-if="displayMilitaryZipAlert"
|
||||||
|
alertClass="alert-warning" />
|
||||||
<buttonQuestion
|
<buttonQuestion
|
||||||
cmsWidgetName="ServiceTypeQuestionWidget"
|
cmsWidgetName="ServiceTypeQuestionWidget"
|
||||||
:questionText="questionText"
|
:questionText="questionText"
|
||||||
|
|
@ -58,6 +66,7 @@ import { useMainStore } from "@/store";
|
||||||
import { getServiceabilityDetails, getZipCodeData } from "@/helpers/service-location-helper";
|
import { getServiceabilityDetails, getZipCodeData } from "@/helpers/service-location-helper";
|
||||||
|
|
||||||
// Import Component
|
// Import Component
|
||||||
|
import alert from "@/ux-components/alert/alert";
|
||||||
import baseFormMixin from "@/mixins/base-form-mixin";
|
import baseFormMixin from "@/mixins/base-form-mixin";
|
||||||
import baseMixin from "@/mixins/base-mixin";
|
import baseMixin from "@/mixins/base-mixin";
|
||||||
import { Form, defineRule } from "vee-validate";
|
import { Form, defineRule } from "vee-validate";
|
||||||
|
|
@ -100,6 +109,10 @@ export default {
|
||||||
|
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
vm.setData(
|
||||||
|
resultMap.zipCodeData,
|
||||||
|
resultMap.serviceabilityDetails,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
|
@ -111,7 +124,10 @@ export default {
|
||||||
zipCode: this.mainStore.order.customer.address.zipCode,
|
zipCode: this.mainStore.order.customer.address.zipCode,
|
||||||
state: this.mainStore.order.customer.address.state,
|
state: this.mainStore.order.customer.address.state,
|
||||||
isServiceZipServiceable: null,
|
isServiceZipServiceable: null,
|
||||||
|
isGlassServiceableMobile: null,
|
||||||
|
isRecalibrationServiceableMobile: null,
|
||||||
selectedAppointmentType: "",
|
selectedAppointmentType: "",
|
||||||
|
zipContainsMilitaryBase: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -138,6 +154,16 @@ export default {
|
||||||
|
|
||||||
this.$nextTick();
|
this.$nextTick();
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
isServiceableMobile() {
|
||||||
|
if (this.isRecalibrationServiceableMobile !== null) {
|
||||||
|
return this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile;
|
||||||
|
} else {
|
||||||
|
return this.isGlassServiceableMobile;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
displayMilitaryZipAlert() {
|
||||||
|
return this.zipContainsMilitaryBase && this.isServiceableMobile;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -154,7 +180,30 @@ export default {
|
||||||
//validate and save data here
|
//validate and save data here
|
||||||
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||||
},
|
},
|
||||||
resetDependentState() {},
|
resetDependentState() {
|
||||||
|
|
||||||
|
},
|
||||||
|
setData(zipCodeData, serviceabilityDetails) {
|
||||||
|
if (zipCodeData) {
|
||||||
|
this.zipContainsMilitaryBase = zipCodeData.containsMilitaryBase;
|
||||||
|
}
|
||||||
|
if (serviceabilityDetails) {
|
||||||
|
this.setServiceabilityDetails(serviceabilityDetails);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setContainsMilitaryBase(val) {
|
||||||
|
if (this.zipContainsMilitaryBase !== val) {
|
||||||
|
this.zipContainsMilitaryBase = val;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setServiceabilityDetails(serviceabilityDetails) {
|
||||||
|
this.isGlassServiceableInshop = serviceabilityDetails.isGlassServiceableInshop;
|
||||||
|
this.isRecalibrationServiceableInshop =
|
||||||
|
serviceabilityDetails.isRecalibrationServiceableInshop;
|
||||||
|
this.isGlassServiceableMobile = serviceabilityDetails.isGlassServiceableMobile;
|
||||||
|
this.isRecalibrationServiceableMobile =
|
||||||
|
serviceabilityDetails.isRecalibrationServiceableMobile;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
siteFooter,
|
siteFooter,
|
||||||
|
|
@ -163,6 +212,7 @@ export default {
|
||||||
buttonQuestion,
|
buttonQuestion,
|
||||||
Form,
|
Form,
|
||||||
serviceZipModalQuestion,
|
serviceZipModalQuestion,
|
||||||
|
alert
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
};
|
};
|
||||||
export default {
|
export default {
|
||||||
name: 'servicePackageQuestion',
|
name: 'servicePackageQuestion',
|
||||||
|
emits: ['vapsItemsSelected'],
|
||||||
props: {
|
props: {
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String,
|
||||||
groupName: String,
|
groupName: String,
|
||||||
|
|
@ -34,16 +35,10 @@
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
servicePackageRadio: servicePackageRadio,
|
servicePackageRadio: servicePackageRadio,
|
||||||
selectedPackageName: null
|
selectedPackageName: packageNames.TIER_ONE
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
availableLineItems() {
|
|
||||||
const store = useMainStore();
|
|
||||||
if (this.allGlassPartsAndSupportingItemsHavePrices(store.order.lineItems)) {
|
|
||||||
this.selectDefaultPackage();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectedPackageName(newValue) {
|
selectedPackageName(newValue) {
|
||||||
const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue);
|
const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue);
|
||||||
this.$emit('vapsItemsSelected', VapsProductsInSelectedPackage);
|
this.$emit('vapsItemsSelected', VapsProductsInSelectedPackage);
|
||||||
|
|
@ -51,10 +46,14 @@
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
nullSafeAvailableLineItems() {
|
nullSafeAvailableLineItems() {
|
||||||
|
if (this.availableLineItems?.lineItems) {
|
||||||
|
return this.availableLineItems.lineItems;
|
||||||
|
}
|
||||||
|
|
||||||
return this.availableLineItems ?? [];
|
return this.availableLineItems ?? [];
|
||||||
},
|
},
|
||||||
servicePackageAnswers() {
|
servicePackageAnswers() {
|
||||||
if (!this.cmsWidgetName) return {};
|
if (!this.cmsWidgetName) return [];
|
||||||
const cmsAnswersContent = [
|
const cmsAnswersContent = [
|
||||||
{
|
{
|
||||||
Name: 'TierOne',
|
Name: 'TierOne',
|
||||||
|
|
@ -84,6 +83,9 @@
|
||||||
));
|
));
|
||||||
return modifiedAnswers;
|
return modifiedAnswers;
|
||||||
},
|
},
|
||||||
|
isRecalibrationOnOrder() {
|
||||||
|
return this.lineItemsContainsPartType(partTypeStrings.RECALIBRATION);
|
||||||
|
},
|
||||||
frontWipersApplicableForTierTwo() {
|
frontWipersApplicableForTierTwo() {
|
||||||
const store = useMainStore();
|
const store = useMainStore();
|
||||||
const frontWipersAreAvailable = this.lineItemsContainsPartType(
|
const frontWipersAreAvailable = this.lineItemsContainsPartType(
|
||||||
|
|
@ -205,50 +207,6 @@
|
||||||
});
|
});
|
||||||
return vapsPrice;
|
return vapsPrice;
|
||||||
},
|
},
|
||||||
selectDefaultPackage() {
|
|
||||||
const store = useMainStore();
|
|
||||||
const vapsFromStore = store.lineItems.vaps;
|
|
||||||
let lowestTierForPackage = packageNames.TIER_ONE;
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
allGlassPartsAndSupportingItemsHavePrices(lineItems) {
|
|
||||||
if (lineItems?.glassParts) {
|
|
||||||
for (let i = 0; i < lineItems.glassParts.length; i++) {
|
|
||||||
if (this.priceIsNullOrZero(lineItems.glassParts[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lineItems?.supportingItems) {
|
|
||||||
for (let i = 0; i < lineItems.supportingItems.length; i++) {
|
|
||||||
if (this.priceIsNullOrZero(lineItems.supportingItems[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
priceIsNullOrZero(lineItem) {
|
|
||||||
return (
|
|
||||||
(lineItem.kitPrice == null || lineItem.kitPrice == 0) &&
|
|
||||||
(lineItem.laborAmount == null || lineItem.laborAmount == 0) &&
|
|
||||||
(lineItem.sellingPrice == null || lineItem.sellingPrice == 0)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
getLowestTierForThisItem(vapsItem) {
|
getLowestTierForThisItem(vapsItem) {
|
||||||
let lowestTierForThisItem = null;
|
let lowestTierForThisItem = null;
|
||||||
switch (vapsItem.partType) {
|
switch (vapsItem.partType) {
|
||||||
|
|
@ -345,7 +303,7 @@
|
||||||
return !!glassLocationMatches.length;
|
return !!glassLocationMatches.length;
|
||||||
},
|
},
|
||||||
getTotalLineItemPrice(lineItem) {
|
getTotalLineItemPrice(lineItem) {
|
||||||
return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice
|
return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<baseInputButton v-bind="$props" @buttonClicked="handleAnswerChange" v-model="selectedValue">
|
<baseInputButton v-bind="$props" v-model="selectedValue">
|
||||||
<div class="package-label mb-4"
|
<div class="package-label mb-4"
|
||||||
:class="[this.buttonLabelSubCopy ? 'has-subheader' : '']"
|
:class="[this.buttonLabelSubCopy ? 'has-subheader' : '']"
|
||||||
for="testradio">
|
for="testradio">
|
||||||
|
|
@ -26,12 +26,7 @@
|
||||||
<textLink linkType="text"
|
<textLink linkType="text"
|
||||||
:text="getRouterLinkDisplayTextFromCopy(copy)"
|
:text="getRouterLinkDisplayTextFromCopy(copy)"
|
||||||
href="#!"
|
href="#!"
|
||||||
@click-event="
|
@click-event="textLinkEmit(copy)"
|
||||||
$emit('buttonEvent', {
|
|
||||||
eventName: 'openModal',
|
|
||||||
args: getRouterLinkRouteFromCopy(copy),
|
|
||||||
})
|
|
||||||
"
|
|
||||||
:data-bs-target="'#' + getRouterLinkRouteFromCopy(copy)"
|
:data-bs-target="'#' + getRouterLinkRouteFromCopy(copy)"
|
||||||
aria-label="Modal window" />
|
aria-label="Modal window" />
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -61,6 +56,7 @@ import {
|
||||||
} from '@/helpers/cms-content-helper';
|
} from '@/helpers/cms-content-helper';
|
||||||
export default {
|
export default {
|
||||||
name: 'servicePackageRadio',
|
name: 'servicePackageRadio',
|
||||||
|
emits:['link-event'],
|
||||||
mixins: [inputButtonWrapperMixin],
|
mixins: [inputButtonWrapperMixin],
|
||||||
components: {
|
components: {
|
||||||
baseInputButton,
|
baseInputButton,
|
||||||
|
|
@ -85,8 +81,13 @@ export default {
|
||||||
.split('- ') //At some point we'll want a better delimiter
|
.split('- ') //At some point we'll want a better delimiter
|
||||||
.filter((lineItem) => lineItem);
|
.filter((lineItem) => lineItem);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
textLinkEmit(copy) {
|
||||||
|
this.$parent.$emit('link-event', {
|
||||||
|
args: getRouterLinkRouteFromCopy(copy)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
groupName="ServicePackageQuestion"
|
groupName="ServicePackageQuestion"
|
||||||
:availableLineItems="availableLineItems"
|
:availableLineItems="availableLineItems"
|
||||||
@vapsItemsSelected="vapsItemsSelectedAction"
|
@vapsItemsSelected="vapsItemsSelectedAction"
|
||||||
v-on="{ 'buttonEvent.openModal': openModalAction }"
|
v-on:link-event="openModalAction"
|
||||||
validationRules="option-required"
|
validationRules="option-required"
|
||||||
isRequired />
|
isRequired />
|
||||||
<textBlock cmsWidgetName="PriceDisclaimerWidget"
|
<textBlock cmsWidgetName="PriceDisclaimerWidget"
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Components
|
// Components
|
||||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||||
import siteHeader from '@/iss-components/site-header/site-header';
|
import siteHeader from '@/iss-components/site-header/site-header';
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer';
|
import siteFooter from '@/iss-components/site-footer/site-footer';
|
||||||
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
|
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
|
||||||
|
|
@ -52,12 +52,12 @@
|
||||||
|
|
||||||
defineRule('option-required', required(errorMessages.OPTION_REQUIRED));
|
defineRule('option-required', required(errorMessages.OPTION_REQUIRED));
|
||||||
|
|
||||||
|
const store = useMainStore();
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'service-packages',
|
name: 'service-packages',
|
||||||
mixins: [baseFormMixin],
|
mixins: [baseFormMixin],
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
const store = useMainStore();
|
|
||||||
|
|
||||||
// Call APIs
|
// Call APIs
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
|
||||||
|
|
@ -106,18 +106,17 @@
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedVaps: null,
|
selectedVaps: [],
|
||||||
availableLineItems: null,
|
availableLineItems: [],
|
||||||
supportingItems: null,
|
supportingItems: [],
|
||||||
pricedGlassParts: null
|
pricedGlassParts: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openModalAction(modalName) {
|
openModalAction(modalName) {
|
||||||
this.$refs[modalName].openModal();
|
this.$refs[modalName.args].openModal();
|
||||||
},
|
},
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
const store = useMainStore();
|
|
||||||
return (
|
return (
|
||||||
store.order.serviceLocation.zipCode &&
|
store.order.serviceLocation.zipCode &&
|
||||||
store.order.serviceLocation.zipCodeCtu &&
|
store.order.serviceLocation.zipCodeCtu &&
|
||||||
|
|
@ -134,8 +133,48 @@
|
||||||
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||||
},
|
},
|
||||||
forwardButtonAction() {
|
forwardButtonAction() {
|
||||||
//TODO: save items
|
if (!this.allGlassPartsAndItemsHavePrices()) {
|
||||||
|
console.error('One or more items have no price assigned!');
|
||||||
|
}
|
||||||
|
if (this.pricedGlassParts.length > 0) {
|
||||||
|
|
||||||
|
store.saveGlassParts(this.pricedGlassParts);
|
||||||
|
}
|
||||||
|
store.saveSupportingItems(this.supportingItems);
|
||||||
|
store.saveVaps(this.selectedVaps);
|
||||||
|
|
||||||
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||||
|
},
|
||||||
|
allGlassPartsAndItemsHavePrices() {
|
||||||
|
if (this.pricedGlassParts) {
|
||||||
|
for (let i = 0; i < this.pricedGlassParts.length; i++) {
|
||||||
|
if (this.priceIsNullOrZero(this.pricedGlassParts[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.supportingItems) {
|
||||||
|
for (let i = 0; i < this.supportingItems.length; i++) {
|
||||||
|
if (this.priceIsNullOrZero(this.supportingItems[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.selectedVaps) {
|
||||||
|
for (let i = 0; i < this.selectedVaps.length; i++) {
|
||||||
|
if (this.priceIsNullOrZero(this.selectedVaps[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
priceIsNullOrZero(lineItem) {
|
||||||
|
return (
|
||||||
|
(lineItem.kitPrice == null || lineItem.kitPrice == 0) &&
|
||||||
|
(lineItem.laborAmount == null || lineItem.laborAmount == 0) &&
|
||||||
|
(lineItem.sellingPrice == null || lineItem.sellingPrice == 0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
71
src/layouts/tpa-search/tpa-search.vue
Normal file
71
src/layouts/tpa-search/tpa-search.vue
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
<template>
|
||||||
|
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
||||||
|
<div class="page-container-grouped-styles">
|
||||||
|
<div class="fade-on-route-transition position-relative">
|
||||||
|
<siteHeader cmsWidgetName="SiteHeaderWidget"/>
|
||||||
|
<div class="container-fluid pb-2">
|
||||||
|
<p>Placeholder for TPA-Search</p>
|
||||||
|
<siteFooter
|
||||||
|
cmsWidgetName="SiteFooterWidget"
|
||||||
|
ref="siteFooter"
|
||||||
|
:isForwardActionDisabled="!meta.valid"
|
||||||
|
@ForwardClicked="forwardButtonAction"
|
||||||
|
@back-clicked="backButtonAction"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
// Components
|
||||||
|
import siteHeader from '@/iss-components/site-header/site-header';
|
||||||
|
import siteFooter from "@/iss-components/site-footer/site-footer";
|
||||||
|
// Supporting files
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import { Form } from "vee-validate";
|
||||||
|
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||||
|
export default {
|
||||||
|
name: "tpa-search",
|
||||||
|
mixins: [BaseFormMixin],
|
||||||
|
data() {
|
||||||
|
},
|
||||||
|
async beforeRouteEnter(to, from, next)
|
||||||
|
{
|
||||||
|
// Call APIs
|
||||||
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
// Settle promises and get results
|
||||||
|
const promiseResultMap = [
|
||||||
|
{
|
||||||
|
resultKey: "cmsContent",
|
||||||
|
promise: cmsContentPromise,
|
||||||
|
},];
|
||||||
|
//use resultMap to populate layout content.
|
||||||
|
let resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
next((vm) => {
|
||||||
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods:
|
||||||
|
{
|
||||||
|
backButtonAction() {
|
||||||
|
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||||
|
},
|
||||||
|
forwardButtonAction() {
|
||||||
|
return this.navigateForward();
|
||||||
|
},
|
||||||
|
navigateForward() {
|
||||||
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.CLICKED_FORWARD,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
siteHeader,
|
||||||
|
siteFooter,
|
||||||
|
Form,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -10,6 +10,7 @@ export const issPageValues = {
|
||||||
COVERAGE_STATEMENT: 'coverage-statement',
|
COVERAGE_STATEMENT: 'coverage-statement',
|
||||||
LICENSE_PLATE_LOOKUP: 'license-plate-lookup',
|
LICENSE_PLATE_LOOKUP: 'license-plate-lookup',
|
||||||
MOLDING_QUESTIONS: 'molding-questions',
|
MOLDING_QUESTIONS: 'molding-questions',
|
||||||
|
ORDER_CONFIRMATION: 'order-confirmation',
|
||||||
PAYMENT_PAGE: 'payment-page',
|
PAYMENT_PAGE: 'payment-page',
|
||||||
PART_QUESTIONS: 'part-questions',
|
PART_QUESTIONS: 'part-questions',
|
||||||
POLICY_HOLDER_DETAILS: 'policy-holder-details',
|
POLICY_HOLDER_DETAILS: 'policy-holder-details',
|
||||||
|
|
@ -30,5 +31,6 @@ export const issPageValues = {
|
||||||
VIN_LOOKUP: 'vin-lookup',
|
VIN_LOOKUP: 'vin-lookup',
|
||||||
TPA_SUBMIT: 'tpa-submit',
|
TPA_SUBMIT: 'tpa-submit',
|
||||||
BAILOUT_PAGE: 'bailout-page',
|
BAILOUT_PAGE: 'bailout-page',
|
||||||
|
TPA_SEARCH: 'tpa-search'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -435,7 +435,7 @@ const routingTable = function(store) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE,
|
scenario: navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE,
|
||||||
destinationIssPageValue: issPageValues.SERVICE_PACKAGES
|
destinationIssPageValue: issPageValues.SERVICE_LOCATION
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -444,7 +444,7 @@ const routingTable = function(store) {
|
||||||
maps: [
|
maps: [
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.CLICKED_BACK,
|
scenario: navigationScenarios.CLICKED_BACK,
|
||||||
destinationIssPageValue: issPageValues.SERVICE_PACKAGES,
|
destinationIssPageValue: issPageValues.PROVIDER_PREFERENCE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||||
|
|
@ -474,7 +474,7 @@ const routingTable = function(store) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||||
destinationIssPageValue: issPageValues.REVIEW_PAGE
|
destinationIssPageValue: issPageValues.SERVICE_PACKAGES
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -483,11 +483,11 @@ const routingTable = function(store) {
|
||||||
maps: [
|
maps: [
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.CLICKED_BACK,
|
scenario: navigationScenarios.CLICKED_BACK,
|
||||||
destinationIssPageValue: issPageValues.PROVIDER_PREFERENCE
|
destinationIssPageValue: issPageValues.CONTACT_DETAILS
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||||
destinationIssPageValue: issPageValues.SERVICE_LOCATION
|
destinationIssPageValue: issPageValues.REVIEW_PAGE
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -497,7 +497,7 @@ const routingTable = function(store) {
|
||||||
maps: [
|
maps: [
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.CLICKED_BACK,
|
scenario: navigationScenarios.CLICKED_BACK,
|
||||||
destinationIssPageValue: issPageValues.CONTACT_DETAILS
|
destinationIssPageValue: issPageValues.SERVICE_PACKAGES
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||||
|
|
@ -516,7 +516,7 @@ const routingTable = function(store) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||||
destinationIssPageValue: issPageValues.WELCOME_PAGE
|
destinationIssPageValue: issPageValues.ORDER_CONFIRMATION,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -545,6 +545,30 @@ const routingTable = function(store) {
|
||||||
destinationIssPageValue: issPageValues.TPA_CONFIRMATION,
|
destinationIssPageValue: issPageValues.TPA_CONFIRMATION,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
issPageValue: issPageValues.ORDER_CONFIRMATION,
|
||||||
|
maps: [
|
||||||
|
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||||
|
destinationIssPageValue: issPageValues.WELCOME_PAGE
|
||||||
|
},
|
||||||
|
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
issPageValue: issPageValues.TPA_SEARCH,
|
||||||
|
maps: [
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_BACK,
|
||||||
|
destinationIssPageValue: issPageValues.PROVIDER_PREFERENCE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||||
|
destinationIssPageValue: issPageValues.TPA_SUBMIT,
|
||||||
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -497,8 +497,8 @@ export const useMainStore = defineStore({
|
||||||
///WARNING
|
///WARNING
|
||||||
///TODO: this is temp test code until serviceLocation is complete.
|
///TODO: this is temp test code until serviceLocation is complete.
|
||||||
/// and ctu is available. Also, EON may need to be implemented.
|
/// and ctu is available. Also, EON may need to be implemented.
|
||||||
zipCodeToUse = "44902"
|
zipCodeToUse = "44902";
|
||||||
ctuToUse = "01820"
|
ctuToUse = "01820";
|
||||||
let queryString =
|
let queryString =
|
||||||
`ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}` +
|
`ParentAccountNumber=${applicationConfig.CASH_PARENT_ACCOUNT_NUMBER}` +
|
||||||
`&CTU=${ctuToUse}` +
|
`&CTU=${ctuToUse}` +
|
||||||
|
|
@ -905,7 +905,15 @@ export const useMainStore = defineStore({
|
||||||
// Save new values
|
// Save new values
|
||||||
this.updateCapabilityQuestionAnswers(capabilityQuestionAnswersArray);
|
this.updateCapabilityQuestionAnswers(capabilityQuestionAnswersArray);
|
||||||
},
|
},
|
||||||
|
saveGlassParts(glassParts) {
|
||||||
|
this.order.lineItems.glassParts = glassParts;
|
||||||
|
},
|
||||||
|
saveSupportingItems(supportingItems) {
|
||||||
|
this.order.lineItems.supportingItems = supportingItems;
|
||||||
|
},
|
||||||
|
saveVaps(vaps) {
|
||||||
|
this.order.lineItems.vaps = vaps;
|
||||||
|
},
|
||||||
addEventToBus (event) {
|
addEventToBus (event) {
|
||||||
this.applicationUser.eventBus.push(event);
|
this.applicationUser.eventBus.push(event);
|
||||||
},
|
},
|
||||||
|
|
@ -1178,7 +1186,7 @@ export const useMainStore = defineStore({
|
||||||
resetPartsAndDependencies() {
|
resetPartsAndDependencies() {
|
||||||
this.resetGlassPartsState();
|
this.resetGlassPartsState();
|
||||||
this.updateSupportingItems(null);
|
this.updateSupportingItems(null);
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
persist: true
|
persist: true
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue