diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index 3aa3ce24..2d81cc2e 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -31,6 +31,10 @@ const endpoints = { url: "/parts/api/v1/parts/damage-options", method: "GET", }, + GetParts: { + url: "/parts/api/v1/parts/parts", + method: "POST", + }, GetVehicle: { url: "/vehicle/api/v1/vehicle/lookup", method: "GET", diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue index e69de29b..a0883508 100644 --- a/src/layouts/part-questions/part-questions.vue +++ b/src/layouts/part-questions/part-questions.vue @@ -0,0 +1,146 @@ + + + diff --git a/src/mixins/vehicle-questions-mixin.js b/src/mixins/vehicle-questions-mixin.js index 1e6ec309..5fff8735 100644 --- a/src/mixins/vehicle-questions-mixin.js +++ b/src/mixins/vehicle-questions-mixin.js @@ -7,12 +7,6 @@ import baseMixin from "@/mixins/base-mixin.js"; import store from "@/store"; export default { - data() { - // TODO KO DELETE AFTER QUOTE MVP - return { - shouldGoToHeritageQuote: false, - }; - }, methods: { hasPartQuestions(partsOrQuestions) { return partsOrQuestions?.some((pq) => pq.partQuestions?.length > 0); @@ -452,12 +446,9 @@ export default { const collectedGlassParts = this.reducedGlassPartsArray(partsOrQuestions); // save to store lineItems.glassParts - self.$store.commit(storeMutations.UPDATE_GLASS_PARTS, collectedGlassParts); + this.mainStore.updateGlassParts(collectedGlassParts); - shouldGoToHeritageQuote - ? navigateToHeritageFunnel() - : self.$router.navigateWithSaving( - self.navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, + this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, self.$route ); } @@ -506,9 +497,5 @@ export default { self.$router.navigate(backNavigationScenario, self.$route); }, - // TODO KO delete this after quote mvp - async handleTempButtonClicked(vm) { - this.shouldGoToHeritageQuote = true; - }, }, }; diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 816f0fd2..fe2040f3 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -9,8 +9,29 @@ const navigationScenarios = { SELECTED_MODEL: "SELECTED_MODEL", SELECTED_STYLE: "SELECTED_STYLE", - // TESTING - CLICKED_TEST: "CLICKED_TEST" + // Vin selection + CLICKED_BACK_WITH_VIN: "CLICKED_BACK_WITH_VIN", + CLICKED_FORWARD_WITH_VIN: "CLICKED_FORWARD_WITH_VIN", + CLICKED_FORWARD_WITHOUT_VIN: "CLICKED_FORWARD_WITHOUT_VIN", + CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES: "CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES", + SELECTED_VIN_WITH_MISMATCHED_GLASS: "SELECTED_VIN_WITH_MISMATCHED_GLASS", + SELECTED_MANUAL_VIN: "SELECTED_MANUAL_VIN", + SELECTED_LICENSE_PLATE: "SELECTED_LICENSE_PLATE", + SELECTED_HOME_ADDRESS: "SELECTED_HOME_ADDRESS", + CLICKED_FORWARD_WITH_NO_QUESTIONS: "CLICKED_FORWARD_WITH_NO_QUESTIONS", + + // Part selection + CLICKED_FORWARD_WITH_PART_QUESTIONS: "CLICKED_FORWARD_WITH_PART_QUESTIONS", + CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE: "CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE", + CLICKED_FORWARD_WITH_MOLDING_QUESTIONS: "CLICKED_FORWARD_WITH_MOLDING_QUESTIONS", + CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS: "CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS", + CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS: "CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS", + CLICKED_BACK_WITH_PART_QUESTIONS: "CLICKED_BACK_WITH_PART_QUESTIONS", + CLICKED_BACK_WITH_MULTIPLE_PARTS_TO_CHOOSE: "CLICKED_BACK_WITH_MULTIPLE_PARTS_TO_CHOOSE", + CLICKED_BACK_WITH_MOLDING_QUESTIONS: "CLICKED_BACK_WITH_MOLDING_QUESTIONS", + CLICKED_BACK_WITH_CAPABILITY_QUESTIONS: "CLICKED_BACK_WITH_CAPABILITY_QUESTIONS", + CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS: "CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS", + CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS: "CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS", }; export { navigationScenarios }; \ No newline at end of file diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 717ef11e..cfa431f0 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -73,6 +73,126 @@ const routingTable = function(store) { }, ], }, + { + issPageValue: issPageValues.PART_QUESTIONS, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS, + destinationIssPageValue: issPageValues.VIN_LOOKUP, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS, + destinationIssPageValue: issPageValues.ESTIMATE, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE, + destinationIssPageValue: issPageValues.VEHICLE_PARTS, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS, + destinationIssPageValue: issPageValues.MOLDING_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS, + destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, + destinationIssPageValue: issPageValues.QUOTE, + }, + ], + }, + { + issPageValue: issPageValues.VEHICLE_PARTS, + maps: [ + { + scenario: navigationScenarios.CLICKED_FORWARD, + destinationIssPageValue: issPageValues.REVEAL, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS, + destinationIssPageValue: issPageValues.PART_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS, + destinationIssPageValue: issPageValues.VIN_LOOKUP, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS, + destinationIssPageValue: issPageValues.ESTIMATE, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS, + destinationIssPageValue: issPageValues.MOLDING_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS, + destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, + destinationIssPageValue: issPageValues.QUOTE, + }, + ], + }, + { + issPageValue: issPageValues.MOLDING_QUESTIONS, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS, + destinationIssPageValue: issPageValues.VIN_LOOKUP, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS, + destinationIssPageValue: issPageValues.ESTIMATE, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS, + destinationIssPageValue: issPageValues.PART_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_MULTIPLE_PARTS_TO_CHOOSE, + destinationIssPageValue: issPageValues.VEHICLE_PARTS, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS, + destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, + destinationIssPageValue: issPageValues.QUOTE, + }, + ], + }, + { + issPageValue: issPageValues.CAPABILITY_QUESTIONS, + maps: [ + { + scenario: navigationScenarios.CLICKED_BACK_WITH_VIN_AND_NO_MORE_QUESTIONS, + destinationIssPageValue: issPageValues.VIN_LOOKUP, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS, + destinationIssPageValue: issPageValues.ESTIMATE, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_PART_QUESTIONS, + destinationIssPageValue: issPageValues.PART_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_MULTIPLE_PARTS_TO_CHOOSE, + destinationIssPageValue: issPageValues.VEHICLE_PARTS, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_MOLDING_QUESTIONS, + destinationIssPageValue: issPageValues.MOLDING_QUESTIONS, + }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS, + destinationIssPageValue: issPageValues.QUOTE, + }, + ], + }, { issPageValue: issPageValues.WELCOME_PAGE, maps: [ diff --git a/src/store/index.js b/src/store/index.js index 20e594cf..5c96e9c2 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -39,8 +39,15 @@ const getDefaultState = () => { moldingQuestionAnswers: null, capabilityQuestionAnswers: null, }, + serviceLocation: { + address: null, + city: null, + state: null, + zipCode: null, + }, lineItems: { glassParts: null, + otherParts: null }, referralNumber: null, referralDate: null, @@ -211,6 +218,43 @@ export const useMainStore = defineStore({ payload: {}, }); }, + + async getParts() { + const vehicle = this.getters.vehicle; + const damage = this.getters.damage; + const order = this.order; + + const carId = vehicle.carId; + const glassArray = damage.glassToReplace; + const resultsArray = damage.partQuestionAnswers; + const zipCode = order.serviceLocation.zipCode; + const vin = vehicle.vin; + + // create a new array to avoid mutating state + const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray); + const resultsArrayForPayload = convertResultsForApi(resultsArray); + + const response = await globalMethods.callHttpClient({ + method: endpoints.GetParts.method, + endpoint: endpoints.GetParts.url, + payload: { + carId: carId, + glassPieces: glassArrayForPayload, + answerResults: resultsArrayForPayload, + zip: zipCode, + vin: vin, + }, + }); + + // Flatten location and name properties + response.data.glassPieceParts = convertGlassPieceNamingFromApi( + response.data.glassPieceParts + ); + + return response; + }, + + setVehicle() { return globalMethods .callHttpClient({ @@ -363,6 +407,55 @@ export const useMainStore = defineStore({ updateGlassToReplace(glassToReplace) { this.order.damage.glassToReplace = glassToReplace; }, + + updateGlassParts(partsData) { + this.order.lineItems.glassParts = partsData; + }, + + updateMoldingQuestionAnswers(answersArray) { + this.order.damage.moldingQuestionAnswers = answersArray; + }, + + updateCapabilityQuestionAnswers(answersArray) { + this.order.damage.capabilityQuestionAnswers = answersArray; + }, + + updatePartQuestionAnswers(answersArray) { + this.order.damage.partQuestionAnswers = answersArray; + }, + + updatePageData(pageData) { + this.applicationUser.pageData[pageData.page] = pageData.data; + }, + + savePartQuestionAnswers(partQuestionAnswersArray) { + // if part question answers have changed, reset subsequent question answers + const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue( + context.getters.damage.partQuestionAnswers, + "result" + ); + const sortedPartQuestionAnswersArray = sortArrayOfObjectsByPropertyValue( + partQuestionAnswersArray, + "result" + ); + const havePartQuestionAnswersChanged = + sortedPreviousResultsArray?.length !== sortedPartQuestionAnswersArray.length || + !sortedPreviousResultsArray?.every( + (x, i) => x.result === sortedPartQuestionAnswersArray[i].result + ); + + if (havePartQuestionAnswersChanged) { + this.updateGlassParts(null); + this.updateMoldingQuestionAnswers(null); + this.updateCapabilityQuestionAnswers(null); + this.updatePageData({ page: issPageValues.VEHICLE_PARTS, data: null}); + this.updatePageData({ page: issPageValues.MOLDING_QUESTIONS, data: null}); + this.updatePageData({ page: issPageValues.CAPABILITY_QUESTIONS, data: null}); + } + + //Save new values + this.updatePartQuestionAnswers(partQuestionAnswersArray); + }, addEventToBus (event) { this.applicationUser.eventBus.push(event); @@ -494,3 +587,56 @@ export const useMainStore = defineStore({ }, persist: true }); + + +function sortArrayOfObjectsByPropertyValue(arrayOfObjects, propertyName) { + if (!arrayOfObjects) return null; + + return arrayOfObjects.sort((a, b) => { + if (a[propertyName] < b[propertyName]) return -1; + else if (a[propertyName] > b[propertyName]) return 1; + else return 0; + }); +} + +function convertGlassPieceNamingForApi(glassArray) { + if (!glassArray || glassArray.length === 0) return []; + + // check if array already converted. (likely when a session has been saved previously and then reloaded) + if (glassArray[0].location !== undefined) { + return glassArray; + } + + const converted = []; + glassArray.forEach((glass) => { + converted.push({ + location: glass.glassLocation, + name: glass.glassName, + }); + }); + return converted; +} + +function convertResultsForApi(resultsArray) { + if (!resultsArray) return []; + const converted = []; + resultsArray.forEach((answer) => { + converted.push({ + location: answer.glassLocation, + name: answer.glassName, + result: answer.result, + }); + }); + return converted; +} + +function convertGlassPieceNamingFromApi(glassArray) { + glassArray.forEach((glass) => { + glass.glassLocation = glass.glassPiece.location; + glass.glassName = glass.glassPiece.name; + delete glass.glassPiece; + return glass; + }); + return glassArray; +} +