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`,
method: 'POST'
},
GetCombinedQuote: {
url: `${PRICE_BASE_URL}/combined-quote`,
method: 'POST'
},
GetProviders: {
url: `${LOCATION_BASE_URL}/providers`,
method: 'GET'

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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