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`,
|
||||
method: 'POST'
|
||||
},
|
||||
GetCombinedQuote: {
|
||||
url: `${PRICE_BASE_URL}/combined-quote`,
|
||||
method: 'POST'
|
||||
},
|
||||
GetProviders: {
|
||||
url: `${LOCATION_BASE_URL}/providers`,
|
||||
method: 'GET'
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export async function getPricedMobileFeePart(serviceZipCode) {
|
|||
|
||||
// Get the Mobile Fee Part Price
|
||||
const pricingResults = await useMainStore()
|
||||
.getInsurancePriceOrderItems([mobileFeePart.data]);
|
||||
.getCombinedQuote([mobileFeePart.data]);
|
||||
|
||||
return Promise.resolve(pricingResults[0]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -394,12 +394,10 @@ export default {
|
|||
showIssLoadingModal(false);
|
||||
},
|
||||
async getPricedParts() {
|
||||
const clonedGlassParts = useMainStore().lineItems.glassParts
|
||||
? JSON.parse(JSON.stringify(useMainStore().lineItems.glassParts))
|
||||
: [];
|
||||
const { glassParts, supportingItems } = this.mainStore.order.lineItems;
|
||||
const availableLineItems = [
|
||||
...(this.mainStore.lineItems.supportingItems ?? []),
|
||||
...(clonedGlassParts ?? [])
|
||||
...(glassParts ?? []),
|
||||
...(supportingItems ?? [])
|
||||
];
|
||||
|
||||
// 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) {
|
||||
// Call APIs
|
||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||
const reviewDropdownPromise = reviewDropdown.methods.loadInitialData();
|
||||
const wipersPromise = useMainStore().getWipers();
|
||||
const rainDefensePromise = useMainStore().getRainDefense();
|
||||
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
promise: cmsContentPromise
|
||||
},
|
||||
{
|
||||
resultKey: 'reviewDropdownData',
|
||||
promise: reviewDropdownPromise
|
||||
},
|
||||
{
|
||||
resultKey: 'wipers',
|
||||
promise: wipersPromise
|
||||
},
|
||||
{
|
||||
resultKey: 'rainDefense',
|
||||
promise: rainDefensePromise
|
||||
}
|
||||
];
|
||||
|
||||
|
|
@ -138,28 +123,10 @@ export default {
|
|||
|
||||
await useMainStore().setPriceAndSalesTaxForOrderLineItems();
|
||||
|
||||
const unpricedVaps = [...resultMap.wipers, resultMap.rainDefense];
|
||||
|
||||
let hasBailedOut = false;
|
||||
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 ?? []);
|
||||
});
|
||||
}
|
||||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
|
||||
});
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -321,9 +288,6 @@ export default {
|
|||
this.$route
|
||||
);
|
||||
}
|
||||
},
|
||||
storeAvailableVaps(vaps) {
|
||||
useMainStore().order.availableVaps = vaps;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -96,21 +96,6 @@ export default {
|
|||
}
|
||||
},
|
||||
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() {
|
||||
this.isExpanded = !this.isExpanded;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
|||
import packageNames from '@/constants/package-names';
|
||||
import partTypeStrings from '@/constants/part-type-strings';
|
||||
import damageLocationsSelected from '@/constants/damage-locations-selected';
|
||||
import { useMainStore } from '@/store';
|
||||
|
||||
const testConstants = {
|
||||
cmsPropValues: {
|
||||
|
|
@ -717,11 +718,8 @@ const mockMixin = {
|
|||
}
|
||||
};
|
||||
|
||||
function initializeWithDefault(wrapper) {
|
||||
wrapper.vm.initializeComponent({
|
||||
wipers: [testConstants.parts.frontWiperPart],
|
||||
rainDefense: testConstants.parts.rainDefensePart
|
||||
});
|
||||
function initializeWithDefault() {
|
||||
useMainStore().order.availableVaps = [testConstants.parts.frontWiperPart, testConstants.parts.rainDefensePart];
|
||||
}
|
||||
|
||||
function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
|
||||
|
|
@ -853,7 +851,7 @@ describe('Service Package Review Block', () => {
|
|||
...props
|
||||
});
|
||||
|
||||
initializeWithDefault(wrapper);
|
||||
initializeWithDefault();
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
|
@ -883,7 +881,7 @@ describe('Service Package Review Block', () => {
|
|||
...props
|
||||
});
|
||||
|
||||
initializeWithDefault(wrapper);
|
||||
initializeWithDefault();
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
|
@ -909,7 +907,7 @@ describe('Service Package Review Block', () => {
|
|||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
initializeWithDefault(wrapper);
|
||||
initializeWithDefault();
|
||||
|
||||
// Assert
|
||||
const includesFrontWiperCopy = wrapper.vm.displayContent.includes(testConstants.vapsCopy.frontWiperCopy);
|
||||
|
|
@ -926,7 +924,7 @@ describe('Service Package Review Block', () => {
|
|||
...props
|
||||
});
|
||||
|
||||
initializeWithDefault(wrapper);
|
||||
initializeWithDefault();
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
|
@ -952,10 +950,7 @@ describe('Service Package Review Block', () => {
|
|||
...props
|
||||
});
|
||||
|
||||
wrapper.vm.initializeComponent({
|
||||
wipers: scenario.params.wiperResponse,
|
||||
rainDefense: scenario.params.rainDefenseResponse
|
||||
});
|
||||
useMainStore().order.availableVaps = [scenario.params.rainDefenseResponse, ...scenario.params.wiperResponse];
|
||||
|
||||
// Act
|
||||
await wrapper.vm.$nextTick();
|
||||
|
|
|
|||
|
|
@ -92,34 +92,9 @@ export default {
|
|||
return [
|
||||
...(this.lineItems?.glassParts ?? []),
|
||||
...(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>
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ export default {
|
|||
|
||||
const premiumFeeWithPricePromise = premiumFeePromise.then((result) => {
|
||||
if (result.data) {
|
||||
return useMainStore().getInsurancePriceOrderItems(result.data);
|
||||
return useMainStore().getCombinedQuote(result.data);
|
||||
}
|
||||
return result.data;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -96,7 +96,6 @@ export default {
|
|||
|
||||
const wipersPromise = await store.getWipers();
|
||||
const rainDefensePromise = await store.getRainDefense();
|
||||
const supportingItemsPromise = await store.getSupportingItems();
|
||||
const promiseResultMap = [
|
||||
{
|
||||
resultKey: 'cmsContent',
|
||||
|
|
@ -109,27 +108,20 @@ export default {
|
|||
{
|
||||
resultKey: 'rainDefense',
|
||||
promise: rainDefensePromise
|
||||
},
|
||||
{
|
||||
resultKey: 'supportingItems',
|
||||
promise: supportingItemsPromise
|
||||
}
|
||||
];
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
|
||||
const clonedGlassParts = store.order.lineItems.glassParts
|
||||
? JSON.parse(JSON.stringify(store.order.lineItems.glassParts))
|
||||
: [];
|
||||
const { feeItems } = store.order.lineItems;
|
||||
|
||||
const availableLineItems = [
|
||||
resultMap.rainDefense,
|
||||
...resultMap.supportingItems,
|
||||
...resultMap.wipers,
|
||||
...clonedGlassParts
|
||||
...feeItems
|
||||
];
|
||||
|
||||
let hasBailedOut = false;
|
||||
const pricingResults = await store
|
||||
.getInsurancePriceOrderItems(availableLineItems)
|
||||
await store.getCombinedQuote(availableLineItems)
|
||||
.catch((err) => {
|
||||
useMainStore().setBailout(bailoutMessage.pricingResponseError(
|
||||
availableLineItems.map((li) => li.partNumber),
|
||||
|
|
@ -143,7 +135,7 @@ export default {
|
|||
if (!hasBailedOut) {
|
||||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
vm.setData(clonedGlassParts, resultMap.supportingItems, pricingResults);
|
||||
vm.setData([resultMap.rainDefense, ...resultMap.wipers]);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -151,8 +143,6 @@ export default {
|
|||
return {
|
||||
selectedVaps: [],
|
||||
availableLineItems: [],
|
||||
supportingItems: [],
|
||||
pricedGlassParts: [],
|
||||
loadingText: [
|
||||
'Finding shops near you',
|
||||
'Looking for dates',
|
||||
|
|
@ -183,27 +173,20 @@ export default {
|
|||
&& store.order.lineItems.glassParts.length > 0))
|
||||
);
|
||||
},
|
||||
setData(clonedGlassParts, supportingItems, pricingResults) {
|
||||
this.pricedGlassParts = clonedGlassParts;
|
||||
this.supportingItems = supportingItems;
|
||||
this.availableLineItems = pricingResults;
|
||||
setData(pricedVaps) {
|
||||
this.availableLineItems = pricedVaps;
|
||||
useMainStore().order.availableVaps = pricedVaps;
|
||||
},
|
||||
vapsItemsSelectedAction(vapsItemsSelected) {
|
||||
this.selectedVaps = vapsItemsSelected;
|
||||
},
|
||||
forwardButtonAction() {
|
||||
const parts = {
|
||||
glassParts: this.pricedGlassParts,
|
||||
supportingItems: this.supportingItems,
|
||||
vaps: this.selectedVaps
|
||||
};
|
||||
if (!allGlassPartsAndItemsHavePrices(parts)) {
|
||||
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);
|
||||
|
||||
this.$router.navigate(
|
||||
|
|
|
|||
|
|
@ -1158,6 +1158,52 @@ export const useMainStore = defineStore({
|
|||
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() {
|
||||
const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
|
||||
|
||||
|
|
@ -1795,8 +1841,6 @@ export const useMainStore = defineStore({
|
|||
];
|
||||
}
|
||||
|
||||
await this.getInsurancePriceOrderItems(lineItemsToPrice);
|
||||
|
||||
if (lineItemsToTax && lineItemsToTax.length > 0) {
|
||||
await this.getTaxOrderItems(lineItemsToTax);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue