Merge pull request #843 from Safelite/feature/digital/SSR-1460
SSR-1460 Implement the combined-quote endpoint
This commit is contained in:
commit
2e7ffa87f9
10 changed files with 76 additions and 128 deletions
|
|
@ -80,6 +80,10 @@ const endpoints = Object.freeze({
|
||||||
url: `${PRICE_BASE_URL}/order-items-with-itac-pricing`,
|
url: `${PRICE_BASE_URL}/order-items-with-itac-pricing`,
|
||||||
method: 'POST'
|
method: 'POST'
|
||||||
},
|
},
|
||||||
|
GetCombinedQuote: {
|
||||||
|
url: `${PRICE_BASE_URL}/combined-quote`,
|
||||||
|
method: 'POST'
|
||||||
|
},
|
||||||
GetProviders: {
|
GetProviders: {
|
||||||
url: `${LOCATION_BASE_URL}/providers`,
|
url: `${LOCATION_BASE_URL}/providers`,
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export async function getPricedMobileFeePart(serviceZipCode) {
|
||||||
|
|
||||||
// Get the Mobile Fee Part Price
|
// Get the Mobile Fee Part Price
|
||||||
const pricingResults = await useMainStore()
|
const pricingResults = await useMainStore()
|
||||||
.getInsurancePriceOrderItems([mobileFeePart.data]);
|
.getCombinedQuote([mobileFeePart.data]);
|
||||||
|
|
||||||
return Promise.resolve(pricingResults[0]);
|
return Promise.resolve(pricingResults[0]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -394,12 +394,10 @@ export default {
|
||||||
showIssLoadingModal(false);
|
showIssLoadingModal(false);
|
||||||
},
|
},
|
||||||
async getPricedParts() {
|
async getPricedParts() {
|
||||||
const clonedGlassParts = useMainStore().lineItems.glassParts
|
const { glassParts, supportingItems } = this.mainStore.order.lineItems;
|
||||||
? JSON.parse(JSON.stringify(useMainStore().lineItems.glassParts))
|
|
||||||
: [];
|
|
||||||
const availableLineItems = [
|
const availableLineItems = [
|
||||||
...(this.mainStore.lineItems.supportingItems ?? []),
|
...(glassParts ?? []),
|
||||||
...(clonedGlassParts ?? [])
|
...(supportingItems ?? [])
|
||||||
];
|
];
|
||||||
|
|
||||||
// We only call the ITAC pricing endpoint if we are not repair or we are NoComp
|
// We only call the ITAC pricing endpoint if we are not repair or we are NoComp
|
||||||
|
|
|
||||||
|
|
@ -111,26 +111,11 @@ export default {
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
const reviewDropdownPromise = reviewDropdown.methods.loadInitialData();
|
|
||||||
const wipersPromise = useMainStore().getWipers();
|
|
||||||
const rainDefensePromise = useMainStore().getRainDefense();
|
|
||||||
|
|
||||||
const promiseResultMap = [
|
const promiseResultMap = [
|
||||||
{
|
{
|
||||||
resultKey: 'cmsContent',
|
resultKey: 'cmsContent',
|
||||||
promise: cmsContentPromise
|
promise: cmsContentPromise
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: 'reviewDropdownData',
|
|
||||||
promise: reviewDropdownPromise
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: 'wipers',
|
|
||||||
promise: wipersPromise
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: 'rainDefense',
|
|
||||||
promise: rainDefensePromise
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -138,28 +123,10 @@ export default {
|
||||||
|
|
||||||
await useMainStore().setPriceAndSalesTaxForOrderLineItems();
|
await useMainStore().setPriceAndSalesTaxForOrderLineItems();
|
||||||
|
|
||||||
const unpricedVaps = [...resultMap.wipers, resultMap.rainDefense];
|
next((vm) => {
|
||||||
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
let hasBailedOut = false;
|
vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
|
||||||
const pricedVaps = await useMainStore()
|
});
|
||||||
.getInsurancePriceOrderItems(unpricedVaps)
|
|
||||||
.catch((err) => {
|
|
||||||
useMainStore().setBailout(bailoutMessage.pricingResponseError(
|
|
||||||
unpricedVaps.map((li) => li.partNumber),
|
|
||||||
{ code: err.code, message: err.message, data: err.data }
|
|
||||||
));
|
|
||||||
hasBailedOut = true;
|
|
||||||
next(`/?issPage=${issPageValues.BAILOUT_PAGE}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!hasBailedOut) {
|
|
||||||
next((vm) => {
|
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
|
||||||
vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
|
|
||||||
vm.$refs.reviewDropdown.initializeComponent(resultMap.reviewDropdownData);
|
|
||||||
vm.storeAvailableVaps(pricedVaps ?? []);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -321,9 +288,6 @@ export default {
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
storeAvailableVaps(vaps) {
|
|
||||||
useMainStore().order.availableVaps = vaps;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -96,21 +96,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadInitialData() {
|
|
||||||
const servicePackageInitialDataPromise = servicePackageReview.methods.loadInitialData();
|
|
||||||
|
|
||||||
const promiseResultMap = [
|
|
||||||
{
|
|
||||||
resultKey: 'servicePackageData',
|
|
||||||
promise: servicePackageInitialDataPromise
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
return settleAllPromises(promiseResultMap);
|
|
||||||
},
|
|
||||||
initializeComponent(apiResponses) {
|
|
||||||
this.$refs.servicePackageReview.initializeComponent(apiResponses.servicePackageData);
|
|
||||||
},
|
|
||||||
toggleIsExpanded() {
|
toggleIsExpanded() {
|
||||||
this.isExpanded = !this.isExpanded;
|
this.isExpanded = !this.isExpanded;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
import packageNames from '@/constants/package-names';
|
import packageNames from '@/constants/package-names';
|
||||||
import partTypeStrings from '@/constants/part-type-strings';
|
import partTypeStrings from '@/constants/part-type-strings';
|
||||||
import damageLocationsSelected from '@/constants/damage-locations-selected';
|
import damageLocationsSelected from '@/constants/damage-locations-selected';
|
||||||
|
import { useMainStore } from '@/store';
|
||||||
|
|
||||||
const testConstants = {
|
const testConstants = {
|
||||||
cmsPropValues: {
|
cmsPropValues: {
|
||||||
|
|
@ -717,11 +718,8 @@ const mockMixin = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function initializeWithDefault(wrapper) {
|
function initializeWithDefault() {
|
||||||
wrapper.vm.initializeComponent({
|
useMainStore().order.availableVaps = [testConstants.parts.frontWiperPart, testConstants.parts.rainDefensePart];
|
||||||
wipers: [testConstants.parts.frontWiperPart],
|
|
||||||
rainDefense: testConstants.parts.rainDefensePart
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
|
function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
|
||||||
|
|
@ -853,7 +851,7 @@ describe('Service Package Review Block', () => {
|
||||||
...props
|
...props
|
||||||
});
|
});
|
||||||
|
|
||||||
initializeWithDefault(wrapper);
|
initializeWithDefault();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await wrapper.vm.$nextTick();
|
await wrapper.vm.$nextTick();
|
||||||
|
|
@ -883,7 +881,7 @@ describe('Service Package Review Block', () => {
|
||||||
...props
|
...props
|
||||||
});
|
});
|
||||||
|
|
||||||
initializeWithDefault(wrapper);
|
initializeWithDefault();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await wrapper.vm.$nextTick();
|
await wrapper.vm.$nextTick();
|
||||||
|
|
@ -909,7 +907,7 @@ describe('Service Package Review Block', () => {
|
||||||
// Act
|
// Act
|
||||||
await wrapper.vm.$nextTick();
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
initializeWithDefault(wrapper);
|
initializeWithDefault();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
const includesFrontWiperCopy = wrapper.vm.displayContent.includes(testConstants.vapsCopy.frontWiperCopy);
|
const includesFrontWiperCopy = wrapper.vm.displayContent.includes(testConstants.vapsCopy.frontWiperCopy);
|
||||||
|
|
@ -926,7 +924,7 @@ describe('Service Package Review Block', () => {
|
||||||
...props
|
...props
|
||||||
});
|
});
|
||||||
|
|
||||||
initializeWithDefault(wrapper);
|
initializeWithDefault();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await wrapper.vm.$nextTick();
|
await wrapper.vm.$nextTick();
|
||||||
|
|
@ -952,10 +950,7 @@ describe('Service Package Review Block', () => {
|
||||||
...props
|
...props
|
||||||
});
|
});
|
||||||
|
|
||||||
wrapper.vm.initializeComponent({
|
useMainStore().order.availableVaps = [scenario.params.rainDefenseResponse, ...scenario.params.wiperResponse];
|
||||||
wipers: scenario.params.wiperResponse,
|
|
||||||
rainDefense: scenario.params.rainDefenseResponse
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await wrapper.vm.$nextTick();
|
await wrapper.vm.$nextTick();
|
||||||
|
|
|
||||||
|
|
@ -92,34 +92,9 @@ export default {
|
||||||
return [
|
return [
|
||||||
...(this.lineItems?.glassParts ?? []),
|
...(this.lineItems?.glassParts ?? []),
|
||||||
...(this.lineItems?.supportingItems ?? []),
|
...(this.lineItems?.supportingItems ?? []),
|
||||||
...this.availableVaps
|
...(useMainStore().order.availableVaps ?? [])
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// TODO maybe move to shared location "loadAvailableVaps"
|
|
||||||
loadInitialData() {
|
|
||||||
const wipersPromise = useMainStore().getWipers();
|
|
||||||
const rainDefensePromise = useMainStore().getRainDefense();
|
|
||||||
|
|
||||||
const promiseResultMap = [
|
|
||||||
{
|
|
||||||
resultKey: 'wipers',
|
|
||||||
promise: wipersPromise
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: 'rainDefense',
|
|
||||||
promise: rainDefensePromise
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
return settleAllPromises(promiseResultMap);
|
|
||||||
},
|
|
||||||
initializeComponent(apiResponses) {
|
|
||||||
const vapsFromApi = [...apiResponses.wipers, apiResponses.rainDefense];
|
|
||||||
|
|
||||||
this.availableVaps = vapsFromApi;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ export default {
|
||||||
|
|
||||||
const premiumFeeWithPricePromise = premiumFeePromise.then((result) => {
|
const premiumFeeWithPricePromise = premiumFeePromise.then((result) => {
|
||||||
if (result.data) {
|
if (result.data) {
|
||||||
return useMainStore().getInsurancePriceOrderItems(result.data);
|
return useMainStore().getCombinedQuote(result.data);
|
||||||
}
|
}
|
||||||
return result.data;
|
return result.data;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,6 @@ export default {
|
||||||
|
|
||||||
const wipersPromise = await store.getWipers();
|
const wipersPromise = await store.getWipers();
|
||||||
const rainDefensePromise = await store.getRainDefense();
|
const rainDefensePromise = await store.getRainDefense();
|
||||||
const supportingItemsPromise = await store.getSupportingItems();
|
|
||||||
const promiseResultMap = [
|
const promiseResultMap = [
|
||||||
{
|
{
|
||||||
resultKey: 'cmsContent',
|
resultKey: 'cmsContent',
|
||||||
|
|
@ -109,27 +108,20 @@ export default {
|
||||||
{
|
{
|
||||||
resultKey: 'rainDefense',
|
resultKey: 'rainDefense',
|
||||||
promise: rainDefensePromise
|
promise: rainDefensePromise
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: 'supportingItems',
|
|
||||||
promise: supportingItemsPromise
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
const clonedGlassParts = store.order.lineItems.glassParts
|
const { feeItems } = store.order.lineItems;
|
||||||
? JSON.parse(JSON.stringify(store.order.lineItems.glassParts))
|
|
||||||
: [];
|
|
||||||
const availableLineItems = [
|
const availableLineItems = [
|
||||||
resultMap.rainDefense,
|
resultMap.rainDefense,
|
||||||
...resultMap.supportingItems,
|
|
||||||
...resultMap.wipers,
|
...resultMap.wipers,
|
||||||
...clonedGlassParts
|
...feeItems
|
||||||
];
|
];
|
||||||
|
|
||||||
let hasBailedOut = false;
|
let hasBailedOut = false;
|
||||||
const pricingResults = await store
|
await store.getCombinedQuote(availableLineItems)
|
||||||
.getInsurancePriceOrderItems(availableLineItems)
|
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
useMainStore().setBailout(bailoutMessage.pricingResponseError(
|
useMainStore().setBailout(bailoutMessage.pricingResponseError(
|
||||||
availableLineItems.map((li) => li.partNumber),
|
availableLineItems.map((li) => li.partNumber),
|
||||||
|
|
@ -143,7 +135,7 @@ export default {
|
||||||
if (!hasBailedOut) {
|
if (!hasBailedOut) {
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
vm.setData(clonedGlassParts, resultMap.supportingItems, pricingResults);
|
vm.setData([resultMap.rainDefense, ...resultMap.wipers]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -151,8 +143,6 @@ export default {
|
||||||
return {
|
return {
|
||||||
selectedVaps: [],
|
selectedVaps: [],
|
||||||
availableLineItems: [],
|
availableLineItems: [],
|
||||||
supportingItems: [],
|
|
||||||
pricedGlassParts: [],
|
|
||||||
loadingText: [
|
loadingText: [
|
||||||
'Finding shops near you',
|
'Finding shops near you',
|
||||||
'Looking for dates',
|
'Looking for dates',
|
||||||
|
|
@ -183,27 +173,20 @@ export default {
|
||||||
&& store.order.lineItems.glassParts.length > 0))
|
&& store.order.lineItems.glassParts.length > 0))
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
setData(clonedGlassParts, supportingItems, pricingResults) {
|
setData(pricedVaps) {
|
||||||
this.pricedGlassParts = clonedGlassParts;
|
this.availableLineItems = pricedVaps;
|
||||||
this.supportingItems = supportingItems;
|
useMainStore().order.availableVaps = pricedVaps;
|
||||||
this.availableLineItems = pricingResults;
|
|
||||||
},
|
},
|
||||||
vapsItemsSelectedAction(vapsItemsSelected) {
|
vapsItemsSelectedAction(vapsItemsSelected) {
|
||||||
this.selectedVaps = vapsItemsSelected;
|
this.selectedVaps = vapsItemsSelected;
|
||||||
},
|
},
|
||||||
forwardButtonAction() {
|
forwardButtonAction() {
|
||||||
const parts = {
|
const parts = {
|
||||||
glassParts: this.pricedGlassParts,
|
|
||||||
supportingItems: this.supportingItems,
|
|
||||||
vaps: this.selectedVaps
|
vaps: this.selectedVaps
|
||||||
};
|
};
|
||||||
if (!allGlassPartsAndItemsHavePrices(parts)) {
|
if (!allGlassPartsAndItemsHavePrices(parts)) {
|
||||||
window.console.error('One or more items have no price assigned!');
|
window.console.error('One or more items have no price assigned!');
|
||||||
}
|
}
|
||||||
if (this.pricedGlassParts.length > 0) {
|
|
||||||
store.updateGlassParts(this.pricedGlassParts);
|
|
||||||
}
|
|
||||||
store.updateSupportingItems(this.supportingItems);
|
|
||||||
store.updateVaps(this.selectedVaps);
|
store.updateVaps(this.selectedVaps);
|
||||||
|
|
||||||
this.$router.navigate(
|
this.$router.navigate(
|
||||||
|
|
|
||||||
|
|
@ -1158,6 +1158,52 @@ export const useMainStore = defineStore({
|
||||||
return availableLineItems;
|
return availableLineItems;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async getCombinedQuote(availableLineItems) {
|
||||||
|
const { vehicle, serviceLocation, policy, eon, referralNumber, referralDate, referralSequenceNumber, lineItems } = this.order;
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
ParentAccountNumber: this.order.parentAccountNumber,
|
||||||
|
BillToAccountNumber: this.billToAccountNumber,
|
||||||
|
ProviderNumber: this.providerNumber,
|
||||||
|
CarId: vehicle.carId,
|
||||||
|
Make: vehicle.make,
|
||||||
|
Model: vehicle.model,
|
||||||
|
Year: vehicle.year,
|
||||||
|
EON: eon,
|
||||||
|
ZipCode: policy.policyZipCode,
|
||||||
|
State: policy.damageState,
|
||||||
|
ReferralNumber: referralNumber,
|
||||||
|
ReferralDate: referralDate,
|
||||||
|
ReferralSequenceNumber: referralSequenceNumber,
|
||||||
|
ServiceZipCode: serviceLocation.zipCode,
|
||||||
|
IsReplacement: !this.isRepair,
|
||||||
|
ServerData: lineItems.serverData,
|
||||||
|
LineItems: getLineItemsFlattened(availableLineItems)
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await globalMethods
|
||||||
|
.callHttpClient({
|
||||||
|
method: endpoints.GetCombinedQuote.method,
|
||||||
|
endpoint: endpoints.GetCombinedQuote.url,
|
||||||
|
payload
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error);
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
|
const { lineItems: pricedLinedItems, serverData } = response.data;
|
||||||
|
|
||||||
|
if (serverData) {
|
||||||
|
this.order.lineItems.serverData = serverData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pricedLinedItems) {
|
||||||
|
return addPricesToLineItems(availableLineItems, pricedLinedItems);
|
||||||
|
}
|
||||||
|
return availableLineItems;
|
||||||
|
},
|
||||||
|
|
||||||
getMobileFeePart() {
|
getMobileFeePart() {
|
||||||
const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
|
const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
|
||||||
|
|
||||||
|
|
@ -1795,8 +1841,6 @@ export const useMainStore = defineStore({
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.getInsurancePriceOrderItems(lineItemsToPrice);
|
|
||||||
|
|
||||||
if (lineItemsToTax && lineItemsToTax.length > 0) {
|
if (lineItemsToTax && lineItemsToTax.length > 0) {
|
||||||
await this.getTaxOrderItems(lineItemsToTax);
|
await this.getTaxOrderItems(lineItemsToTax);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue