Merge pull request #827 from Safelite/feature/CSR-504

CSR-504 | Implement Quote page service calls
This commit is contained in:
scottkiener 2022-11-17 16:49:20 -05:00 committed by GitHub
commit 5e963ab491
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 119 additions and 65 deletions

View file

@ -62,6 +62,18 @@ const endpoints = {
url: "/parts/api/v1/parts/parts", url: "/parts/api/v1/parts/parts",
method: "POST", method: "POST",
}, },
GetWipers: {
url: "/parts/api/v1/parts/wipers",
method: "GET",
},
GetRainDefense: {
url: "/parts/api/v1/parts/rain-defense",
method: "GET",
},
GetSupportingItems: {
url: "/parts/api/v1/parts/supporting-items",
method: "POST",
},
GetCapabilityQuestions: { GetCapabilityQuestions: {
url: "/parts/api/v1/parts/capability-questions", url: "/parts/api/v1/parts/capability-questions",
method: "GET", method: "GET",
@ -82,6 +94,10 @@ const endpoints = {
url: "/location/api/v1/location/zip", url: "/location/api/v1/location/zip",
method: "GET", method: "GET",
}, },
PriceOrderItems: {
url: "/price/api/v1/price/order-items",
method: "POST",
},
LogExperimentExposureIfAssigned: { LogExperimentExposureIfAssigned: {
url: "/experiments/api/v1/experiments/log-exposure", url: "/experiments/api/v1/experiments/log-exposure",
method: "POST", method: "POST",

View file

@ -20,6 +20,9 @@ const storeActions = {
LOOKUP_VIN_BY_ADDRESS: "lookupVinByAddress", LOOKUP_VIN_BY_ADDRESS: "lookupVinByAddress",
GET_PARTS_OR_QUESTIONS: "getPartsOrQuestions", GET_PARTS_OR_QUESTIONS: "getPartsOrQuestions",
GET_PARTS: "getParts", GET_PARTS: "getParts",
GET_WIPERS: "getWipers",
GET_RAIN_DEFENSE: "getRainDefense",
GET_SUPPORTING_ITEMS: "getSupportingItems",
GET_CAPABILITY_QUESTIONS: "getCapabilityQuestions", GET_CAPABILITY_QUESTIONS: "getCapabilityQuestions",
GET_PART_FROM_CAPABILITY_QUESTION_ANSWER: "getPartFromCapabilityQuestionAnswer", GET_PART_FROM_CAPABILITY_QUESTION_ANSWER: "getPartFromCapabilityQuestionAnswer",
GET_MOLDING_QUESTIONS: "getMoldingQuestions", GET_MOLDING_QUESTIONS: "getMoldingQuestions",
@ -27,6 +30,7 @@ const storeActions = {
LOAD_SESSION: "loadSession", LOAD_SESSION: "loadSession",
UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE: "updateStoreWithSaveSessionResponse", UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE: "updateStoreWithSaveSessionResponse",
VALIDATE_ZIP: "validateZip", VALIDATE_ZIP: "validateZip",
PRICE_ORDER_ITEMS: "priceOrderItems",
LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure", LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure",
LOG_PAGE_VIEW: "logPageView", LOG_PAGE_VIEW: "logPageView",
LOG_CUSTOM_EVENT: "logCustomEvent", LOG_CUSTOM_EVENT: "logCustomEvent",

View file

@ -57,7 +57,9 @@ import textBlock from "@/common-components/text-block/text-block";
import modal from "@/common-components/modal/modal"; import modal from "@/common-components/modal/modal";
import baseMixin from "@/mixins/base-mixin.js"; import baseMixin from "@/mixins/base-mixin.js";
import vehicleQuestionsMixin from "../../mixins/vehicle-questions-mixin"; import vehicleQuestionsMixin from "../../mixins/vehicle-questions-mixin";
import { settleAllPromises } from "@/helpers/layout-helper";
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { Form } from "vee-validate"; import { Form } from "vee-validate";
@ -66,70 +68,48 @@ export default {
async beforeRouteEnter(to, from, next) { async beforeRouteEnter(to, from, next) {
// Call APIs // Call APIs
const cmsContent = await fetchCmsContentForPage(to.query.fmgPage); const cmsContent = await fetchCmsContentForPage(to.query.fmgPage);
const wipersPromise = baseMixin.methods.dispatchStoreAction(storeActions.GET_WIPERS);
const rainDefensePromise = baseMixin.methods.dispatchStoreAction(
storeActions.GET_RAIN_DEFENSE
);
const supportingItemsPromise = baseMixin.methods.dispatchStoreAction(
storeActions.GET_SUPPORTING_ITEMS
);
// TODOS - modify as needed, just a rough sketch to place initializations const promiseResultMap = [
{
resultKey: "wipers",
promise: wipersPromise,
},
{
resultKey: "rainDefense",
promise: rainDefensePromise,
},
{
resultKey: "supportingItems",
promise: supportingItemsPromise,
},
];
// get supporting availableLineItems const resultMap = await settleAllPromises(promiseResultMap);
const glassParts = [...store.getters.order.lineItems.glassParts];
const availableLineItems = [
resultMap.rainDefense,
...resultMap.supportingItems,
...resultMap.wipers,
...glassParts,
];
// get wiper and rain defense availableLineItems const pricingResults = await baseMixin.methods.dispatchStoreAction(
storeActions.PRICE_ORDER_ITEMS,
// Settle promises and get results availableLineItems,
false
// get price of supporting, rain defense & wipers, and parts );
// Settle pricing promise and get results
// Call the "next" function to complete the transition to this page. // Call the "next" function to complete the transition to this page.
next((vm) => { next((vm) => {
vm.setCmsContent(cmsContent); vm.setCmsContent(cmsContent);
vm.availableLineItems = [ vm.availableLineItems = pricingResults;
{
partNumber: "001",
Description: "Windshield with Recal",
partType: "Windshield",
Quantity: "1",
BasePartNumber: "001",
Color: "Green",
CanSafeliteRecalibrate: true,
price: 350.22,
},
{
partNumber: "SBB16",
description: "SAFELITE BEAM BLADE 16",
partType: "FRONT WIPER",
price: 32.64,
},
{
partNumber: "A DISPOSAL FEE",
partType: "DISPOSAL FEE",
price: 15.0,
},
{
partNumber: "SBB26",
description: "SAFELITE BEAM BLADE 26",
partType: "FRONT WIPER",
price: 53.04,
},
{
partNumber: "SBBR12A",
description: "SAFELITE REAR BLADE 12A",
partType: "REAR WIPER",
price: 24.48,
},
{
partNumber: "RAIN DEFENSE",
description: null,
partType: "RAIN DEFENSE",
price: 35.5,
},
{
partNumber: "RECAL STATIC",
Description: "Recalibration",
partType: "recalibration",
Quantity: "1",
price: 150.0,
},
];
vm.isInsuranceSelected = vm.getDefaultIsInsuranceSelectedValue(); vm.isInsuranceSelected = vm.getDefaultIsInsuranceSelectedValue();
}); });
}, },

View file

@ -42,6 +42,8 @@ export default {
partNumber: singlePart.partNumber, partNumber: singlePart.partNumber,
description: singlePart.description, description: singlePart.description,
color: singlePart.color, color: singlePart.color,
partType: singlePart.partType,
canSafeliteRecalibrate: singlePart.canSafeliteRecalibrate,
requiresRecalibration: singlePart.requiresRecalibration, requiresRecalibration: singlePart.requiresRecalibration,
requiresCapabilityQuestions: singlePart.requiresCapabilityQuestions, requiresCapabilityQuestions: singlePart.requiresCapabilityQuestions,
recalibrationType: singlePart.recalibrationType, recalibrationType: singlePart.recalibrationType,

View file

@ -342,7 +342,7 @@ export const mutations = {
state.order.damage.isRepair = sessionInformation.order.damage.isRepair; state.order.damage.isRepair = sessionInformation.order.damage.isRepair;
state.order.damage.numberOfChips = sessionInformation.order.damage.numberOfChips; state.order.damage.numberOfChips = sessionInformation.order.damage.numberOfChips;
state.order.lineItems.glassParts = sessionInformation.order.lineItems.parts; state.order.lineItems.glassParts = sessionInformation.order.lineItems.glassParts;
state.order.accountNumber = sessionInformation.order.accountNumber; state.order.accountNumber = sessionInformation.order.accountNumber;
state.order.providerNumber = sessionInformation.order.providerNumber; state.order.providerNumber = sessionInformation.order.providerNumber;
(state.order.serviceLocation.address = (state.order.serviceLocation.address =
@ -871,6 +871,49 @@ export const actions = {
return response; return response;
}, },
getWipers(context) {
const carId = context.getters.vehicle.carId;
const serviceZipCode = context.getters.order.serviceLocation.zipCode;
return globalMethods
.callHttpClient({
method: endpoints.GetWipers.method,
endpoint: `${endpoints.GetWipers.url}/${carId}/${serviceZipCode}`,
})
.catch((error) => {
// The wiper service sometimes returns 500s on legitimate carId/zipCode combination - return empty array instead of breaking flow
return [];
});
},
getRainDefense(context) {
return globalMethods.callHttpClient({
method: endpoints.GetRainDefense.method,
endpoint: endpoints.GetRainDefense.url,
});
},
getSupportingItems(context) {
const glassPartsArray = context.getters.lineItems.glassParts;
if (!glassPartsArray) {
return [];
}
const carId = context.getters.vehicle.carId;
const isRepair = context.getters.damage.isRepair;
const numberOfChips = context.getters.damage.numberOfChips;
const accountNumber = "82791"; //context.getters.order.accountNumber.toString();
return globalMethods.callHttpClient({
method: endpoints.GetSupportingItems.method,
endpoint: endpoints.GetSupportingItems.url,
payload: {
carId: carId,
serviceType: isRepair ? "Repair" : "Replace",
//accountNumber: accountNumber,
parts: glassPartsArray,
numberOfRepairChips: isRepair ? numberOfChips : 0,
},
});
},
getCapabilityQuestions(context, { carId, partNumber }) { getCapabilityQuestions(context, { carId, partNumber }) {
return globalMethods.callHttpClient({ return globalMethods.callHttpClient({
method: endpoints.GetCapabilityQuestions.method, method: endpoints.GetCapabilityQuestions.method,
@ -984,7 +1027,7 @@ export const actions = {
}) })
.then((response) => { .then((response) => {
// Flatten location and name properties // Flatten location and name properties
response.data.damage?.glassToReplace?.map((glass) => { response.data.order.damage?.glassToReplace?.map((glass) => {
glass.glassLocation = glass.location; glass.glassLocation = glass.location;
glass.glassName = glass.name; glass.glassName = glass.name;
delete glass.location; delete glass.location;
@ -1311,6 +1354,14 @@ export const actions = {
capabilityQuestionAnswers capabilityQuestionAnswers
); );
}, },
// Price order actions
// PLACEHOLDER, WILL CHANGE WHEN PRICING END POINT IS IMPLEMENTED
priceOrderItems(context, availableLineItems) {
availableLineItems.forEach((lineItem) => {
lineItem["price"] = parseFloat((Math.random() * 100).toFixed(2));
});
return availableLineItems;
},
// Misc order actions // Misc order actions
saveServiceLocation(context, serviceLocationInfo) { saveServiceLocation(context, serviceLocationInfo) {
context.commit(storeMutations.UPDATE_SERVICE_LOCATION, serviceLocationInfo); context.commit(storeMutations.UPDATE_SERVICE_LOCATION, serviceLocationInfo);
@ -1394,7 +1445,7 @@ function sortArrayOfObjectsByPropertyValue(arrayOfObjects, propertyName) {
} }
function convertGlassPieceNamingForApi(glassArray) { function convertGlassPieceNamingForApi(glassArray) {
if (!glassArray) return []; if (!glassArray || glassArray.length === 0) return [];
// check if array already converted. (likely when a session has been saved previously and then reloaded) // check if array already converted. (likely when a session has been saved previously and then reloaded)
if (glassArray[0].location !== undefined) { if (glassArray[0].location !== undefined) {

View file

@ -662,7 +662,7 @@ describe("Actions", () => {
const context = state; const context = state;
globalMethods.callHttpClient.mockImplementation(() => { globalMethods.callHttpClient.mockImplementation(() => {
return Promise.resolve({ data: { referralNumber: 123 } }); return Promise.resolve({ data: { referralNumber: 123, order: {} } });
}); });
const commit = jest.fn(); const commit = jest.fn();
@ -675,9 +675,10 @@ describe("Actions", () => {
}); });
// Assert // Assert
expect(response.data).toEqual({ referralNumber: 123 }); expect(response.data).toEqual({ referralNumber: 123, order: {} });
expect(commit).toBeCalledWith(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, { expect(commit).toBeCalledWith(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, {
referralNumber: 123, referralNumber: 123,
order: {},
}); });
}); });
@ -686,7 +687,7 @@ describe("Actions", () => {
const context = state; const context = state;
globalMethods.callHttpClient.mockImplementation(() => { globalMethods.callHttpClient.mockImplementation(() => {
return Promise.resolve({ data: { eon: "123" } }); return Promise.resolve({ data: { eon: "123", order: {} } });
}); });
context.commit = jest.fn(); context.commit = jest.fn();
@ -709,7 +710,7 @@ describe("Actions", () => {
const context = state; const context = state;
globalMethods.callHttpClient.mockImplementation(() => { globalMethods.callHttpClient.mockImplementation(() => {
return Promise.resolve({ data: { eon: "123" } }); return Promise.resolve({ data: { eon: "123", order: {} } });
}); });
context.commit = jest.fn(); context.commit = jest.fn();