diff --git a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue index c37e596ef..1769961b7 100644 --- a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue +++ b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue @@ -22,6 +22,7 @@ aria-live="polite">
@@ -32,6 +33,7 @@
- diff --git a/src/helpers/object-cloning-helper.js b/src/layouts/service-location/helpers/object-cloning-helper/object-cloning-helper.js similarity index 100% rename from src/helpers/object-cloning-helper.js rename to src/layouts/service-location/helpers/object-cloning-helper/object-cloning-helper.js diff --git a/src/helpers/object-cloning-helper.spec.js b/src/layouts/service-location/helpers/object-cloning-helper/object-cloning-helper.spec.js similarity index 100% rename from src/helpers/object-cloning-helper.spec.js rename to src/layouts/service-location/helpers/object-cloning-helper/object-cloning-helper.spec.js diff --git a/src/helpers/service-location-helper.js b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js similarity index 64% rename from src/helpers/service-location-helper.js rename to src/layouts/service-location/helpers/service-location-helper/service-location-helper.js index 41f4be147..f9529ccec 100644 --- a/src/helpers/service-location-helper.js +++ b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.js @@ -1,8 +1,13 @@ import { storeActions } from "@/constants/store-actions"; import baseMixin from "@/mixins/base-mixin.js"; -export async function getPricedMobileFeePart(serviceZipCode) { - if (!serviceZipCode) { +export async function getPricedMobileFeePart( + serviceZipCode, + serviceType, + parentAccountNumber, + billToAccountNumber +) { + if (!serviceZipCode || !serviceType || !parentAccountNumber) { return Promise.resolve(null); } @@ -11,7 +16,11 @@ export async function getPricedMobileFeePart(serviceZipCode) { // Get the Mobile Fee Part const mobileFeePart = await baseMixin.methods.dispatchStoreAction( storeActions.GET_MOBILE_FEE_PART, - null, + { + serviceType: serviceType, + parentAccountNumber: parentAccountNumber, + billToAccountNumber: billToAccountNumber, + }, false ); @@ -21,7 +30,7 @@ export async function getPricedMobileFeePart(serviceZipCode) { { availableLineItems: [mobileFeePart.data], serviceZipCode: serviceZipCode, - ctu: zipCodeData.zipCodeCtu, + serviceZipCodeCtu: zipCodeData.zipCodeCtu, }, false ); diff --git a/src/helpers/service-location-helper.spec.js b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.spec.js similarity index 79% rename from src/helpers/service-location-helper.spec.js rename to src/layouts/service-location/helpers/service-location-helper/service-location-helper.spec.js index 345e4c807..061fd6bcd 100644 --- a/src/helpers/service-location-helper.spec.js +++ b/src/layouts/service-location/helpers/service-location-helper/service-location-helper.spec.js @@ -48,10 +48,18 @@ describe("service-location-helper.js", () => { it("Should return null if no service zip code is passed in", async () => { // Arrange const serviceZipCode = null; + const serviceType = "Replace"; + const parentAccountNumber = 167132; + const billToAccountNumber = 1234; const expected = null; // Act - const result = await getPricedMobileFeePart(serviceZipCode); + const result = await getPricedMobileFeePart( + serviceZipCode, + serviceType, + parentAccountNumber, + billToAccountNumber + ); // Assert expect(result).toEqual(expected); @@ -60,6 +68,10 @@ describe("service-location-helper.js", () => { it("Should return the priced mobile fee part", async () => { // Arrange const serviceZipCode = "43235"; + const serviceType = "Replace"; + const parentAccountNumber = 167132; + const billToAccountNumber = 1234; + const expected = { partNumber: "MOBILE FEE", description: "MOBILE FEE", @@ -70,7 +82,12 @@ describe("service-location-helper.js", () => { }; // Act - const result = await getPricedMobileFeePart(serviceZipCode); + const result = await getPricedMobileFeePart( + serviceZipCode, + serviceType, + parentAccountNumber, + billToAccountNumber + ); // Assert expect(result).toEqual(expected); 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 d90f68b1f..ab0ba6573 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 @@ -247,6 +247,7 @@ describe("mobile-location-modal-questions.vue", () => { attachTo: document.body, }); wrapper.vm.$refs.MobileLocationModalWidget.closeModal = jest.fn(); + wrapper.vm.resetModalButtonStyle = jest.fn(); // Act wrapper.vm.internalModel = newMobileLocationQuestions; @@ -293,6 +294,7 @@ describe("mobile-location-modal-questions.vue", () => { }); wrapper.vm.internalModel = newMobileLocationQuestions; + wrapper.vm.resetModalButtonStyle = jest.fn(); // Act await wrapper.vm.setMobileLocation(); @@ -300,40 +302,6 @@ describe("mobile-location-modal-questions.vue", () => { // Assert expect(wrapper.vm.displayInvalidZipAlert).toBe(true); }); - - it("Should clear the internal model when resetModel is called", async () => { - // Arrange - const mobileLocationQuestions = { - addressQuestions: { - streetAddress: "555 Some St", - apartmentNumberOrBusinessName: "Apt 1", - city: "Funkytown", - state: "OH", - zipCode: "55555", - }, - isVehicleProtected: true, - serviceZipCode: "55555", - }; - - const { wrapper } = setupMocks({ - mixins: [mockMixin], - props: { - modelValue: mobileLocationQuestions, - }, - mountOptions: { - attachTo: document.body, - }, - }); - - // Act - wrapper.vm.resetModel(); - - // Assert - expect(wrapper.vm.internalModel.addressQuestions.streetAddress).toEqual(""); - expect(wrapper.vm.internalModel.addressQuestions.apartmentNumberOrBusinessName).toEqual(""); - expect(wrapper.vm.internalModel.addressQuestions.city).toEqual(""); - expect(wrapper.vm.internalModel.isVehicleProtected).toEqual(null); - }); }); function setupMocks({ mountOptions, mixins, props, isShallowMount = true }) { 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 4c6028ca5..cdba0058f 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 @@ -58,7 +58,7 @@ import addressQuestions from "@/layouts/address-lookup/customer-questions/addres import vehicleProtectedQuestion from "@/layouts/service-location/mobile-location-modal-questions/vehicle-protected-question/vehicle-protected-question"; // Helpers -import { deepClone } from "@/helpers/object-cloning-helper"; +import { deepClone } from "@/layouts/service-location/helpers/object-cloning-helper/object-cloning-helper"; export default { name: "mobile-location-modal-questions", @@ -81,10 +81,12 @@ export default { zipCode: "", }, isVehicleProtected: null, - serviceZipCode: "", - mobileFeePart: null, }), }, + mobileFeePart: { + type: Object, + default: () => ({}), + }, isZipServiceableMobile: Boolean, isZipServiceableInShop: Boolean, linkWidgetName: String, @@ -122,13 +124,14 @@ export default { return cmsContentText.replaceAll("{custom:mobileFee}", this.mobileFee); }, mobileFee() { - if (!this.modelValue.mobileFeePart) { + if (!this.mobileFeePart) { return 0; } + return ( - this.modelValue.mobileFeePart.laborAmount + - this.modelValue.mobileFeePart.sellingPrice + - this.modelValue.mobileFeePart.kitPrice + this.mobileFeePart.laborAmount + + this.mobileFeePart.sellingPrice + + this.mobileFeePart.kitPrice ); }, modalFooterText() { @@ -148,23 +151,22 @@ export default { closeModal() { this.$refs[this.modalName].closeModal(); }, - resetComponent() { - this.resetModel(); - - // Reset the validation form - this.$refs[this.modalName].form.resetForm(); - - // Reinitialize the Address Auto Complete - this.$refs.addressQuestions.setupAddressLookup(); + resetComponent(updatedServiceZipCodeInfo) { + // Reset the validation form, setting the initial values + // for the state and zipCode to those that were entered + // on the service-zip-modal-question component + this.$refs[this.modalName].form.resetForm({ + values: { + state: updatedServiceZipCodeInfo.state, + zipCode: updatedServiceZipCodeInfo.zipCode, + }, + }); }, - resetModel() { - // Address - this.internalModel.addressQuestions.streetAddress = ""; - this.internalModel.addressQuestions.apartmentNumberOrBusinessName = ""; - this.internalModel.addressQuestions.city = ""; - - // Is Vehicle Protected - this.internalModel.isVehicleProtected = null; + resetModalButtonStyle() { + this.$refs[this.modalName].resetButtonStyle(); + }, + onAddressUpdated(updatedServiceZipCodeInfo) { + this.resetComponent(updatedServiceZipCodeInfo); }, async setMobileLocation() { // Validate the Zip Code @@ -174,6 +176,7 @@ export default { if (!zipCodeData.isValid) { this.displayInvalidZipAlert = true; + this.resetModalButtonStyle(); } else { // Update the page level model this.$emit("update:modelValue", this.internalModel); @@ -185,6 +188,11 @@ export default { modelValue: { handler(newValue) { this.internalModel = deepClone(newValue); + + this.resetComponent({ + state: newValue.state, + zipCode: newValue.zipCode, + }); }, deep: true, }, diff --git a/src/layouts/service-location/service-location.spec.js b/src/layouts/service-location/service-location.spec.js index fb92fbf58..fbe7aa448 100644 --- a/src/layouts/service-location/service-location.spec.js +++ b/src/layouts/service-location/service-location.spec.js @@ -32,11 +32,14 @@ const mockGetPricedMobileFeePart = (mockServiceZipCode) => { return Promise.resolve(mobileFeePart); }; -jest.mock("@/helpers/service-location-helper", () => ({ - getPricedMobileFeePart: jest.fn((mockServiceZipCode) => { - return mockGetPricedMobileFeePart(mockServiceZipCode); - }), -})); +jest.mock( + "@/layouts/service-location/helpers/service-location-helper/service-location-helper", + () => ({ + getPricedMobileFeePart: jest.fn((mockServiceZipCode) => { + return mockGetPricedMobileFeePart(mockServiceZipCode); + }), + }) +); jest.mock("@/store", () => ({ commit: jest.fn(), @@ -107,6 +110,9 @@ const mockMixin = { getTotalLineItemPrice: jest.fn((lineItem) => { return 49.99; }), + + onSubmit: jest.fn(), + onInvalidSubmit: jest.fn(), }, }; @@ -130,6 +136,9 @@ beforeEach(() => { state: "OH", }, }, + damage: { + isRepair: false, + }, payment: { isInsurance: false, }, @@ -168,7 +177,7 @@ describe("service-location.vue", () => { ); // Assert - expect(wrapper.vm.mobileLocationQuestions.mobileFeePart).toStrictEqual(mobileFeePart); + expect(wrapper.vm.mobileFeePart).toStrictEqual(mobileFeePart); }); }); @@ -217,7 +226,9 @@ describe("service-location.vue", () => { describe("updating service zip", () => { test("updates the page model after providing the service zip code", () => { // Arrange - const { wrapper } = setupMocks({}); + const { wrapper } = setupMocks({ + mixins: [mockMixin], + }); wrapper.vm.$refs.mobileLocationModalQuestions.resetComponent = jest.fn(); const newServiceZipCodeQuestion = { @@ -256,7 +267,6 @@ describe("service-location.vue", () => { zipCode: "43054", }, isVehicleProtected: true, - mobileFeePart: null, }; wrapper.vm.mobileLocationQuestions = mobileLocationQuestions; @@ -269,7 +279,6 @@ describe("service-location.vue", () => { zipCode: "61606", }, isVehicleProtected: null, - mobileFeePart: null, }; const serviceZipCodeComponent = wrapper.findComponent({ @@ -299,7 +308,6 @@ describe("service-location.vue", () => { zipCode: "", }, isVehicleProtected: null, - mobileFeePart: null, }; wrapper.vm.mobileLocationQuestions = mobileLocationQuestions; @@ -312,7 +320,6 @@ describe("service-location.vue", () => { zipCode: "43054", }, isVehicleProtected: true, - mobileFeePart: null, }; const mobileLocationComponent = wrapper.findComponent({ diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 6950b23c1..c4944f3ee 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -11,6 +11,7 @@ modalWidgetName="ServiceZipModalWidget" /> @@ -36,7 +37,7 @@ import { Form } from "vee-validate"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; -import { getPricedMobileFeePart } from "@/helpers/service-location-helper"; +import { getPricedMobileFeePart } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper"; import store from "@/store"; export default { @@ -48,6 +49,7 @@ export default { city: this.getServiceCityFromStore(), state: this.getServiceStateFromStore(), zipCode: this.getServiceZipCodeFromStore(), + isVehicleProtected: null, isZipServiceableMobile: null, isZipServiceableInShop: null, mobileFeePart: null, @@ -58,7 +60,16 @@ export default { const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage); const serviceZipCode = store.getters.order.serviceLocation.zipCode; - const mobileFeePartPromise = getPricedMobileFeePart(serviceZipCode); + const serviceType = store.getters.damage.isRepair ? "Repair" : "Replace"; + const parentAccountNumber = store.getters.payment.parentAccountNumber; + const billToAccountNumber = 0; + + const mobileFeePartPromise = getPricedMobileFeePart( + serviceZipCode, + serviceType, + parentAccountNumber, + billToAccountNumber + ); // Settle promises and get results const promiseResultMap = [ @@ -90,7 +101,7 @@ export default { }, set: function (newValue) { if (newValue.zipCode !== this.zipCode) { - this.resetMobileLocation(this.zipCode); + this.resetMobileLocation(newValue); } this.state = newValue.state; @@ -108,7 +119,6 @@ export default { zipCode: this.zipCode, }, isVehicleProtected: this.isVehicleProtected, - mobileFeePart: this.mobileFeePart, }; }, set: function (newValue) { @@ -119,7 +129,6 @@ export default { this.state = newValue.addressQuestions.state; this.zipCode = newValue.addressQuestions.zipCode; this.isVehicleProtected = newValue.isVehicleProtected; - this.mobileFeePart = newValue.mobileFeePart; }, }, }, @@ -149,19 +158,27 @@ export default { return store.getters.order.serviceLocation.zipCode; }, resetMobileFeePart(serviceZipCode) { - getPricedMobileFeePart(serviceZipCode).then((pricedMobileFeePart) => { + const serviceType = store.getters.damage.isRepair ? "Repair" : "Replace"; + const parentAccountNumber = store.getters.payment.parentAccountNumber; + const billToAccountNumber = 0; + + getPricedMobileFeePart( + serviceZipCode, + serviceType, + parentAccountNumber, + billToAccountNumber + ).then((pricedMobileFeePart) => { this.mobileFeePart = pricedMobileFeePart; }); }, - resetMobileLocation(updatedServiceZipCode) { + resetMobileLocation(updatedServiceZipCodeInfo) { this.streetAddress = ""; this.apartmentNumberOrBusinessName = ""; this.city = ""; + this.isVehicleProtected = null; - this.$refs.mobileLocationModalQuestions.resetComponent(); - - this.resetMobileFeePart(updatedServiceZipCode); + this.resetMobileFeePart(updatedServiceZipCodeInfo.zipCode); }, backButtonAction() { this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route); diff --git a/src/store/index.js b/src/store/index.js index 3793111ae..64acea595 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1431,11 +1431,16 @@ export const actions = { context.commit(storeMutations.UPDATE_VAPS, vaps); }, // Price order actions - async priceOrderItemsAndSaveServerData(context, { availableLineItems, serviceZipCode, ctu }) { + async priceOrderItemsAndSaveServerData( + context, + { availableLineItems, serviceZipCode, serviceZipCodeCtu } + ) { const zipCodeToUse = serviceZipCode ? serviceZipCode : context.getters.order.serviceLocation.zipCode; - const ctuToUse = ctu ? ctu : context.getters.order.serviceLocation.zipCodeCtu; + const ctuToUse = serviceZipCodeCtu + ? serviceZipCodeCtu + : context.getters.order.serviceLocation.zipCodeCtu; const availableLineItemsFormattedForRequest = getLineItemQueryStringForPricing(availableLineItems);