From c9c5d29b3d3c7cc0c959336274c1b4b0b86e1f43 Mon Sep 17 00:00:00 2001 From: Chris Redelinghuys Date: Mon, 24 Mar 2025 11:49:33 -0400 Subject: [PATCH] CASH-413: Update recycle fee on location change --- .../service-location-helper.js | 45 +++++++++++++++++++ .../mobile-location-modal-questions.spec.js | 20 +++++++++ .../mobile-location-modal-questions.vue | 8 ++++ .../service-location/service-location.vue | 43 +++++++++++++----- .../service-zip-modal-question.spec.js | 20 +++++++++ .../service-zip-modal-question.vue | 8 ++++ 6 files changed, 134 insertions(+), 10 deletions(-) diff --git a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js index 99b200037..7a9ac00d0 100644 --- a/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js +++ b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js @@ -1,5 +1,6 @@ import { storeActions } from "@/constants/store-actions"; import baseMixin from "@/mixins/base-mixin.js"; +import { partNumberStrings } from "@/constants/part-number-strings"; export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) { if (!serviceZipCode) { @@ -42,6 +43,50 @@ export async function getPricedMobileFeePart(serviceZipCode, pageNameToLog) { return pricingResults[0]; } +export async function getPricedRecycleFeePart(serviceZipCode, pageNameToLog) { + if (!serviceZipCode) { + return null; + } + + const zipCodeData = await getZipCodeData(serviceZipCode); + + // Get supporting items + const supportingItems = await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.GET_SUPPORTING_ITEMS, + null, + pageNameToLog, + false + ); + + if ( + supportingItems.data === null || + supportingItems.data === undefined || + supportingItems.data === "" + ) { + return null; + } + + const recycleFeePart = supportingItems.data.find( + (item) => item.partNumber === partNumberStrings.RECYCLE_FEE + ); + + if (recycleFeePart) { + // Get the Recycle Fee Part Price + const pricingResults = await baseMixin.methods.dispatchStoreActionWithLogging( + storeActions.PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA, + { + availableLineItems: [recycleFeePart], + serviceZipCode: serviceZipCode, + serviceZipCodeCtu: zipCodeData.zipCodeCtu, + }, + pageNameToLog, + false + ); + + return pricingResults[0]; + } +} + export async function getServiceabilityDetails(serviceZipCode, lineItems, pageNameToLog) { // Get the Mobile Fee Part return await baseMixin.methods.dispatchStoreActionWithLogging( diff --git a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js index f38262005..3e2873fa1 100644 --- a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js +++ b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.spec.js @@ -106,6 +106,23 @@ const mockGetPricedMobileFeePart = (mockServiceZipCode) => { return Promise.resolve(mobileFeePart); }; +const mockGetPricedRecycleFeePart = (mockServiceZipCode) => { + let recycleFeePart = {}; + + if (mockServiceZipCode === "43235") { + recycleFeePart = { + partNumber: "RECYCLE FEE", + description: "RECYCLE FEE", + partType: "FEE", + laborAmount: 39.99, + sellingPrice: 0, + kitPrice: 0, + }; + } + + return Promise.resolve(recycleFeePart); +}; + const mockGetServiceabilityDetails = (mockServiceZipCode) => { const serviceabilityDetails = { isGlassServiceableInshop: true, @@ -123,6 +140,9 @@ jest.mock( getPricedMobileFeePart: jest.fn((mockServiceZipCode) => { return mockGetPricedMobileFeePart(mockServiceZipCode); }), + getPricedRecycleFeePart: jest.fn((mockServiceZipCode) => { + return mockGetPricedRecycleFeePart(mockServiceZipCode); + }), getServiceabilityDetails: jest.fn((mockServiceZipCode) => { return mockGetServiceabilityDetails(mockServiceZipCode); }), diff --git a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue index 4672cca7f..0d7a82248 100644 --- a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue +++ b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue @@ -82,6 +82,7 @@ import vehicleProtectedQuestion from "@/layouts/service-location/mobile-location import { deepClone } from "@/helpers/object-helper"; import { getPricedMobileFeePart, + getPricedRecycleFeePart, getServiceabilityDetails, getBillToAccountNumber, } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; @@ -267,6 +268,12 @@ export default { "service-location" ); + // retrieve recycle fee part + const recycleFeePart = await getPricedRecycleFeePart( + serviceZipCode, + "service-location" + ); + // retrieve serviceability details const serviceabilityDetails = await getServiceabilityDetails( serviceZipCode, @@ -280,6 +287,7 @@ export default { // update content related to service zip code this.$emit("updated-mobile-fee-part", mobileFeePart); + this.$emit("updated-recycle-fee-part", recycleFeePart); this.$emit("updated-serviceability", serviceabilityDetails.data); this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase); this.$emit("updated-mobile-ctu", zipCodeData.zipCodeCtu); diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index ddb765da3..56c76bb2d 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -17,6 +17,7 @@ ref="serviceZipCodeQuestion" :mobileFeePart="mobileFeePart" @updated-mobile-fee-part="setMobileFeePart" + @updated-recycle-fee-part="setRecycleFeePart" @updated-serviceability="setServiceabilityDetails" @updated-contains-military-base="setContainsMilitaryBase" @updated-bill-to-account-number="setBillToAccountNumber" @@ -90,6 +91,7 @@ :mobileFeePart="mobileFeePart" :mobileFeeApplies="mobileFeeApplies" @updated-mobile-fee-part="setMobileFeePart" + @updated-recycle-fee-part="setRecycleFeePart" @updated-serviceability="setServiceabilityDetails" @updated-contains-military-base="setContainsMilitaryBase" @updated-mobile-ctu="setCtuForMobile" @@ -195,6 +197,7 @@ export default { selectedAppointmentType: this.getSelectedAppointmentType(), selectedProvider: this.getSelectedProvider(), mobileFeePart: null, + recycleFeePart: null, zipContainsMilitaryBase: false, zipCodeCtu: null, billToAccountNumber: null, @@ -480,6 +483,9 @@ export default { setMobileFeePart(mobileFeePart) { this.mobileFeePart = mobileFeePart; }, + setRecycleFeePart(recycleFeePart) { + this.recycleFeePart = recycleFeePart; + }, //creating async function as the computed property can not directly handle asynchronous operations or promises. async setMobileLocationQuestions(newValue) { var newZipCode = newValue.addressQuestions.zipCode; @@ -592,6 +598,7 @@ export default { }, updateAndSaveSupportingItems() { let supportingItems = store.getters.lineItems.supportingItems; + let shouldSaveSupportingItems = false; supportingItems = !supportingItems && this.isMobileStaticRecalibrationApplicable @@ -603,6 +610,21 @@ export default { return; } + // update recyle fee price + if (this.recycleFeePart) { + const recycleFeeIndex = supportingItems.findIndex( + (item) => item.partNumber == partNumberStrings.RECYCLE_FEE + ); + if (recycleFeeIndex >= 0) { + supportingItems[recycleFeeIndex].laborAmount = this.recycleFeePart.laborAmount; + supportingItems[recycleFeeIndex].sellingPrice = + this.recycleFeePart.sellingPrice; + supportingItems[recycleFeeIndex].kitPrice = this.recycleFeePart.kitPrice; + + shouldSaveSupportingItems = true; + } + } + // if we have a mobile fee, then save/update supporting items if (this.selectedAppointmentType == "Mobile") { const mobileFeeIndex = supportingItems.findIndex( @@ -617,11 +639,7 @@ export default { if (this.mobileFeePart !== null) supportingItems.push(this.mobileFeePart); } - this.dispatchStoreAction( - this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, - supportingItems, - false - ); + shouldSaveSupportingItems = true; } else { // if it's not a mobile, then make sure we remove any that may have been added const removeMobileFeeIndex = supportingItems?.findIndex( @@ -630,13 +648,18 @@ export default { if (removeMobileFeeIndex >= 0) { supportingItems.splice(removeMobileFeeIndex, 1); - this.dispatchStoreAction( - this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, - supportingItems, - false - ); + shouldSaveSupportingItems = true; } } + + // Use shouldSaveSupportingItems flag to determine if we need to save supporting items. Prevents unnecessary/multiple saves + if (shouldSaveSupportingItems) { + this.dispatchStoreAction( + this.storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING, + supportingItems, + false + ); + } }, async forwardButtonAction() { this.navigatingForward = true; diff --git a/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.spec.js b/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.spec.js index ed8a811ed..b1231991b 100644 --- a/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.spec.js +++ b/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.spec.js @@ -32,6 +32,23 @@ const mockGetPricedMobileFeePart = (mockServiceZipCode) => { return Promise.resolve(mobileFeePart); }; +const mockGetPricedRecycleFeePart = (mockServiceZipCode) => { + let recycleFeePart = {}; + + if (mockServiceZipCode === "43235") { + recycleFeePart = { + partNumber: "RECYCLE FEE", + description: "RECYCLE FEE", + partType: "FEE", + laborAmount: 39.99, + sellingPrice: 0, + kitPrice: 0, + }; + } + + return Promise.resolve(recycleFeePart); +}; + const mockGetServiceabilityDetails = (mockServiceZipCode) => { const serviceabilityDetails = { isGlassServiceableInshop: true, @@ -49,6 +66,9 @@ jest.mock( getPricedMobileFeePart: jest.fn((mockServiceZipCode) => { return mockGetPricedMobileFeePart(mockServiceZipCode); }), + getPricedRecycleFeePart: jest.fn((mockServiceZipCode) => { + return mockGetPricedRecycleFeePart(mockServiceZipCode); + }), getServiceabilityDetails: jest.fn((mockServiceZipCode) => { return mockGetServiceabilityDetails(mockServiceZipCode); }), diff --git a/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue b/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue index 24d063e5e..a2ab4134e 100644 --- a/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue +++ b/src/layouts/service-location/service-zip-modal-question/service-zip-modal-question.vue @@ -45,6 +45,7 @@ import alert from "@/ux-components/alert/alert"; import { getPricedMobileFeePart, + getPricedRecycleFeePart, getServiceabilityDetails, getBillToAccountNumber, } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; @@ -164,6 +165,12 @@ export default { "service-location" ); + // retrieve recycle fee part + const recycleFeePart = await getPricedRecycleFeePart( + serviceZipCode, + "service-location" + ); + // retrieve serviceability details const serviceabilityDetails = await getServiceabilityDetails( serviceZipCode, @@ -177,6 +184,7 @@ export default { // update content related to service zip code this.$emit("updated-mobile-fee-part", mobileFeePart); + this.$emit("updated-recycle-fee-part", recycleFeePart); this.$emit("updated-serviceability", serviceabilityDetails.data); this.$emit("updated-contains-military-base", zipCodeData.containsMilitaryBase); this.$emit("updated-bill-to-account-number", billToAccountNumber);