Merge pull request #843 from Safelite/feature/digital/SSR-1460

SSR-1460 Implement the combined-quote endpoint
This commit is contained in:
Josh Dassinger 2024-09-17 10:38:50 -05:00 committed by GitHub
commit 2e7ffa87f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 76 additions and 128 deletions

View file

@ -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'

View file

@ -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]);
} }

View file

@ -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

View file

@ -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;
} }
} }
}; };

View file

@ -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;
} }

View file

@ -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();

View file

@ -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>

View file

@ -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;
}); });

View file

@ -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(

View file

@ -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);
} }